CompareAttribute and comparing against properties on a complex type - asp.net-mvc-3

I've just read about MVC3's new CompareAttribute that you can apply to a model's property to define another property that it should match - the classic use case is confirming email address has been entered correctly, or having a Password and ConfirmPassword field. I've run into a problem with trying to implement it in my own project.
We've got a fairly standard User object which, among other things, has these properties:
public class User {
....
[Required, RegularExpression(RegularExpressions.Email, ErrorMessage = "Please supply a valid email address")]
public string EmailAddress
[Required]
public string Password
....
}
I've then incorporated User and a couple of other objects that we need into a view model:
public class SignUpViewModel {
....
public User user { get; set; }
....
}
Which, when passed to the form in the UI, allows the ModelBinder to run the Data Annotation validation for the User object as well as the other objects and primitive types in SignUpViewModel when the user submits the form. I was really pleased when this all "just worked" because it meant that we could define validation in just one place and not have too much work to do in persisting out to the database or map UI models to domain models etc.
Noticing that the Html.EditorFor(model => model.User.Password) emits an with the name set to "User.Password", I added the following to SignUpViewModel:
[Required, Compare("User.Password")]
public string ConfirmPassword { get; set; }
but submitting the form now triggers a validation error along the lines of "Could not find a property named User.Password". I was hoping that it would follow the same kind of convention, but it would appear not :(
I don't really want to put ConfirmPassword into the User object as ConfirmPassword is purely a UI concern, and it seems wrong to have that in a domain object like that. I also don't really want to flatten out the various objects within SignUpViewModel as that starts to feel like duplication of where validation rules are defined, and we're trying to keep our code as DRY as possible.
Has anyone come across a way to get CompareAttribute working with comparing against properties of sibling objects rather than sibling properties as it would appear the attribute expects to?

Get rid of the User property on your SignUpViewModel and put the necessary properties from the User domain object on the SignUpViewModel.
You said you want your concerns separated, and having a domain object as a property on the view model is an example of not having your concerns separated.
This might seem like it could result in your writing more code, but look into a solution like Automapper to automate mapping your domain object properties to view model properties.

Even though smartcaveman's response is great from the architectural standpoint it does not address the original question about inability to leverage CompareAttribute's client-side validation in MVC3 inside models contained within some parent model (complex model). I know of a situation where some reusable [sub]model can be reused from within several parent container models and CompareAttribute is used inside the submodel. The server-side validation in MVC3 will work just fine (when javascript is disabled on the client), but there is a bug in javascript provided by Microsoft that breaks client-side validation. Please follow the link below for the resolution:
MVC3 CompareAttribute Client-side Bug (stackoverflow)

I recently ran into this problem myself; here's how I solved it.
[Compare("OriginalPassword")]
public string ConfirmPassword { get; set; }
public string OriginalPassword
{
get
{
return User.Password;
}
}

Related

how to synchronize data annotations between model and view models

I'm working with EF Code First, so my data annotations are driving my SQL server database columns definitions/properties (i.e., [StringLength(30)] = nvarchar(30), etc.). I'm using ViewModels to drive my views. How can I synchronize the data annotations between Models and ViewModels?
For example, I have the following entity class:
public class Ticket
{
...
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:C}")]
public double TicketBalance { get; set; }
...
}
And a ViewModel that uses the same property from the Model class:
public class EditTicketViewModel
{
...
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:C}")]
public double TicketBalance { get; set; }
...
}
How can I synchronize these two data annotations?
While you can't change the attributes on your ViewModels at runtime, you can to some degree emulate them for the purposes of validation (which is presumably the reason that you're using data annotations).
This requires creating the ViewModels using an object mapper like AutoMapper or EmitMapper. You can then hook into an appropriate part of the mapping process to update the DataAnnotationsModelMetadataProvider and DataAnnotationsModelValidatorProvider, which are used by MVC in the various parts of the validation process.
This answer shows a way of doing it with AutoMapper. I'm currently having some fun looking at a solution with EmitMapper, since that's somewhat faster to execute.
There is no synchronization between the two. While they may look similar, they actually are different: one is for the database, another is for the GUI.
For the database you mainly want to test for [Required] and [StringLength(XXX)]. Sometimes [DataType] as well.
For the GUI you want to check for those in addition of formatting, regular expressions, ranges etc.
There are validation attributes, display attributes, data modeling attributes. Choose the right attributes category at the right place according to the situation.
And it gets even worse when you start using things like jQuery validation or KnockoutJS validation. In that case you will have to duplicate your efforts third time for JS purposes. Unfortunately.
You can also check what other folks did here: How do I remain DRY with asp.net mvc view models & data annotation attributes?
There folks use inheritance. which is fine, but a bit confusing while you let others read your code later on.
The good advise is to switch from data annotations to fluent validation as per one of the responses in the link above. It will allow you to apply the same validation class to multiple models.
Hope this helps.

ASP.Net MVC 3: Custom data binder to transform data coming from/going to the DB

I am working on an ASP.Net MVC 3 project where I would like to encrypt all emails stored in a database for additional protection in case some hacker would ever get access to the db, and I was wondering what was the best way to achieve this.
I read a bit about custom model binders, but this is for the binding between the controller and the view. I am not sure if this is what I want, since I may need to have access to unencrypted email addresses in the code (in the Service Layer, where I have the Business Rules). So I would have preferred the encryption/decryption to occur automatically when the model is saved to/loaded from the database, and this is what I don't know how to do.
We can imagine that I have this POCO model:
public partial class Contact
{
public virtual int ContactId { get; set; }
public virtual string Name { get; set; }
public virtual string Email { get; set; }
}
What I need is a way to have the Email property encrypted when it is persisted to the database and decrypted when it is loaded from the database.
One way to do it would be to have an extra UnencryptedEmail property in my Contact model that would have a getter and a setter that would decrypt and encrypt the Email property, but I find that having to add an extra property is not as clean a solution.
If, for some reason, using a custom IModelBinder is the way to go, please let me know why and tell me how to get it to be applied only on the Email property of the Contact model. Up to now, I have only seen implementations for applying transformations on all properties of a specific data type.
Consider using the Model View approach instead of directly binding to models and displaying them in the Views.
As for encryption and decryption there are tons of approaches you can employ.
I can see what you are looking for, instead of answering and explaining the whole stuff, I can point you to a related material which is not exactly what your requirement is but you can take a cue from it.
http://codefirstmembership.codeplex.com/
In the above code first membership provider code, the passwords are hashed and stored in database and for comparison the hashing is removed and then they are compared.
I understand it will be time consuming but its worth to take a look at.
I don't think the model binder is the right way to go. The encryption of an email sounds like a business requirement and as such I would place it in the business layer.
When storing the email, your business layer would get the plain email address as input from the application layer, encrypt it and pass the encrypted value to the repository.
When retrieving the email, your business layer would receive the email in an encrypted state from the repository, decrypt it and pass it back to the application layer.
Unless you require it, the application layer would not need to know about the encrypted version of the email as it only deals with the plain version of it. On the other end the repository would not need to know about the decrypted version of the email as it only needs to deal with the encrypted version of it. To that end the business layer does sound like the best place to handle this.

ASP.NET MVC DataAnnotation - Convert to Lowercase

I am having a bit of a problem with login/register authentication on a site in regards to case scheme.
First, I started out by just having the regular expression for the input fields only accept lowercase. Seemed like the smartest thing to do. But that backfired horribly. Basically put, even if I put in the text You must use only lowercase letters, people don't read it, get frustrated, and then just don't bother to register.
So then, to remedy this, I fixed it so that the regular expression could take both upper and lowercase values. When I stored the email addresses in the database, I just converted them to lowercase. Everyone seemed happy for about 8 seconds.
However I am finding myself having to do this in multiple places, now. And it is getting obnoxious. I was wondering if there was a way to make a DataAnnotation for my ViewModel, like ..
class LoginViewModel {
[ConvertLowercase]
public string Email { get; set; }
/// ... other view model properties
}
That would always ensure that that result turned lowercase before it hits my controller, thus bottlenecking the entire operation at the ViewModel and taking it away from the redundant repetition of putting the logic in every query, request, and lookup.
Any suggestions? I've looked into building my own custom data annotations but I've only managed to understand it as far as validation goes, not actually manipulating data.
here is one option: (creating readonly property which is to be passed to your controller/business layer)
class LoginViewModel {
public string Email { get; set; }
public string LowerCaseEmail
{ //This is a read only property.
get {
return Eamil.ToLower();
}
}
/// ... other view model properties
}
IMHO DataAnnotations can't and shouldn't change the data. This kind of logic should go either in custom model binder or in an action filter. Or, probably even better, in the data repository before you save the data to the datastore.
Also, you don't always have to have everything the right case, it can become a pain to ensure that, rather than that try to use overloads of string Compare, Equals function (or Linq functions) that take StringComparison or StringComparer and provide OrdinalIgnoreCase to it.

MVC: Am I doing it right?

Hey people. I don't know if I understood 100% the MVC concept.
I'm having troubles with the Model-View relation.
In order to present the data to the user, the View must have access to the data, right?
Is this access obtained by passing all the needed data to the view directly (and having the view hold the data within its class as an attribute), or just obtain the data "parsed" as strings, integers, etc... as it is needed (as the user navigates through the GUI) from the controller, by raising events? I feel like this is a little bit event overkill, since the data hasn't changed.
BTW, can you tell me what those arrows on the MVC diagram on Wikipedia do on a real example? Thanks.
A view is for presentation purposes only. The controller is in charge of fielding requests from the UI and invoking the necessary methods in the model, which then present their outputs to the views.
The arrows denote relationships between the classes. The dotted lines are relationships between classes and interfaces while the solid lines denote direct relationships, meaning that the classes likely hold instance variables of the classes they are related to.
The model is the central, authoritative repository of information. As an example, take a church's directory of its congregation.
There are controllers into that model that inform the model of data that should be changed. As an example, a congregation member informs the church office when they move or change phone numbers, and the directory is updated.
There are also views into that model that use the data, but cannot make changes to it. As an example, one church member can get information about another from the directory.
Note that in some cases views and controllers can be the same thing, or views for one model, controllers for another, etc., etc. For example a church member can be a view into other members' data, or change their own by interacting with the model.
The important thing to keep in mind is who owns the authoritative version of the data. The invariant that it is the model that has the most timely, accurate and authoritative data means you know exactly where to go to get the information you need.
There are two basic ways a model can communicate with the views: pushing and pulling. Pushing the data involves intelligence on the model side to know which views should be notified when a piece of information has been updated. Pulling the data involves intelligence on the view side to know how and when to look at the model for changes to the data it is most interested in.
To build on the previous answers, here is a super simple application showing the various usage of each of the areas in question. This app stores and displays cars which a Salesman has sold.
First we have our models:
public class Car
{
int Id { get; set; }
string make { get; set; }
string colour { get; set; }
}
public class Salesman
{
int Id { get; set; }
string name { get; set; }
IList<Sale> Sales { get; set; }
}
public class Sale
{
int Id { get; set; }
int CarId { get; set; }
int SalesmanId { get; set; }
decimal Amount { get; set; }
}
Now lets say we need to display a page which details all of the cars which a particular Salesman has sold. To do this we decide what data we will need on the page, e.g. Salesman name and a list of Car's which he has sold. We create a View Model of this data.
public class SalesViewModel
{
string SalesmanName { get; set; }
List<Car> CarsSold { get; set; }
}
Now we need to build (populate) this View model in our controller ready to be passed to our View.
public ActionResult SalesmanCarsSold(int salesmanId)
{
SalesViewModel salesVm = new SalesViewModel();
using (var dbCtx = new dbCtx())
{
salesVm.SalesmanName = dbCtx.GetSalesmanById(salesmanId).Name;
salesVm.CarsSold = dbCtx.GetCarsSoldBySalesmanId(salesmanId);
}
return View(salesVm);
}
Now all there is to do is just write this data out to our view, e.g.
#model MyProject.Web.Models.ViewModels.SalesViewModel
Salesman Name: #Model.SalesmanName
#foreach(var car in Model.CarsSold)
{
Car: #car.make
}
I believe I can add a little clarity. Basically you can use a Singleton pattern where only one instance of the model exists then you can use said Singleton within the View to bind things in your View to the model, that is you add listeners for changes to the model (in one sense or another) and the view updates itself whenever the model changes.
The model itself isn't affected directly by the view rather the view dispatches events or otherwise uses the controller to modify the model. This way you can have a common "shared" model a common controller which modifies said model and all sorts of views that display parts of said model in ways that make sense.
The views don't need to handle passing around data between one another in this way and the common functionality of modifying the model is contained in the controller. I had some trouble with these concepts when I first dove into them as well mostly because you never have 100% true separation of these parts, they are all related and will have a references to one another (via attached listeners at the least).
In Flex/AS3 my dev environment of choice this is very very easy to accomplish, you make on Model.as file that has a static variable called say modelLocator which is itself a new Model(), in the Model.as you define all your public variables, in Controller.as you have a handle on the model by creating a property (sure call it modelLocator here too) and within the controller's constructor you can instantiate the modelLocator like modelLocator=Model.modelLocator, do the same in your View then in the view you just update your view components when the model changes (in Flex you can use {} to bind values directly onto properties of your components, views pull from the model based on the post from #fbereto, good explanation btw).
From a high-level view, when you think about application architecture i.e. data layer, business logic layer and presentation layer, MVC should only be your presentation layer. I have often seen people make the mistake of thinking that in MVC, models represent their data layer, controllers represent the business logic layer and views represent the presentation layer.
You should always have a separate business logic layer (or services layer) which your MVC controllers access to carry out business logic, and also a separate data access layer (or repositories) which is only accessed by your services/business logic layer to retrieve data out of the database.
In your typical MVC application, you may have multiple view models representing the same data layer object (which typically represents a database table). For example, you may have 2 views for to represent information about a person; one is a summary view and the other is a details view. In your MVC application you will have 2 View Models i.e. PersonSummary and PersonDetail both of which are populated from the same Persons table in the data layer and are returned to your Controller Action when your controller calls methods (e.g. GetPersonSummary() and GetPersonDetails()) on the PersonService class (business logic layer).
Layering your applications in this way will make them far more maintainable and testable than treating your View Models as data models and writing all your business logic in the Controller actions.
This was my 2cents anyway! Hope it helps you understand MVC better...

When using Data Annotations with MVC, Pro and Cons of using an interface vs. a MetadataType

If you read this article on Validation with the Data Annotation Validators, it shows that you can use the MetadataType attribute to add validation attributes to properties on partial classes. You use this when working with ORMs like LINQ to SQL, Entity Framework, or Subsonic. Then you can use the "automagic" client and server side validation. It plays very nicely with MVC.
However, a colleague of mine used an interface to accomplish exactly the same result. it looks almost exactly the same, and functionally accomplishes the same thing. So instead of doing this:
[MetadataType(typeof(MovieMetaData))]
public partial class Movie
{
}
public class MovieMetaData
{
[Required]
public object Title { get; set; }
[Required]
[StringLength(5)]
public object Director { get; set; }
[DisplayName("Date Released")]
[Required]
public object DateReleased { get; set; }
}
He did this:
public partial class Movie :IMovie
{
}
public interface IMovie
{
[Required]
object Title { get; set; }
[Required]
[StringLength(5)]
object Director { get; set; }
[DisplayName("Date Released")]
[Required]
object DateReleased { get; set; }
}
So my question is, when does this difference actually matter?
My thoughts are that interfaces tend to be more "reusable", and that making one for just a single class doesn't make that much sense. You could also argue that you could design your classes and interfaces in a way that allows you to use interfaces on multiple objects, but I feel like that is trying to fit your models into something else, when they should really stand on their own. What do you think?
I like your interface approach as it allows you to define a contract for your model which you can use to adapt your ORM generated classes to. That would allow you to decouple your app from the ORM framework and get more use out of the MetadataType interface as it serves as data validation metadata as well as a contract for your model. You could also decorate your interface with serialization attributes for use in WCF gaining more use out of the interface. I followed a few early blogs that recommended creating a metadata class but again I think the interface solution is a nice idea.
If those two options are the two I am presented with, I would personally probably choose the interface way, simply because I think it looks cleaner. But this is entirely based on personal taste - I don't know enough about the inner workings of .NET to say for sure, but I don't know any case where the actual functionality of the two approaches would differ.
On the other hand, a much better approach would be to use Data Transfer Objects (DTO's) for sending data back and forth, and have the validation requirements on them. That is, instead of requiring that the Movie object meet all the validation requirements, you require that a MovieInput object meets all those requirements, and then create code to map a correct MovieInput into a Movie. (If you don't want to do that manually, you could use AutoMapper or some other utility).
The concept is basically to have something like a View Model object on the way in just as well as on the way out - I could just as well have let MovieInput be called MovieViewModel and use it for transferring of data both in and out of the server.
I see no functional difference between the two approaches. I'm not sure reusability is really important here, given that validation will most often be on "one-off" ViewModels that probably won't get much, if any, reuse.

Resources