Search code examples
c#stringrazorblazorignore-case

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


There are many related questions (and answers) like this (case insensitive string comparison), but none are for Razor C# pages.

I'm using Visual Studio 2019 and Blazor (Razor pages and C#). Browser is Chrome or Edge (oddly, it works fine in Internet Exploder...)

In my razor page, I'm trying to set the "selected" option on an HTML select option IF the passed URL parameter matches an item in my string array. But the variable.Equals(param,StringComparison.OrdinalIgnoreCase) or String.Equals(param,variable,StringComparison.OrdinalIgnnoreCase) fails unless the case of the parameter matches exactly.

I'm getting my string array using Entity Framework and a SQL Server database. But to illustrate the problem, I've condensed it down to 1 Razor page (no EF and no database):

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

I tried using the String class rather than string variables but it still behaves the same.

I tried using an interim string variable to see if that made a difference, still no werky.

If the browser URL does not match exactly, the select option will not be selected. For example, this works:

 http://localhost:35333/EqualsTest/Hello

And this does not:

 http://localhost:35333/EqualsTest/hello

Is this a bug or am I doing something wrong?


Solution

  • If I loop thru the array in the @code section the string compare works fine.

    I can use this hack in the @code section to work around the problem:

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

    And now the string comparison in the Razor C# code works correctly.

    But I would like to know why it does not work in the Razor page without this silly business.

    UPDATE: Better - no compiler warnings:

    protected override void OnInitialized()
    {
        base.OnInitialized();
    
        foreach (var p in myParams)
        {
            if (String.Equals(p, incomingParam, StringComparison.OrdinalIgnoreCase))
            {
                incomingParam = p;
            }
        }
    

    UPDATE: And even better - change the parameter 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;
                    }
                }
            }
        }
    }