简体   繁体   中英

MVC3 Partial model validation

I'm in trouble and ask for your help.

I have a simple class

public class Test
{
    [Key]
    public string a { get; set; }

    [Required]
    public string c { get;set; }

    public string b { get; set; }
}

I created a simple form to submit new entity instance and it works. I'm in trouble for edit: Edit form displays 'a' and 'b' properties. Since 'c' can be submitted only in new Entities and must not be displayed ( do not ask why ), on my update method:

public ActionResult Edit(Test t)
{
    if (ModelState.IsValid)
    {
     //get the m instance
      UpdateModel(m,//other params);
      ValidateModel(m);
    }
    //saving code
}

Obiously ModelState.IsValid is always false (because 'c' is required', but it's null) and UpdateModel throws an Exception (for same reason). How can i say to MVC3 "Do not validate this field, only in this controller method?" Obiously i won't write unvalidated fields in model class! I have to update only 'b' property. Thank you.

最简单的方法是为此局部视图创建另一个视图模型。

为此视图创建另一个视图模型,并针对该视图模型而不是实体进行验证。

 @{
   object htmlAttribute = null;
   if(Model.Id > 0)
   {
       htmlAttribute = new { disabled = "disabled" };
   }
 }

 @Html.TextBoxFor(model => model.C, htmlAttributes)

when disabled, C will not be validated

When the form is in Edit mode, make the field a hidden property with a "default" value that you evaluate in the controller. If you want to not display the property on the form at all and still have it required, then you shouldn't use the "ModeState.IsValid" and do your own validation.

Example of the property being hidden:

Controller

    public ActionResult Index() {
        return View();
    }

    public ActionResult Edit(string id) {
        return View((string.IsNullOrEmpty(id)) ? new Test { a = "new" } : FakeRepository.Data(id));
    }

    [HttpPost]
    public ActionResult Edit(Test model) {
        if (ModelState.IsValid) {
            if (model.a == "new") {
                //Create a new record
            } else {
                //Update Record
            }
            return RedirectToAction("Index");
        }
        return View(model);
    }

    public static class FakeRepository {
        public static Test Data(string a) {
            return new Test {
                a = a,
                b = "B",
                c = "C"
            };
        }
    }

Entity

public class Test {
    [Key]
    [Display(Name="A Property")]
    public string a { get; set; }

    [Required]
    [Display(Name = "C Property")]
    public string c { get; set; }

    [Display(Name = "B Property")]
    public string b { get; set; }
}

View

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Test</legend>

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


        @if (Model.a != "new") { 
            @Html.HiddenFor(model => model.c)
        } else { 
            <div class="editor-label">
                @Html.LabelFor(model => model.c)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.c)
                @Html.ValidationMessageFor(model => model.c)
            </div>
        }    

        <div class="editor-label">
            @Html.LabelFor(model => model.b)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.b)
            @Html.ValidationMessageFor(model => model.b)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

Now :

.../Edit/Something will hide "C"

.../Edit/ will display "C"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM