Maintaining ViewModel fields with default model binding and failed validation

Posted by TonE on Stack Overflow See other posts from Stack Overflow or by TonE
Published on 2010-03-11T15:07:16Z Indexed on 2010/03/17 20:31 UTC
Read the original article Hit count: 411

Filed under:
|
|

I have an ASP.Net MVC Controller with a 'MapColumns' action along with a corresponding ViewModel and View.

I'm using the defaultModelBinder to bind a number of drop down lists to a Dictionary in the ViewModel. The view model also contains an IList field for both source and destination columns which are used to render the view.

My question is what to do when validation fails on the Post call to the MapColumns action?

Currently the MapColumns view is returned with the ViewModel resulting from the default binding. This contains the Dictionary values but not the two lists used to render the page. What is the best way to re-provide these to the view?

I can set them explicitly after failed validation, but if obtaining these values (via GetSourceColumns() and GetDestinationColumns() in the example) carries any overhead this doesn't seem ideal. What I am looking for is a way to retain these lists when they are not bound to the model from the view.

Here is some code to illustrate:

public class TestViewModel
{
    public Dictionary<string, string> ColumnMappings { get; set; }

    public List<string> SourceColumns;
    public List<string> DestinationColumns;
}

public class TestController : Controller
{
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult MapColumns()
    {
        var model = new TestViewModel;
        model.SourceColumns = GetSourceColumns();
        model.DestinationColumns = GetDestinationColumns();     
        return View(model);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult MapColumns(TestViewModel model)
    {
        if( Validate(model) )
        {
            // Do something with model.ColumnMappings
            RedirectToAction("Index");
        }
        else
        {
             // Here model.SourceColumns and model.DestinationColumns are empty
            return View(model);
        }
    }

}

The relevant section of MapColumns.aspx:

<%
int columnCount = 0;
foreach(string column in Model.targetColumns)
{%>
        <tr>
            <td> 
                <input type="hidden" name="ColumnMappings[<%= columnCount %>].Value" value="<%=column %>" />
                <%= Html.DropDownList("ColumnMappings[" + columnCount + "].Key", Model.DestinationColumns.AsSelectItemList())%>
            </td>            
        </tr>
    <%
    columnCount++;
}%>

© Stack Overflow or respective owner

Related posts about asp.net-mvc

Related posts about viewmodel