Как выполнить сравнение строк без учета регистра на странице Blazor / Razor со встроенной C#? - PullRequest
1 голос
/ 30 января 2020

Есть много похожих вопросов (и ответов), подобных этому (сравнение строк без учета регистра), но ни один не предназначен для страниц Razor C#.

Я использую Visual Studio 2019 и Blazor (страницы Razor и C#). Браузер Chrome или Edge (как ни странно, он прекрасно работает в Inte rnet Exploder ...)

На моей странице бритвы я пытаюсь установить параметр "selected" для HTML выберите опцию, ЕСЛИ переданный параметр URL соответствует элементу в моем массиве строк. Но variable.Equals (param, StringComparison.OrdinalIgnoreCase) или String.Equals (param, variable, StringComparison.OrdinalIgnnoreCase) завершается ошибкой, если только случай параметра не соответствует точно.

Я получаю свой строковый массив, используя Entity Framework и SQL Серверную базу данных. Но чтобы проиллюстрировать проблему, я сократил ее до 1 страницы Razor (без EF и без базы данных):

@page "/EqualsTest/{incomingParam}"
<h3>EqualsTest</h3>

<p>incomingParam = @incomingParam</p>

<!--display list on page to show lengths-->
@foreach (var p in myParams)
{
    <p>'@p' = @p.Length</p>
}

<!--select list with passed param selected if it matches-->
<select @bind="@incomingParam">
    @foreach (var p in myParams)
    {
        @if (incomingParam.Equals(p, StringComparison.OrdinalIgnoreCase))
        {
            <option selected value="@p">@p</option>
        }
        else
        {
            <option value="@p">@p</option>
        }
    }
</select>

@code {
    [Parameter]
    public string incomingParam { get; set; }

    IEnumerable<string> myParams = new List<string>(){
        "Hello",
        "Whazzzup",
        "Goodbye"
    };
}

Я пытался использовать класс String, а не строковые переменные, но он по-прежнему ведет себя так же.

Я попытался использовать временную строковую переменную, чтобы увидеть, если это что-то изменило, но все же не слишком.

Если URL браузера не совпадает точно, опция выбора не будет выбрана. Например, это работает:

 http://localhost:35333/EqualsTest/Hello

И это не:

 http://localhost:35333/EqualsTest/hello

Это ошибка или я что-то не так делаю?

Ответы [ 2 ]

0 голосов
/ 30 января 2020

Это в основном из-за того, что @bind в <select @bind="@incomingParam"> пытаются связать с новой переменной или не связывают вообще для теста ...

Однако лично я бы посоветовал вам сохранить все в нижнем регистре и просто .ToLower() какой бы параметр вы не получили

ОБНОВЛЕНИЕ Я немного осмотрелся и похоже, что @bind поддерживает конвертер @bind: поэтому вы можете использовать LowerCaseStringConverter

 <select @bind="@incomingParam" @bind-converter="LowerCaseStringConverter">
    @foreach (var p in myParams)
    {
        @if (incomingParam.Equals(p, StringComparison.OrdinalIgnoreCase))
        {
            <option selected value="@p">@p</option>
        }
        else
        {
            <option value="@p">@p</option>
        }
    }
</select>
0 голосов
/ 30 января 2020

Если I l oop через массив в секции @code, сравнение строк работает нормально.

Я могу использовать этот хак в секции @code, чтобы обойти проблему:

protected override async Task OnInitializedAsync()
{
    foreach (var p in myParams)
    {
        if (incomingParam.Equals(p,StringComparison.OrdinalIgnoreCase))
        {
            incomingParam = p;
        }
    }
}

А теперь сравнение строк в коде Razor C# работает правильно.

Но я хотел бы знать, почему это не работает на странице Razor без этого глупого бизнеса.

ОБНОВЛЕНИЕ: Лучше - без предупреждений компилятора:

protected override void OnInitialized()
{
    base.OnInitialized();

    foreach (var p in myParams)
    {
        if (String.Equals(p, incomingParam, StringComparison.OrdinalIgnoreCase))
        {
            incomingParam = p;
        }
    }

ОБНОВЛЕНИЕ : И еще лучше - изменить параметр get / set properties:

@code {
    IEnumerable<string> myParams = new List<string>()
    {
        "Hello",
        "Whazzzup",
        "Goodbye"
    };

    private string _incomingParam;

    [Parameter]
    public string incomingParam
    {
        get => _incomingParam;
        set
        {
            _incomingParam = value; // set the default

            foreach (var p in myParams)
            {
                if (String.Equals(p, value, StringComparison.OrdinalIgnoreCase))
                {
                    _incomingParam = p;
                }
            }
        }
    }
}
...