Updating ModelState with model object

前端 未结 3 1779
猫巷女王i
猫巷女王i 2020-12-30 05:52

The problem: How to update ModelState in posting+validation scenario.

I\'ve got a simple form:

<%= Html.ValidationSummary() %>
<% using(Html         


        
相关标签:
3条回答
  • 2020-12-30 06:17

    am I doing something extremely uncommon or am I missing something?

    I think this is pretty rare. I think MVC is assuming validation errors are a yes/no affair, and in this case you're using a validation error as a means to give general user feedback.

    I think MVC also seems happiest when POSTs either fail due to validation errors, or perform an action and redirect or render something completely different. Outside for model validation errors, it's pretty rare to re-render the same input.

    I've been using MVC for about a year now and just ran into this in another context, where after a POST I wanted to render a fresh form as the response.

    [HttpPost]
    public ActionResult Upload(DocumentView data) {
       if(!ModelState.IsValid) return View(data);
       ProcessUpload(data);
       return View(new DocumentView());
    }
    

    MVC is rendering the ModelState from data, not my new object. Very surprising.

    If the former, then how could I implement such functionality in a better way

    1. implement to automatic fixes in javascript (might not be possible)
    2. keep a list of automatic fixes made, if the object is valid after all those then pass it down to the "About" view and display as a message like "M saved, with the following corrections: ...".
    0 讨论(0)
  • 2020-12-30 06:20

    I know this post is fairly old but it's a problem I've had before and I just thought of a simple solution that I like - just clear the ModelState after you've got the posted values.

    UpdateModel(viewModel);
    ModelState.Clear();
    
    viewModel.SomeProperty = "a new value";
    return View(viewModel);
    

    and the view has to use the (possibly modified) view model object rather than the ModelState.

    Maybe this is really obvious. It seems so in hindsight!

    0 讨论(0)
  • 2020-12-30 06:29

    You could accept a form collection as a parameter instead of your model object in your controller, like this : public ActionResult Index(FormCollection Form).

    Therefor default model binder will not update the model state, and you'll get the behaviour you want.

    Edit : Or you can just update the ModelStateDictionary to reflect your changes to the model.

    
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(M m)
    {
        if (m.Value != "a")
        {
            ModelState["m.Value"].Value = new ValueProviderResult("a", m.Name, 
                        CultureInfo.CurrentCulture);
            ModelState.AddModelError("m.Value", "should be \"a\"");
            m.Value = "a";
            return View(m);
        }
        return View("About");            
    }
    

    Note : I'm not sure if this is the best way. But it seems to work and it should be the behaviour you want.

    0 讨论(0)
提交回复
热议问题