Frage

I'm wondering what is the best practice for dealing with editable/read only field in the same viewModel. I'm facing this problem for a bigger ViewModel but let's assume I have a very simple ViewModel:

public class BaseListViewModel
{
    public int Id { get; set; }
    public bool IsCheckedForAction { get; set; }
    public string DisplayName { get; set; }
}

My PartialView:

@model Wims.Website.ViewModels.Shared.BaseModelListViewModel
@using Wims.Website.Classes.Helpers.ExtentionMethods
<div class="dataDetail">
        <div>
            <div class="float-left">
                @Html.CheckBoxFor(model => model.IsCheckedForAction)
            </div>

            <div class="float-left">
                @Html.LabelFor(model => model.IsCheckedForAction, Model.DisplayName)


                @Html.GenerateSecureDataControls(w => w.Id)
            </div>
        </div>
    </div>
<div style="clear: both"></div>

Obviously, when i Post my data, DisplayName will not be filled. Let's assume some validation fails, and I just return the data i recieved the DisplayName would be missing.

    [HttpPost]

public ActionResult Edit(BaseListViewModel stuff)
{
    if (ModelState.IsValid)
    {
        ...
        return View("Index");
    }
    return View(stuff);
}

I know there is several way to fix this:

1) add

  @Html.HiddenFor(model => model.DisplayName)

in the view, which is ok if it's just 1 field, but, what happens if i do have 10 display only field?

2) requery data if (!Model.isValid) in [HttpPost].

3) I guess I could cache it in TempData ?

What is the best way to go for this? Thanks!

Edit: I am trying to avoid having to requery the data if validation fails

War es hilfreich?

Lösung

I'd use the PRG pattern. It is more DRY as you only build ViewModel in the GET action. If validation fails then redirect to GET and get the model state out of tempdata.

The attributes on from this article, http://www.jefclaes.be/2012/06/persisting-model-state-when-using-prg.html, or from MVC Contrib https://github.com/mvccontrib/MvcContrib/blob/master/src/MVCContrib/Filters/ModelStateToTempDataAttribute.cs, make it easy to pass the Modelstate between the POST and the GET

Andere Tipps

The POST action should perform the same initialisation of the viewmodel as the GET action. You could move the initialisation code into a common private function in the controller. The reason for this is if validation fails because of some concurrent change to the same data, the validation errors would be displayed to the user along with the new data. You could use the PRG pattern as well if the views allow for it.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top