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.
Related
I was wondering, should the entities have the capability to save changes to the context? Or have business logic that relates to that particular entity? For example:
ActionResult ResetPassword(UserViewModel viewModel)
{
var user = userCollection.GetUser(viewModel.Username);
user.ResetPassword();
}
where:
class User : Entity
{
public string Password{ get; set; }
public ResetPassword()
{
Password = ""
context.SaveChanges();
}
}
I find this a bit weird since the entity would have a reference to the context. I am not sure whether this would work either - or whether this is recommended. But I want to work on a domain where I do not have to worry about saving changes, at a higher level etc. How can I accomplish this?
Thanks!
Update
I have updated my example - hope its a bit clearer now :)
According to Domain-Driven Design domain objects should have behavior.
You should definately read this book:
I would keep my Entities as POCO's(Plain Old Class Objects, classes with only properties) and have a Repositary do methods like Insert / Update.
I can keep my Entities in a separate class library and use it in different places ( even in a different project), with a different Repository implementation.
In this Tutorial It is nicely explained, how to do a Repositary & Unit Of Work Patterns on an MVC project which uses Entity Framework
You may want to consider the UnitOfWork pattern between your controller and your entities.
http://martinfowler.com/eaaCatalog/unitOfWork.html
I'm very new to RavenDB and MVC3, in particular the usage (not concept) of IoC. So just to warn you that this will sound like a very beginner question.
In summary:
I have a domain model, let's say it's
public class Goose
Within this class I might have a more complex object as a property
public Beak beak { get; set; }
In RavenDB we are rightly encouraged to [JsonIgnore] this property or not have it at all and instead have a reference identifier, like
public String beakId { get; set; }
Somwhere along the way in my MVC3 application I will want to view the Goose and I might want to display to the user, something about the Goose and it's Beak (should that be Bill?). So yeah I need a view model right?
public class GooseModel
{
public String BeakColour { get; set; }
public String BeakLength { get; set; }
...etc
}
Right, so assuming I have some GooseRepository and some BeakRepository here's the simple question....
I'm in the GooseController class and I'm loading a Goose to view. At what point do I use the BeakRepository and who should know about it? The GooseController knows about the GooseRepository and is loading the Goose by id. At this point we could have some property inside the Goose class which represents the whole Beak, but I don't really want to inject the BeakRepository into the GooseRepository do I? Ok, so perhaps when I create the GooseModel from the Goose I've found I could get the GooseModel properties for the BeakColour and BeakLength, how? Well I like AutoMapper, so perhapds my Map For the GooseModel from Goose is using the BeakRepository to find the Beak and then extract the two Beak properties to populate the GooseModel fields.. this too seems wrong... so what's left? The GooseController.. should the Goose controller know about the BeakRespository and then find and set the BeakColour and BeakLength!? that certainly seems completely wrong too..
So where does it get done? the Controller, the domain object, the mapper or somewhere else? Perhaps I should have a partial view of Type Beak which is used within the Goose view?..
I tend to consolidate this kind of logic into a service/business layer (GooseService) that i then inject into the controller. your service layer might take a GooseRepository and a BeakRepository, and return a resolved object that has mapped the GooseViewModel together.
Uhm,... reading your question I strongly suggest you forget about the Service-Layer and the Repository-Layer. If you don't have really good reasons to keep them (testing is not one of them since RavenDB has an EmbeddableDocumentStore, which is fast and easy) pull them in order to take advantage of some very nice features of RavenDB.
I've actually written a post about why I think you should generally avoid these layers:
http://daniellang.net/keep-your-code-simple/ It is about NHibernate, but concepts apply here as well.
Whether you should denormalize the BeakColor and BeakLength property into your Goose-document depends on your applications need. If you feel comfortable with the term "aggregate root", then the rule of thumb is that these generally are your documents. If you're not sure whether denormalization should be applied, avoid it, and use .Include(goose => goose.Beak) instead when loading your Goose.
Please let me know if that makes sense to you.
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;
}
}
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...
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.