views:

302

answers:

3

When you have an ASP.Net MVC form created by Html.BeginForm(), how do fields inside it get populated? In the case of

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2>Edit Dinner</h2>
<%= Html.ValidationSummary("Please correct the errors and try again.") %>
<% using (Html.BeginForm()) { %>
   <p>
       <label for="Title">Dinner Title:</label>
       <%= Html.TextBox("Title") %>
       <%= Html.ValidationMessage("Title", "*") %>
   </p>

Where does the value for Html.TextBox("Title") come from? I know, the model. And in this case the model does have a Title field. But I have cases where I have to create a view model so I end up having something like:

public class DinnerViewModel {
    public Dinner Dinner {get; set;};
    public SomethingElse SomethingElse {get; set;};
}

and use that as a model, the <%= Html.TextBox("Title") %> gets the right value. Or at least it does if the validation fails and the form is re-displayed.

I'm asking because I have a case of a form that is being submitted via AJAX (using Ajax.BeginForm()) and the form gets refreshed. I'm creating a new model object, empty, for it, but it's still loading the values of the last submission. When I submit without AJAX everything works fine.

Update

I'm watching the debugger in the template. Model.Dinner.Title equals "" yet Html.TextArea("Title", Model.Dinner.Title) puts the previous value that was submitted inside the text area.

A: 

You can also force the values to be empty:

<% =Html.TextBox("Title", null, new { @value = '' }); %>

It would be better though to pass an empty Model (default values) to the View ? EDIT That's what you're doing I see ;). Just go for my first suggestion, check if the request is an AJAX request or not, then based on that pass the emtpy @value to the TextBox.

Ropstah
I am passing an empty model to the view.
J. Pablo Fernández
A: 

I'm no sure I understand the problem. You do an ajax request but the text fields in you form still hold their values after the call?

If that is the case then you should check that those text field are inside the element asociated to UpdateTargetId property of AjaxOption class. When you do an ajax request, only a part of your page gets updated (the one referenced by UpdateTargetId property). The rest of the fields in your page will not get updated whether you update your model or not. Look at this example:

<%= Html.TextBox("Title") %>
....
<div id="myDiv">
    <%= Html.TextBox("SomeField") %>
</div>

<% using (Ajax.BeginForm(new AjaxOptions() { UpdateTargetId = "myDiv" })) {%>
    //... blah blah blah
<% } %>

When you submit your ajax form, only SomeField field will get updated, Title field will remain unchanged.

When you submit a regular form, the whole page gets updated and that is why all the fields get updated without ajax.

EDIT: Typo.

Gerardo Contijoch
A: 

The data is stored in the ModelState. The HtmlHelper methods will look for values stored in the model state based on the name of the form element. The ModelState gets cleaned when I redirect, but not when I just return, as in the case of the AJAX call.

J. Pablo Fernández