0

I have an issue which I've solved, but I don't understand why I've solved it.

I'm using MVC, and posting in a form using razor.

My Email model contains many properties but the important one to note is

public class MyEmail
{
    public string Email { get; set; }
}

And the controller signature is

    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";

        return View();
    }

    [HttpPost]
    public ActionResult Contact(MyEmail Email)
    {
        ViewBag.Message = $"Email is null : {Email == null}";

        return View();
    }

Please note, both the property of MyEmail is Email and the parameter in the Controller is also named Email

When I post in the CSHTML (view), the controller's parameter email is always null.

I've played with this and learned the issue is the parameter name (email) matches the name of a property in my object.

Why is this not allowed? Meaning does any one know what MVC is doing behind the scenes which confuses it?

By changing the property from Email to EmailAddress or changing the parameter name from Email to MySendObject resolves the issue. I don't understand why though.

The view is

@model WebApplication1.Models.MyEmail

@{
    ViewBag.Title = "Contact";
}

@using (Html.BeginForm())
{
    @Html.TextBoxFor(a => a.Email);
    <input type="submit" value="Send" />
}
MyDaftQuestions
  • 4,487
  • 17
  • 63
  • 120
  • `Email` and `email` are not the same, and do not conflict. If that's causing a problem, I think you have something else going on here. Something that we don't have enough information to resolve. – Jonathan Wood Jan 10 '18 at 18:54
  • @JonathanWood I'd love to give more detail but don't know what detail to give :(. As per my last paragraph, my own efforts of testing show this is the cause. – MyDaftQuestions Jan 10 '18 at 18:55
  • Then show the markup from your view. – Jonathan Wood Jan 10 '18 at 18:56
  • @MyDaftQuestions You need to provide enough information for *other* people to get that same result, rather than only you being able to reproduce it. You should provide the *smallest* example that's still complete enough to demonstrate that problem. – Servy Jan 10 '18 at 18:56
  • @Servy, let me close this then, and attempt to reproduce with a tiny code base – MyDaftQuestions Jan 10 '18 at 19:00
  • @Servy, the code I've provided now contains all the code you need to replicate – MyDaftQuestions Jan 12 '18 at 12:09

1 Answers1

0

I've not looked.. this is just some comments based on my understanding of ASP.NET MVC. MVC is open source, so you can verify (or disprove) my observations easily enough.

My guess is that the model binder is looking at the HTML form field "Email" and then looking at the Action method parameter "Email" and saying to itself, this string doesn't look anything like a complex object (MyEmail), so it throws up its hands and returns a null.

It's probably seeing the form field and the parameter name are the same and running the SimpleTypeModelBinder rather than the ComplexTypeModelBinder.

Our company uses the parameter name model for all our POST Action method parameters to avoid these kinds of conflicts.

Its the exact same reason most of our GET parameters are named id, and none of our domain models have an ID property.

Here's an interesting Gist detailing one approach to debugging the default model binder - if that's a road you want to walk down.

Sam Axe
  • 33,313
  • 9
  • 55
  • 89