FluentValidation usage in AspNetMvc n-tier project - asp.net-mvc

I have a multi-layered project. Layers are as follows :
Business
DataAccess
Entities
Core
MvcWebUI
I have a Category class in entity layer:
public class Category : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
I also have a CategoryValidator class in the business layer:
public class CategoryValidator : AbstractValidator<Category>
{
public CategoryValidator(IEnumerable<Category> categories)
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(50);
}
}
I have a class in the Core layer for validation.
public class ValidatorTool
{
public static void FluentValidate(IValidator validator, object entity)
{
var result = validator.Validate(entity);
if (result.Errors.Any())
throw new ValidationException(result.Errors);
}
}
I'm performing validation in the Business layer with the FluentValidate method.
But I got stuck when it came to the MvcWebUI layer. According to the FluentValidation documentation, I need to apply an attribute to the entity class as follows:
[Validator(typeof(PersonValidator))]
But since the business layer references the entity layer, I can't reach the CategoryValidator class in the entity layer. (circle reference)
How can I solve this problem?
Did I create the layers incorrectly?
Or should I define the entities as a model again in the Web layer?
Please help me.

Firstly, you probably shouldn't be exposing your entities directly in the UI so I'm going to recommend you create new models there and write validators specifically for them.
Assuming this is wired up correctly, this approach means the validators are automatically fired during the HTTP POST in the MVC app and the model state is automatically updated with a list of errors.
I use this approach extensively, albeit in MVC apps that call an internal API.
In the majority of my cases, the MVC client validates the model and if it passes the checks it then calls the API or service layer after with a DTO / service / entity model which is mapped with Automapper.
The MVC validation is typically light and checks for required fields, lengths, etc.
The API does validation again but it does it on the entity and it goes much deeper this time as it checks for duplicates, invalid entity state, etc. .
One last comment that I would like to add. I wouldn't throw exceptions on validation errors. The UI should use ModelState and the service layer returns a result which the client knows how to merge back into ModelState so either scenario results in the users getting a nice list of errors to deal with.
Hope this helps!

Generally you have 2 ways to perform validation:
Validate View Models (used in most cases)
Internal Business Entities validation (which most often used with 1-st)
For 1-st point you validate view models (on client and server), which placed in your Web project. In that case you should place view model validators in Web project too. [Validator(typeof(PersonValidator))] attribute is needed for linking view model parameter of action and action itself to perform validation before action execution. As in documentation:
Internally, FluentValidation’s MVC integration makes use of a validator factory to know how to work out which validator should be used to validate a particular type. By default, FluentValidation ships with an AttributedValidatorFactory that allows you to link a validator to the type that it validates by decorating the class to validate with an attribute that identifies its corresponding validator.
If you want to validate business models (2-nd point), not/not only view models, you need to place entity validators to Business project and register them in your IoC container (example with Castle Windsor), and change validator tool next way:
public class ValidatorTool
{
public static void FluentValidate<T>(IContainer container, T entity) // replace IContainer with your actual container interface name
{
var validator = container.Resolve<IValidator<T>>();
var result = validator.Validate(entity);
if (result.Errors.Any())
throw new ValidationException(result.Errors);
}
}

Related

How to call model methods in controller in asp.net mvc

I am working on an asp.net mvc application.
This is the approach that i am following right through the application.
Here is my model:
public class EmployeeModel
{
//Properties
// Constructors
// Methods
}
My View: (strongly typed with model Properties) for example : Some Edit View
My Controller:
[httppost]
public void save(Employeemodel m) // ajax call that gets updated model details
{
m.update() // making database call from controller action
}
Are there any serious design issues with my approach of MVC. May be i mis understood MVC?
Is it appropriate to call model methods(m.update() ) in controller action?
Model contains methods that manipulate data ? IS it correct?
please help/suggest the correct approach to follow in MVC
I would recommend you to have separate layer to save data to the database, because its not just MVC that one should follow.
You should use Model(with function only) as a provider whose duty is to perform database task.
ViewModel that hold your entities (properties only)
Controller that can handle your application logic.
View to render HTML/UI.
So its not about MVC rather the best practice one should follow to architect an application.
Further we have several options that we must consider before planning architecture of an application.
Service/Business Layer - Interact b/w Application layer and Repository
Providers/Repository Layer - Interact b/w Service layer and Database
So, it depends on the level of abstraction you want, but as far as MVC concern I would recommend you to have extra layer of separation of ViewModel MVVM.
Its better to ask these type of questions in stachexchange chat.
Example
ViewModel
public class User
{
public Guid Id {get;set;}
public string Name {get;set;}
}
Model
public class UserModel
{
public void AddUser(User user)
{
//add to the database
}
public void UpdateUser(User user)
{
//update in the database
}
}
Controller
[HttpPost]
public ActionResult UpdateUser(User user)
{
UserModel user = new UserModel();
user.UpdateUser(user);
}
In general practice you should now follow this methodology.
Although this is the default MVC behavior of accepting entire model as an argument you should have a middle layer called as DTO(Data Transfer Object) or ViewModel which represents UI.
And after accepting and validating View model you can transform it to your main business entity.
Offcouse it depends how you have written code in your update method but the main hack is this case is that.... any body can pass any known property value to this method and can hack your system. for example suppose you have following values in your Employeemodel
{
Id,
Name,
SecurityCode,
...
}
and your edit screen just have Name input to update it. Any body can add extra html for SecurityCode and can add bad value to it :)
I hope i didn't confused you.
For start try to implement Repository pattern MVC... Google it and you'll find the basic usage of it. :)
Cheers
Your logic is fine. But as K D said, you should have viewmodel that represents view. I would suggest you write your methods in view model since you will pass only model entity to database or anywhere else.
public class Employee
{
//Properties
}
public class EmployeeViewmodel
{
// Employee model object
//Constructors
//Methods
}
return view("View name", EmployeeViewModel);
So you can update model, pass Employee alone to Database via OR/M ..This is basic flexible approach. You can have a utility model class which contains common data retrival like City, state, gender .. so you wont mix entity with other models.

MVC Validation: Service Layer or Data Annotations

I hope this isn't terribly subjective, but when it comes to validating business logic, I see two paths that, unless I'm mistaken, deliver pretty much the same result:
Use a service layer where all validation on your models is performed (ref: http://www.asp.net/mvc/tutorials/older-versions/models-%28data%29/validating-with-a-service-layer-cs)
Decorate your models with Data Annotations
In the first instance, the model is a dumb container for data, and in the second, the model knows about its valid state. Above and beyond that, is there nuance between the two that I'm missing? Should one be used over the other in some instances?
Thanks,
Chris
In my opinion, you could keep the basic validation (required fields, regex fields, comparative fields etc...) on your Model (InputModel) with Data Annotations or Fluent Validation, and your bussiness validation in service layer. I think the Annotations is much more to create a screen validation and inputs to server side than business validation. If you keep the business at the service layer you must remember to create a ModelState Wrapper to integrate it with Asp.Net MVC, and show it on the view.
Take a look at a samepl of ModelState Wrapper:
public class ModelStateWrapper : IValidationDictionary
{
private ModelStateDictionary _modelState;
public ModelStateWrapper(ModelStateDictionary modelState)
{
_modelState = modelState;
}
#region IValidationDictionary Members
public void AddError(string key, string errorMessage)
{
_modelState.AddModelError(key, errorMessage);
}
public bool IsValid
{
get { return _modelState.IsValid; }
}
#endregion
}
They are not mutually exclusive, you can use attributes for "static" rules, and service layer validation for "dynamic" rules (e.g. check for uniqueness).
Quoting the tutorial you referred to:
In this tutorial, you learn how to move your validation logic out of
your controllers and into a separate service layer.
Well, the model decorated with data annotation attributes does not have to be in the web project next to the controller, it can be in the service layer next to the service, which means all validation logic is in one place.

How are you populating/validating your ViewModels?

I'm curious of all of the various ways people are building their ViewModels and why they choose that method.
I can think of several ways here:
-1. Injected repository - the controller loads the model and maps to the ViewModel. Here the ViewModel constructor could take various collections to interally set for ex. in a select list such as:
public CustomerController(ISomeRepository repository)
{
_repository = repository;
}
public ActionResult Create()
{
CustomerCreateViewModel model = new CustomerCreateViewModel(_repository.GetShipTypes,
_repository.GetStates);
..
..
}
-2. ViewModelBuilder - Either injected or instantiated in the controller with an instance of the injected repository. Called via something like
>var orderViewModel = orderViewModelBuilder.WithStates().Build(orderId);
or,
var orderViewModel = orderViewModelBuilder.WithStates().Build(orderId);
-3. Directly in controller (no code required - its messy)
-4. Some other service (injected or not) that returns domain model which the controller then maps or a ViewModel (anyone doing this to return a view model that isn't specifically named/noted as a ViewModel builder class?)
public JobCreateViewModel BuildJobCreateViewModel(int parentId)
{
JobCreateViewModel model = new JobCreateViewModel();
model.JobStatus = _unitOfWork.JobRepository.GetJobStatuses();
model.States=_unitOfWork.StateRepository.GetAll();
return model;
}
Now on the return trip - regarding validating your view models - are you inheriting from a base ViewModel class for standard validations, or copying your validations (ex. data annotation attributes) between all of your ViewModels, or simply relying on server side validation so it can all be validated againt your domain object?
Any others? Anything better? Why?
EDIT
Based on a link below, I did find a nice article from Jimmy Bogard on the architecture of ViewModels. While it doesn't address the question above directly, it's a great reference for anyone coming here for ViewModel information.
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
I inject a service into the controller, not a repository, and then use AutoMapper to convert it into a view model. The benefit of the service layer in this case is that it could aggregate multiple simple operations from one or more repositories into a single operation exposing a domain model. Example:
private readonly ICustomerService _service;
public CustomerController(ICustomerService service)
{
_service = service;
}
[AutoMap(typeof(Customer), typeof(CustomerViewModel))]
public ActionResult Create(int id)
{
Customer customer = _service.GetCustomer(id);
return View(customer);
}
in this example AutoMap is a custom action filter that I can write which executes after the controller action, inspects the returned object and uses defined AutoMapper mappings to map it to the specified destination type. So the view gets the corresponding CustomerViewModel as model type. Would have been equivalent to:
public ActionResult Create(int id)
{
Customer customer = _service.GetCustomer(id);
CustomerViewModel vm = Mapper.Map<Customer, CustomerViewModel>(customer);
return View(vm);
}
it's just that it is too much plumbing and repetitive code that could be centralized.
I would also recommend you watching the putting your controllers on a diet video from Jimmy Bogard.
I just finished a project where we did a variation on #4. We had a service class injected into the controller. The service class held dependencies on the repository and a model builder class (we called it model factory).
The controller called into the service class, which handled business validation logic, and then fetched view models from the appropriate factory. The models themselves relied on data annotations for input validation.
It worked really well for our team. There was enough separation of concerns to allow the devs to do their work without affecting one another, but it was manageable enough to understand what was going on.
It's the first time we tried it and we'll be sticking with it. I'm interested to see how others respond.
Our method is to inject the repository in to the controller and map it to the ViewModel using Automapper http://automapper.org/. Our ViewModels contain data annotation attributes to allow the validation to occur on the client.
We call methods on the repository which return Domain objects (Entity Framework). The domain objects are mapped to the ViewModel. We tend to use the same ViewModel for edits and adds so the data annotations are needed once. In its simplest form it looks like the following code:
public ActionResult List(int custId, int projId)
{
var users = _userRepository.GetByCustomerId(custId);
var userList = Mapper.Map<IEnumerable<CMUser>, IEnumerable<UserListViewModel>>(users);
return View(userList);
}
I use a service layer that hides the domain model from the controller returning ViewModels from the service methods. This allows me to make changes to the domain model without impacting the client.

Validation approach on MVC3 CRUD application with EF4-based WCF as backend

I develop a simple MVC3 CRUD application - simple controllers / views, which uses WCF service for CRUD data access.
The WCF uses EF4.1 with DbContext, and simple CRUD-style methods: ListEntities, GetEntity(ID), AddEntity (entity), DeleteEntity(ID)
If I develop the MVC application directly with EF, code first, I can annotate properties in the entity classes with validation attributes, and the MVC application will automatically recognize validation errors and report them in the UI when I try to save and a validation error occurs (e.g. a required field is not set).
But in my application I don't use this approach and I face two problems:
My entities in the WCF are generated from the EDMX, which in turn was also generated from the database. So I cannot actually add to them any data validation annotation attributes, because they'll vanish as soon as the entities will be regenerated from the EDMX. Is there any solution to this?
Since my client (MVC app) does not share the data contract classes with WCF (for clear separation), but instead it is generated form service reference, even if I find a way to add data annotation attributes to server-side data contract classes, will they be recognized and recreated when the data contract proxy class is created on client side?
So how could I made the MVC application to use client side validation and error message reporting for validation failures when binding to entities exposed by WCF service as data contracts?
One idea I have is, on client side, to create derived classes for all entities exposed as data contracts, and apply annotation attributes to them to desired properties. But this doesn't looks like a good solution to me, because with this I create a logic "coupling" between UI client and the WCF service / data layer (forcing UI to know about data more than it should do - by putting BL logic in client).
Can anyone give me some suggestions on how to handle those this situation?
Thanks
1: Yes you can add validation using the System.ComponentModel.DataAnnotations.MetaDataType.
I answered this question at MVC Partial Model Updates
2a: What you can do is create a seperate Class Library Assembly that contains all the interfaces (with or without additional MetaDataTypes) and use that on both the WCF service and the MVC application. After you add the reference to your MVC application, when adding the WCF Service reference, you can match the WCF Service DataContacts directly to the interfaces in the Assembly. One Caveat is that both the WCF service and MVC application are dependant on the Assembly (some might consider this tightly coupled) but this should be ok because you are only tightly coupling at the interface level, and whether or not you choose to allow VS to recreate it's own interfaces/classes or reuse what you already created in the Assembly it boils down to the same thing in my opinion.
2b: If you decide not to use a Class Library, I'm pretty sure that the service reference classes are partial, and you can simply create another .cs file with partial classes and add the interfaces as I described in part 1 to the partial classes.
Update
I am currently using Entity Framework to access my database. Entity Framework, like WCF References, classes are Auto-Generated classes will look something similar to:
[EdmEntityTypeAttribute(NamespaceName="MyNameSpace", Name="Info ")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class Info : EntityObject
{
public static Info CreateInfo (global::System.Int32 id)
{
Info info= new Info ();
info.Id = id;
return info;
}
public string Name { get; set; }
public string FavoriteColor { get; set; }
// etc etc
}
In a separate file with the same namespace as the previous partial class, I have created:
[SomeAttribute1]
[AnotherAttribute2]
public partial class Info: IInfo
{
}
So now my auto-generated class is not only based on an Interface I created IInfo so the actual methods are not exposed (because my datatier in MVC returns interfaces), but it also has Attributes (for Data Annotations or whatever).
What I would suggest is instead of putting your data annotations directly on your WCF Service reference class is to use the MetedataType DataAnnotations. This allows you to separate the actual data object with the data annotations validations. Especially helpful if you want to use the same data class with different validations based on whatever (maybe administrators don't have to have a valid favorite color).
For example:
public interface NormalUser
{
[Required]
string Name { get; set; }
[Required]
string FavoriteColor { get; set; }
}
public interface AdminUser
{
[Required]
string Name { get; set; }
string FavoriteColor { get; set; }
}
[MetadataType(typeof(INormalUser))
public class NormalUserInfo : Info { }
[MetadataType(typeof(IAdminUser))
public class AdminUserInfo : Info { }
In this example we have two different classes NormaUserInfo and AdminUserInfo which both have different validations. Each of them have inherited from Info so they are valid models that can be passed into the WCF Service.
Out of my mind, as I can't test it right now...
Let's say your autogenerated code is like this:
public partial class Employee
{
//some code here
}
You can add a new Employee class, also partial, and this one won't be autogenerated
[you can annotate here]
public partial class Employee
{
//somecode here
}
try it
As for the validation, you could use: http://fluentvalidation.codeplex.com/

How to mock a model in ASP.NET MVC?

I've made a custom model, and I want to mock it. I'm fairly new to MVC, and very new to unit testing. Most approaches I've seen create an interface for the class and then make a mock that implements the same interface. However I can't seem to get this to work when actually passing the interface into the View. Cue "simplified" example:
Model-
public interface IContact
{
void SendEmail(NameValueCollection httpRequestVars);
}
public abstract class Contact : IContact
{
//some shared properties...
public string Name { get; set; }
public void SendEmail(NameValueCollection httpRequestVars = null)
{
//construct email...
}
}
public class Enquiry : Contact
{
//some extra properties...
}
View-
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<project.Models.IContact>" %>
<!-- other html... -->
<td><%= Html.TextBoxFor(model => ((Enquiry)model).Name)%></td>
Controller-
[HttpPost]
public ActionResult Index(IContact enquiry)
{
if (!ModelState.IsValid)
return View(enquiry);
enquiry.SendEmail(Request.ServerVariables);
return View("Sent", enquiry);
}
Unit Testing-
[Test]
public void Index_HttpPostInvalidModel_ReturnsDefaultView()
{
Enquiry enquiry = new Enquiry();
_controller.ModelState.AddModelError("", "dummy value");
ViewResult result = (ViewResult)_controller.Index(enquiry);
Assert.IsNullOrEmpty(result.ViewName);
}
[Test]
public void Index_HttpPostValidModel_CallsSendEmail()
{
MockContact mock = new MockContact();
ViewResult result = (ViewResult)_controller.Index(mock);
Assert.IsTrue(mock.EmailSent);
}
public class MockContact : IContact
{
public bool EmailSent = false;
void SendEmail(NameValueCollection httpRequestVars)
{
EmailSent = true;
}
}
Upon a HttpPost I get a "Cannot create an instance of an interface" exception. I seems that I can't have my cake (passing a model) and eat it (pass mock for unit testing). Maybe there's a better approach to unit testing models bound to views?
thanks,
Med
I'm going to throw it out there, if you need to mock your models you're doing it wrong. Your models should be dumb property bags.
There is absolutely no reason that your model should have a SendEmail method. That is functionality that should be invoked from a controller calling to an EmailService.
Responding to your question:
After years of working with Separation of Concern (SOC) patterns like MVC, MVP, MVVM and seeing articles from people brighter than me (I wish I could find the one I'm thinking off about this but maybe I read it in a magazine). You will eventually conclude in an enterprise application you will end up with 3 distinct sets of model objects.
Previously I was a very big fan of doing Domain Driven Design (DDD) using a single set of business entities that were both plain old c# objects (POCO) and Persistent Ignorant (PI). Having domain models that are POCO/PI leaves you with a clean slate of objects where there is no code related to accessing the object storage or having other attributes that have schematic meaning for only 1 area of the code.
While this works, and can work fairly well for a period of time, there is eventually a tipping point where the complexity of expressing the relationship between View, Domain Model, and Physical Storage Model becomes too complex to express correctly with 1 set of entities.
To solve the impedance mismatches of View, Domain and Storage you really need 3 sets of models. Your ViewModels will exactly match your views binding to facilitate it to be easy to work with the UI. So this will frequently have things such as adding a List to populate drop downs with values that are valid for your edit view/action.
In the middle is the Domain Entities, these are the entities that you should validate against your business rules. So you will map to/from them on both sides to/from the view and to/from the storage layer. In these entities is where you could attach your code to do validation. I personally am not a fan of using attributes and coupling validation logic into your domain entities. It does make alot of sense to couple validation attributes into your ViewModels to take advantage of the built in MVC client side validation functionality.
For validation I would recommend using a library like FluentValidation (or your own custom one, they're not hard to write) that lets you separate your business rules from your objects. Although with new features with MVC3 you can do remote validation severside and have it display client side, this is an option to handle true business validation.
Finally you have your storage models. As I said previously I was very zealous on having PI objects being able to be reused through all layers so depending on how you setup your durable storage you might be able to directly use your domain objects. But if you take advantage of tools like Linq2Sql, EntityFramework (EF) etc you will most likely have auto generated models with code for interacting with the data provider so you will want to map your domain objects to your persistence objects.
So wrap all of this up this would be a standard logic flow in MVC actions
User goes to edit product page
EF queries the database to get the existing product information, inside the repository layer the EF data objects are mapped to the Business Entities (BE) so all the data layer methods return BEs and have no external coupling to the EF data objects. (So if you ever change your data provider you don't have to alter a single line of code except for the internal implementation)
The controller gets the Product BE and maps it to a Product ViewModel (VM) and adds collections for the different options that can be set for drop down lists
Return View(theview, ProductVM)
User edits the product and submits the form
Client side validation is passed (useful for date validation / number validation instead of having to submit the form for feedback)
The ProductVM gets mapped back to ProductBE at this point you would validate the business rules along the lines ValidationFactory.Validate(ProductBE), if it's invalid return messages back to view and cancel edit, otherwise continue
You pass the ProductBE into your repository model, inside the internal implementation of the data layer you map the ProductBE to the Product Data Entity for EF and update the database.
2016 edit: removed usages of Interface as separation of concerns and interfaces are entirely orthogonal.
Your issue is here:
public ActionResult Index(IContact enquiry)
MVC in the background has to create a concrete type to pass to the method when calling it. In this method's case, MVC needs to create a type which implements IContract.
Which type? I dunno. Neither does MVC.
Instead of using interfaces in order to be able to mock your models, use normal classes that have protected methods which you can override in mocks.
public class Contact
{
//some shared properties...
public string Name { get; set; }
public virtual void SendEmail(NameValueCollection httpRequestVars = null)
{
//construct email...
}
}
public class MockContact
{
//some shared properties...
public string Name { get; set; }
public bool EmailSent {get;private set;}
public override void SendEmail(NameValueCollection vars = null)
{
EmailSent = true;
}
}
and
public ActionResult Index(Contact enquiry)
It is possible to use interfaces.
See: http://mvcunity.codeplex.com/

Resources