开发者

Is it possible to have "selective" validation with Data Annotations?

I have a form which posts 13 objects right now. Some of the objects can be optional, such as the Referrer, others can not be. The problem is that if I uses DAV and decorate the objects with validation attributes such as [Required] even if the object is optional the entire post will fail because the ModelState will be invalid.

I can remove the [Required] decoration from all objects, but that's just not proper. So, is there a way to selectively validate individual objects while still using DAV?

Consider this:

<form>
    <input type="hidden" name="Description.AuthorId" value="{?}" />
    <p>
        <label>Office</label>
        <select name="Job.OfficeId">{?}</select>
    </p>
    <p>
        <label>Description</label>
        <textarea name="Description.Text"></textarea>
    </p>
</form>

In this much simplified form I'm working with Job and Description (Description is really a Note type as far as DB is concerned). Job information must be filled out, but the description is optional. The problem with the form is that Description.AuthorId is always populated with the Id of the currently authorized user.

public class Note {
    [Required]
    public short AuthorId { get; set; }

    [Required, StringLength(XXX)]
    public string Text { get; set; }
}

public RedirectToRouteResult Jobs(
    [Bind(Prefix = "Job", Include = "OfficeId")] Job Job,
    [Bind(Prefix = "Description", Include = "AuthorId,Text")] Note Description) {
    if (ModelState.IsValid) {
        if (Description != null) {
            Description.Job = Job;
        };

        DataContext.Jobs.InsertOnSubmit(Job);
        DataContext.SubmitChanges();
    };
}

The first problem with the method is that because of the form Description will always be generated because the form will always pass Description.AuthorId so the conditional checking if Description is null will never be called even if the Description.Text was never filled in.

The second problem is because of the DAV if Description.Text is not po开发者_开发技巧pulated then the entire model will fail validation because it's a required field for Note. Thereby, I wouldn't even get a chance to do anything else.

So, I guess my question is, what would be the proper way to implement validation (DAV?) on an object that could be optional in the UI form, but itself has required fields because of the database design?

One way I'm thinking of is instead of passing the objects to the method would be to instantiate them in the method and then perform TryUpdateModel on each one in order, check the model state and continue on based on conditionals. That could take a lot of code, so I want to see if there's a more automatic version before I jump into that solution.

Help would be highly appreciated!


My suggestion would be to create view models (simple models that are used for view data/validation and model binding and are mapped to db models later) for such cases. Trying to push around you business/db models with all the validations will not always be possible. If a model is validated differently in some places than most probably you are forcing a round peg in a square hole just because they are both green. If you absolutely must use the same objects because of some limitations, you can chose to ignore the validation or to remove the offending errors from the ModelState dictionary on the controller, but that is not a good idea.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜