Search code examples
c#asp.net-coreasp.net-core-mvc

ASP.NET Core MVC using query string parameter to automatically populate a form field with the same name


I noticed that ASP.NET Core MVC will take a query string parameter and use its value to automatically populate a form field with the same name, even if I ignore the query string parameter and explicitly set the model property to null.

I have a reproduction on GitHub.

The Model (Models/HomeIndexModel.cs)

This is a simple record with one property, Email. This is bound to the lone textbox on the form.

public record HomeIndexModel(string? Email);

The Controller Action (Controllers/HomeController.cs)

The controller action takes a string? from the query string and binds it to the email parameter.

Note how we're ignoring this value and explicitly setting the view model's Email property to null.

public IActionResult Index(string? email)
{
    // NOTE: Ignore the query string parameter and explicitly set the view model property to null.
    return View(new HomeIndexModel(Email: null));
}

The View (Views/Home/Index.cshtml)

The view uses HomeIndexModel as its view model. It has a single form with a textbox for HomeIndexModel's Email property.

@model AspNetCoreMvcQueryStringToForm.Models.HomeIndexModel
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    
    <form>
        <label asp-for="Email"> Email
            <input type="email" asp-for="Email" />
        </label>
        
    </form>
</div>

The Unexpected behavior

If I make a request to the action with an email query string parameter, the Email form field is automatically populated with that value, even though I'm explicitly setting the Email model property to null in the controller action:

enter image description here

Question

How and why is this happening? I must be overlooking something simple.

Is there a way to disable this behavior, preferably at the action level?


Solution

  • Is there a way to disable this behavior, preferably at the action level?

    Two tricks for you:

    1. In your action add the code:

      ModelState.Clear()/ModelState.Remove("email")
      
    2. Modify the name of the argument in your controller:

      public IActionResult Index(string? mail)