1

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?

5
  • 1
    You are positive that Index(string? email) is actually being called? There isn't another overload of Index(...) that may be triggered instead? Commented Aug 23, 2023 at 5:17
  • You need to place some breakpoints... maybe rebuild the app before debugging it. Pretty sure you are mistaken Commented Aug 23, 2023 at 5:18
  • 1
    Yes, I'm sure. It's the only action in the controller, and the project, for that matter. Commented Aug 23, 2023 at 5:19
  • And, yes, I rebuilt many times, and hit breakpoints in various places, including in the view. Commented Aug 23, 2023 at 5:20
  • 1
    asp-for will populate form fields from ModelState. Mostly this is so that invalid values will be preserved. eg you can't bind "abc" to an int, but you want to re-render the form with the invalid value. Commented Aug 23, 2023 at 5:38

1 Answer 1

2

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)    
    
Sign up to request clarification or add additional context in comments.

1 Comment

Removing email from ModelState did the trick. I set a breakpoint and confirmed that email is in ModelState, and marked as Valid. Thank you, and thank you, too, Jeremy Lakeman, for the insights.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.