asp.net-mvcmodelstatepost-redirect-get

Asp.net MVC ModelState.Clear


Can anyone give me a succinct definition of the role of ModelState in Asp.net MVC (or a link to one). In particular I need to know in what situations it is necessary or desirable to call ModelState.Clear().

Bit open ended huh... sorry, I think it might help if tell you what I'm acutally doing:

I have an Action of Edit on a Controller called "Page". When I first see the form to change the Page's details everything loads up fine (binding to a "MyCmsPage" object). Then I click a button that generates a value for one of the MyCmsPage object's fields (MyCmsPage.SeoTitle). It generates fine and updates the object and I then return the action result with the newly modified page object and expect the relevant textbox (rendered using <%= Html.TextBox("seoTitle", page.SeoTitle)%>) to be updated ... but alas it displays the value from the old model that was loaded.

I've worked around it by using ModelState.Clear() but I need to know why / how it has worked so I'm not just doing it blindly.

PageController:

[AcceptVerbs("POST")]
public ActionResult Edit(MyCmsPage page, string submitButton)
{
    // add the seoTitle to the current page object
    page.GenerateSeoTitle();

    // why must I do this?
    ModelState.Clear();

    // return the modified page object
     return View(page);
 }

Aspx:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyCmsPage>" %>
....
        <div class="c">
            <label for="seoTitle">
                Seo Title</label>
            <%= Html.TextBox("seoTitle", page.SeoTitle)%>
            <input type="submit" value="Generate Seo Title" name="submitButton" />
        </div>

Solution

  • I think is a bug in MVC. I struggled with this issue for hours today.

    Given this:

    public ViewResult SomeAction(SomeModel model) 
    {
        model.SomeString = "some value";
        return View(model); 
    }
    

    The view renders with the original model, ignoring the changes. So I thought, maybe it does not like me using the same model, so I tried like this:

    public ViewResult SomeAction(SomeModel model) 
    {
        var newModel = new SomeModel { SomeString = "some value" };
        return View(newModel); 
    }
    

    And still the view renders with the original model. What's odd is, when I put a breakpoint in the view and examine the model, it has the changed value. But the response stream has the old values.

    Eventually I discovered the same work around that you did:

    public ViewResult SomeAction(SomeModel model) 
    {
        var newModel = new SomeModel { SomeString = "some value" };
        ModelState.Clear();
        return View(newModel); 
    }
    

    Works as expected.

    I don't think this is a "feature," is it?