如何在带有嵌入式 C# 的 Blazor/Razor 页面中进行不区分大小写的字符串比较?

How to do case insensitive string comparison in a Blazor/Razor page with embedded C#?

有很多类似这样的相关问题(和答案)(不区分大小写的字符串比较),但 none 适用于 Razor C# 页面。

我正在使用 Visual Studio 2019 和 Blazor(Razor 页面和 C#)。浏览器是 Chrome 或 Edge(奇怪的是,它在 Internet Exploder 中工作正常...)

在我的剃须刀页面中,如果传递的 URL 参数与我的项目匹配,我正在尝试在 HTML select 选项上设置 "selected" 选项字符串数组。但是 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"
    };
}

我尝试使用字符串 class 而不是字符串变量,但它的行为仍然相同。

我尝试使用一个临时字符串变量来查看是否有所不同,仍然没有问题。

如果浏览器 URL 不完全匹配,select 选项将不会被 select 编辑。例如,这有效:

 http://localhost:35333/EqualsTest/Hello

而这不是:

 http://localhost:35333/EqualsTest/hello

这是一个错误还是我做错了什么?

如果我循环遍历@code 部分中的数组,字符串比较工作正常。

我可以在@code 部分使用这个 hack 来解决这个问题:

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;
        }
    }

UPDATE:甚至更好 - 更改参数 get/set 属性:

@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;
                }
            }
        }
    }
}

主要是因为 @bind<select @bind="@incomingParam"> 尝试绑定到一个新变量,或者根本不绑定以进行测试...

但是,就我个人而言,我建议您将所有内容都保留为小写,只 .ToLower() 您收到的任何参数

更新 我看了看周围,似乎 @bind 支持 @bind:converter 所以你可以使用 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>