简体   繁体   中英

Validation for ViewModels different from the page ViewModel

Assume I have a page (View) that takes a certain ViewModel:

@model IEnumerable<MyProject.ViewModels.MyViewModel>

In this page, I have a form that posts data through another ViewModel (let's call it a PostModel):

@using (Html.BeginForm("Order", "Order", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Give your order info</h4>
    <hr />
    @Html.ValidationSummary()
    <div class="form-group">
        <label for="Order.Name" class="col-md-2 control-label">Name:</label>

        <div class="col-md-10">
            @Html.TextBox("Order.Name", null, new { @class = "form-control" })
            @Html.ValidationMessage("Order.Name")
        </div>
    </div>
    ...
}

This is processed on the controller in an Order HttpPost action method that takes an argument of my PostModel's type.

I can display validation messages in the style I have above. My question is, how (if possible) can I make this strongly typed for my PostModel? Something like:

@Html.TextBox<MyPostModel>(t => t.Order.Name, ...)
@Html.ValidationMessageFor<MyPostModel>(t => t.Order.Name)

Is this at all possible, without changing the ViewModel of the page?

you can simply use a different partial-view for that form and in that partial-view you can specify it to be of any type you want, in this case, as i see in your code example, Order

Lets say you have a model called Order with the following definition

public class Order
{
    public string Name { get; set; }
}

and also a partial-view called _MyPostPartialView.cshtml with its definition

@model Order

@using (Html.BeginForm("Order", "Order", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Give your order info</h4>
    <hr />
    @Html.ValidationSummary()
    <div class="form-group">
        @Html.Label(m => m.Name, "Name:")

        <div class="col-md-10">
            @Html.TextBox(m => m.Name, null, new { @class = "form-control" })
            @Html.ValidationMessage(m => m.Name)
        </div>
    </div>
    ...
}

and you're done!

try import javascript bellow in your view

jquery.validate.min.js
jquery.validate.unobtrusive.min.js

In your form view

@Html.LabelFor(model => model.ClientDocument[0].Number)
 @Html.TextBoxFor(model => model.ClientDocument[0].Number, new { @class = "form-control" })

In your controller

[HttpPost]
public ActionResult Create(YourViewModel model){
if (ModelState.IsValid)//to complete validate server side
}

In your ViewModel *Try use DataAnnotation

 [Display(Name = "Name of Field")]
    [Required(ErrorMessage="your message error")]        
    public string Name { get; set; }
    public DocumentViewModel[] ClientDocument { get; set; }

The simple answer is don't use a different view model for GET vs POST. There's no reason to. Anything you POST should be rendered through the view model used for the GET request. If you are for some reason posting something that was not initially on the view model used for the GET request, then frankly, stop it.

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