Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

Validating with Sharp Architecture and MVC 2

DOMAIN MODEL VALIDATION AND VIEW MODEL VALIDATION IS NOT THE SAME.

- The domain model validation is inherent to our domain entities and business.
o We use the IsValid() method available on every Entity to make sure the object data is
valid before processing.

- The view model validation is inherent to what we are presenting to the user.
o It’s possible we are using the same object validation for the domain and the view, like
the following example.
o But it’s more common to create an specific view for the page we are working on .
o That means that we will probably transform that view to a know object model and we
need to validate it separately. It’s also a good practice for public forms to avoid inject
malicious form values that could end because of the automatic binder in the object
model.

Configure Sharp Architecture to use DataAnnotationsModelValidator instead


of NhibernateValidator

Find the current model provider and replace with the following line on Global.asax:

ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());

Decorate our Model entities with the corresponding DataAnnotations


attributes we need.
using System.ComponentModel.DataAnnotations;

public class Content : Entity


{
[Required]
[StringLength(10)]
public virtual string Title
{
get { return title; }
set { title = value; }
}

[Required]
[StringLength(10)]
public virtual string Body
{
get { return body; }
set { body = value; }
}
}

We can also create it with a ContentValidator class to not put so many attributes on the class itself.
Review at: http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx

Create our controller logic

public ActionResult Create()


{
return View(new Content());
}

[AcceptVerbs(HttpVerbs.Post), Transaction]
[ValidateAntiForgeryToken]
public ActionResult Create(Content c)
{
// 1. Validate the View Model State
// 2. Validate the Domain Model State.
// It’s the same on this example, but we could be creating new
// domain models objects from the view data and those should be
// validated too.
if (ModelState.IsValid && c.IsValid())
Response.Write("IsValid");
else // Rollback transaction if something was not correct.
repContent.DbContext.RollbackTransaction();

// Go back to index page.


return View(c);
}

Create our view to manage the desired logic

<script src="/js/MicrosoftAjax.js" type="text/javascript"></script>


<script src="/js/MicrosoftMvcValidation.js"
type="text/javascript"></script>

<% Html.EnableClientValidation(); %>

<% using (Html.BeginForm("Create", "SecureForm"))


{
%>

<% = Html.AntiForgeryToken() %>


<% = Html.Hidden("Content.Id", Model.Id) %>

<fieldset>
<div>
<label>Name</label>
<% =Html.TextBoxFor(model => model.Title) %>
<% =Html.ValidationMessageFor(model => model.Title) %>
</div>
<div>
<label>Body</label>
<% =Html.TextBoxFor(model => model.Body) %>
<% =Html.ValidationMessageFor(model => model.Body) %>
</div>
</fieldset>
<input type="submit" value="Send Secure Form" />

<% }%>

It’s important to note a few things here:

- The Html.EnableClientValidation automatically creates the client side validation for us.
- The Html.AntiForgeryToken() avoids CRFS attacks to be possible.
o For that we need to set the ValidateAntiForgeryToken attribute on the Create method.
o This way we can make sure nobody is playing around with our forms and sending fake
data.

Reviewing not using a domain model directly on the View

First we will create the necessary view to interact with the page.

public class ContentCreateViewData


{
[Required]
[StringLength(10)]
public string Title
{
get { return title; }
set { title = value; }
}

[Required]
[StringLength(10)]
public string Body
{
get { return body; }
set { body = value; }
}
}

Now we update the code to support that view and keep validating correctly:

public ActionResult Create()


{
return View(new ContentCreateViewData());
}

[AcceptVerbs(HttpVerbs.Post), Transaction]
[ValidateAntiForgeryToken]
public ActionResult Create(ContentCreateViewData ccvd)
{
// We need to transform our view to the real domain object
Content c = CreateContentFromView(ccvd);

// We validate the View Model State & Content Model


if (ModelState.IsValid & c.IsValid()) {
// Save changes
}
else {
// Rollback transaction if something was not correct.
repContent.DbContext.RollbackTransaction();
}

// Go back to index page.


return View(ccvd);
}

You might also like