How to handle service-layer validation in MVC3 - validation

I am working on a project which requires different validation sets for the same model, and we're trying to find the best solution to handle it.
A simplified example could be using our Customer DTO:
public class Customer
{
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required] // Only required on some views
public string Title { get; set; }
}
In our first view, all fields are required, as they're shown in the DTO using DataAnnotations.
In our second view, FirstName and LastName may be required, but Title is optional, and may not even be represented on the view.
The complication comes in, that we want to have validation rules live in our service layer (so that we can provide an API at a later point utilizing the same validation), which can access the data annotations, and validate against them, reporting back up to the UI if they don't validate.
So far, the winning method is:
Every view has a dedicated viewmodel, which the DataAnnotations exist on.
The viewmodel then maps our domain objects using something like Automapper.
The domain objects are then passed to the repositories and services to have actions taken upon them.
This also means:
Validation would not occur in the service layer, since by the time the objects got there, they would be domain objects instead of viewmodels.
Is there some better way that we should be handling this for an enterprise application? We have yet to find a solution.

You can't cram all your validation into one place when it's context-specific. Use your winning method, but also have your entity services do appropriate validation in that layer.

Related

MVC: Should logic be placed in the Model or Service layer?

Recently I talked with a co-worker and had a conversation regarding Model View Controller paradigm. We were talking about proper organization of files and such and I mentioned that I thought that "skinny controllers and fat models" were the way to go. Meaning that the controller just calls the "fat models" methods which contain business logic:
public class CreditCard {
//instance vars
//constructor
//getters
//setters (if you want mutability)
public boolean makeCreditCardPayment(Cart cart) {
//implementation details...
}
}
My co-worker mentioned otherwise. He said that the models shouldn't really be "fat" and contain any other business logic. The model should just be a data-structure and contain zero methods (obviously if your are in Java you need setters and getters). Just like a C-style structure, obviously with data fields that have mutators and accessors:
public class CreditCard {
//instance vars
//constructor
//getters
//setters (if you want mutability)
}
public class PaymentService {
public boolean makeCreditCardPayment(CreditCard card, Cart cart) {
//implementation details...
}
public boolean makePayPalPayment(PayPal paypal, Cart cart){
//implementation details...
}
Or even have a PaymentService for each type of payment that implements an interface. So something like 'CreditCardPaymentService implements Payment' or 'PayPalPaymentService implmeents Payment'.
To me, using the service method way seems like we are just going back to procedural style programming.
Another example would be a 'Vehicle' object with a getSpeed method compared to a service which takes in a Vehicle object and returns the speed.
I have looked over other stackoverflow answers but they have differing answers. In one question, one of the users mentioned that the service layer is part of the models part of MVC. I am looking for other answers.
I've encountered many different philosophies claimed to fall under the MVC umbrella.
My position:
Models directly manage some kind of backing store, and should contain mutation and validation logic.
Controllers should look like a model to other controllers and views (making them composable), and contain any additional logic required to validate the mapping from the controller's interface to a model's interface.
Views just contain whatever state and logic they need to function; their purpose is to display data and collect input.
It looks like your PaymentService is trying to be more than one controller, so I'd go the separate CreditCardPaymentService and PayPalPaymentService route.

Web api map request parameter with a hyphen to a Pascal cased complex model property

I am trying to figure out a way to map POSTED form parameters that have hyphens in them to a WEB-API method that takes a complex object.
Some context:
We are using Mailgun to forward a processed email to our own custom Web API Controller method.
Mailgun POSTS to our API and some of the parameters it uses have hyphens in them - for example: body-plain.
My C# complex model will have a property to match in Pascal Case (can't use hyphens in property names)
so if these parameters are generated by Mailgun and posted to our WEB API controller:
from
subject
body-plain
body-stripped
timestamp
and our complex object looks like this:
public class Response{
public string From{get; set;}
public string Subject{get; set;}
public string BodyPlain{get; set;}
public string BodyStripped{get; set;
public int Timestamp{get; set;}
}
Then From, Subject, and Timestamp all map correctly - but BodyPlain and BodyStripped do not - they are null since the model binding can't translate the hyphenated parameters to Camelcase.
Is there a way to do this?
I have seen some posts referring to different ways to achieve this with MVC but we are not using MVC, just strictly WEB API.
You can use the Request object in the controller, which will make the parameters available key/value style.
In the case of Mailgun forwarding (which was the same problem I ran into), the Request.ReadFormAsync() method will expose the IFormCollection, from which you can access the parameters you need via:
IFormCollection.TryGetValue("my-parameter", out StringValues myParameter)
Since the parameters are sent through form submission and not JSON, using [JsonProperty(PropertyName = "my-param")] won't help and you'll have to resort to having your action receiving a parameter of type FormDataCollection and then inside your action you'll map it to your complex object. An alternative is to implement a custom model binder.
In this post there are details about those two options.

How can I make my ViewModel map to my actual Model?

I have a tab in my application, upon clicking which, the user's details are displayed (using the placeholder HTML attribute) to him inside editable text-boxes. The user can simply view them or can edit whichever detail he wants to.
Now my question is: should I create a View Model class for this scenario or should I use the actual Account model class? I guess I will have to create a View Model class as I will require only 'some' properties from the Account model class, but if I do so, how will I make it 'editable' and subsequently, map the edited properties(if any) to the actual Account model class?
Also, please tell me where exactly do I need to store the View Model class if I need to create one.
should I create a View Model class for this scenario or should I use
the actual Account model class?
Yes, it's best to create a model that represents the action you need and you do that to prevent under and over posting. So you work on properties where you expect users to work on. For example, if you have an AccountModel that has a lot of properties and you only need to work on ten of it on an add action and five of its properties on an edit action, then you create two ViewModels:
// your model or entity
public class AccountModel {
// the list of properties goes here
}
// your view models
public class CreateAccountModel {
public string Username {get;set;}
public string Password {get;set;}
public string Phone {get;set;}
}
// this model is for the scenario
// where you want users to edit their basic info
// but not the password (e.g. you have a separate
// functionality for changing the password)
public class EditAccountModel {
public string Username {get;set;}
public string Phone {get;set;}
}
Now to map your viewmodels to your actual model or entity, you can use mapper tools or do it on your own (tiring but an option for small models). Here are the steps:
You receive the model/entity from a post
You query your entity from your database
You copy the values from the viewmodel to the model/entity
You save the model/entity back to your database
where exactly do I need to store the View Model class
You can have it in your MVC project under the Models folder that was created. This is more of a preference really and there is no standard way of doing it - especially if you start layering your application. Put it somewhere where it makes more sense.

MVC.NET: Sharing validation rules between controllers and the service (business) layer

I'm working on a project where we have multiple UI (view) models with DataAnnotations attributes for validation, mainly for input such as required fields, length, regular expressions, etc):
[Required]
public int Order { get; set; }
[Required]
[MaxLength(150)]
public string Title { get; set; }
The controller checks the ModelState to make sure objects are valid before handing them to the service layer.
Now, the service layer also validates the objects in order to accommodate for future changes that may require a new controller to support other output formats or another utility to import objects in batch.
My question is: Knowing that there should be a separation of concerns where controllers deal with UI models and Service layers deal with Business Objects, and therefore, I wouldn't like to pass UI model objects to the service layers, what's the preferred way to reuse the validation rules in the UI model objects? Or should they be replicated with code in the service layer? or should the DataAnnotations be added to the Business Objects too?
I'm using EF model first, so I don't see a simple way to add these annotations to the auto-generated POCOs.
Why not use FluentValidation? That way you can create a validator for each view model and run them in your UI layer and service layer if needs be. It also removes the need to decorate your view models with validation attributes. http://fluentvalidation.codeplex.com/

ASP.Net MVC3, DataAnnotations and Dynamic Validation

I'm creating an MVC 3 application that needs to establish data validation rules at runtime based on external data (e.g. Required, MinimumLength, MaximumLength). It seems natural to use Data Annotations in MVC 3, however the property attributes that provide validation metadata are set at compile-time.
Is there a pattern to use Data Annotations with metadata provided at runtime?
Example:
public string Text { get; set; }
public void SetIsRequired(string propertyName, bool required)
{
// Somehow find the property 'propertyName' and create/remove a RequiredAttribute
// on that property
}
...
SetIsRequired("Text", true);
I'm aware of TypeDescriptor, but don't see an option to modify attributes of a property of an instance (only class level attributes on an instance, or property level attributes for a type).
It seems natural to use Data Annotations in MVC 3
Not for me. I never really liked data annotations due to their declarative nature. And doing validation in a declarative way limits capabilities. I have always liked and use FluentValidation.NET.
You could probably use the IDataErrorInfo interface (which MVC can consume) to write your custom, dynamic, validation rules.

Resources