3

With this controller method: -

    [AcceptVerbs(HttpVerbs.Post)]
    public ViewResult Contact(Contact contactMessage)
    {
        return View();
    }

Why does this work...

public class Contact
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Message { get; set; }
}

<% using(Html.BeginForm()) { %>
<p>Name : <%= Html.TextBox("Name")%></p>
<p>Email : <%= Html.TextBox("Email")%></p>
<p>Message : <%= Html.TextBox("Message")%></p>
<p><input type="submit" value="Send Data" /></p>

But this doesn't?

public class Contact
{
    public string ContactName { get; set; }
    public string ContactEmail { get; set; }
    public string ContactMessage { get; set; }
}

<p>Name : <%= Html.TextBox("ContactName")%></p>
<p>Email : <%= Html.TextBox("ContactEmail")%></p>
<p>Message : <%= Html.TextBox("ContactMessage")%></p>
<p><input type="submit" value="Send Data" /></p>

Please don't tell me that field names are only partially identified ?

Trust me - All I did was add the text "Contact" to each of the fields in the object and each of the fields in the form. Its almost as if MVC got confused with the fields all starting with the same first 7 characters.

What gives ?

Can anyone shed any light on this ?

Paul.

3
  • 2
    Do you have a form tag at the second ? Commented Oct 29, 2009 at 8:53
  • 1
    I confirm, the second does not work. The parameter is null. Could be a bug in the DefaultModelBinder. Commented Oct 29, 2009 at 8:56
  • Congratulations on having a dumb title. Please can you think about changing it? Commented Oct 29, 2009 at 9:04

4 Answers 4

4

I currently can't find any reasonable explanation as to why the second is not working. But it works if you change your action signature to look like this:

public ViewResult Index([Bind(Prefix="")]Contact contactMessage)

I suppose this has something to do with the DefaultModelBinder.


UPDATE: Ok, this starts to be really funny:

// Not working
public ViewResult Index(Contact contactMessage)

// Not working
public ViewResult Index(Contact contactmessage)

// Working
public ViewResult Index(Contact contact)

// Working
public ViewResult Index(Contact contactMsg)

// Working
public ViewResult Index(Contact abc)

Strange indeed!


UPDATE2:

Ok got it. You have a property called ContactMessage in your model and the variable name passed in the action is also called contactMessage. This is where the ambiguity comes from. No bug in the DefaultModelBinder. He can't bind at the same time to a property of type string and Contact, case closed :-)

Sign up to request clarification or add additional context in comments.

3 Comments

Nice didn't try it in the end, but the Update2 makes perfect sense so +1.
Ok I accept the answer, but, its not that brilliant is it !. Why can't I have a parameter called contactMessage even though there's a property inside the object of the same name ? We're clearly defining the type we want passed into the method, and since we can't overload there's little room for ambiguity, we should get the object created & "properties" set from matching form fields - what's in a name eh ?... lol... As far as I'm converned its a "gotcha" or "bug" but so long as I know, I can work around it. Thanks everyone for your help.
@Paul- it's not a bug. The DefaultModel binder also tries to map id's to parameters, it doesn't know what your intentions are. It is certainly one of those things that catch you out though, that's why I upvoted your question!
2

Is it possible the view auto-recompiled when you refreshed your browser, but the overall project hasn't been Rebuilt since you changed the property names?

4 Comments

Or he has no form tag. Can't see any other issue.
+1. Yeah- the project not being rebuilt was my first thought.
@RichardOD, unfortunately this is not where the problem comes from.
@Darin. Interesting- if I get the opportunity to try it out myself I will upvote your answer. I guess for now a good strategy is to debug the ModelBinder, if as you say there is a bug somewhere.
1

Code your Textboxes like this:

 <%=html.TextBox("Contact.Name")%>

and you Action signature like this:

public ViewResult Index([Bind(Prefix="Contact")]Contact contactMessage)

I hope this helps and good luck

1 Comment

Nolo: I didn't appreciate being able to do this - cool !!! :-) I'll try to remember this one.
0
<% using(Html.BeginForm()) { %> 

is missing from your non-working example.

Or.. Maybe contactMessage parameter name is conflicting with the variable number in the form post.

1 Comment

I removed the tags for brevity... Its in my form.

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.