Complex Model updating in form posting scenarios and MVC - asp.net-mvc

Many people have written about using Automapper to map domain objects (models) to view models, which I find very interesting and useful, but my question is about how to do the opposite. I understand the complexity of this process and why Automapper doesn't work in that scenario but I have to do that a lot with form posting, specially when updating.
I have a model, I map it to a view model and then I present a form to the user. Then, the form is posted and as models can be quite complex, I use custom ModelBinders to handle the response and building a new model, which won't be directly persisted. Instead, I load the original model from the DB and call a method to update it from the posted from without breaking anything. But this becomes repetitive and maybe there's a better approach.
Examples I've seen are very Model limited and naive, but in our application we may have now 50+ form posting scenarios like this one and growing.

If you want to go the other direction, first create the map to the other direction, Mapper.Map()
Next, you might want to create type converters (Mapper.CreateMap().ConvertUsing()), as sometimes forms can be more...string-y.
Then, you may need to ignore or use destination values. That can be configured with ForMember(entity => entity.Id, opt => opt.Ignore()) or ForMember(entity => entity.ChildCollection, opt => opt.UseDestinationValue()).
Finally, you'll want to use the overload that takes an existing destination object, Mapper.Map(dto, entity).

Related

Should sorting logic be placed in the model, the view, or the controller? [closed]

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I have a drop down list that displays values from a table to the end user. I would like to have these values be sorted alphabetically.
According to proper MVC design, at what layer should I place my sorting logic: the model, the view, or the controller?
EDIT: In response to LarsH's question, "Do you mean code that determines what sort order is desired? or code that performs the sort?", I was originally referring to the code that determines what sort order is desired.
Who controls the sort order?
(From Wikipedia)
1) Natural order within the data itself:
The order is part of the Model, so it should go there. A raw pull of "all data" would return the data in the sorted order, and there is no interface to choose the sort order.
2) The user should control how they see the data:
The View would provide an interface (such as ascending/descending arrows) that interact with the Controller, and the Model understands the data well enough to do the requested sort on the data. However, a raw pull of the data doesn't necessarily have to be sorted, unlike in (1).
In either case,
The View doesn't understand that there's a sort going on, other that the ability to show which sort direction has been chosen. Don't put the logic there.
Small caveat
The sorting functionality could go purely in the View, under one circumstance (that I can think of offhand; there may be more):
A "dumb" sort where all the data is already in the view and it doesn't have to use any domain knowledge to do the sort. Very simple string or number comparison, for example. This is not possible in, for example, search results on a webpage when results are likely to be split across multiple pages.
(Note: this quote and citation is taken from #dasblinkenlight's answer, but we disagree on our interpretation of it. read his post and make up your own mind).
According to MVC description,
A controller can send commands to its associated view to change the view's presentation of the model (for example, by scrolling through a document). It can send commands to the model to update the model's state (e.g. editing a document).
Sorting logic (e.g., the sorting comparator/sorting algorithm) belongs in the model since it contains business rules and state data. Since altering the way the model data is sorted falls squarely into the "change the view's presentation of the model" category, the controller is responsible for "doing the sorting" by calling the model.changeSortedState() method.
According to MVC description,
A controller can send commands to its associated view to change the view's presentation of the model (for example, by scrolling through a document). It can send commands to the model to update the model's state (e.g. editing a document).
According to this, sorting logic belongs in the controller, because altering the way the model data is sorted falls squarely into the "change the view's presentation of the model" category.
EDIT: To clarify multiple misunderstandings voiced in the comments, the "sorting logic" is not the code that performs the sort; it is the code that defines the sort. The sorting logic compares individual items to each other to establish an order (e.g through an instance of IComparator<T>) or contains logic that constructs an object to be used for ordering by an external system (e.g. through an instance of IOrderedQueryable<T>). This logic belongs in your controller, because it needs knowledge related to the "business" side of your application. It is entirely sufficient to perform the sort, but it is separate from the code that actually performs it. The code that sorts may be in your view, in your model, or even in the persistence layer that backs your model (e.g. your SQL database).
None of the above. Sorting is business logic, and business logic doesn't belong in any of the three. Not every piece of code in your application will be a model, view, or controller.
What I generally do in my MVC apps is I have a service layer that performs all the business logic. The methods in the service layer should have a clean, simple API with well named parameters. You can then invoke those methods from your controller to manipulate the data in the models.
In that sense, the sorting is "in the controller", but the code itself that does the sorting should not be implemented in the controller, only invoked from there.
Definetly not the controller: It sends messages to view and model but should do as little work as possible. If the user can change the sorting that request gets handled by the controller by informing the model or the view about it.
Maybe the View if it is a pure View thing. If the Application works just as well without sorting then the sorting is just part of the representation and should go in the view.
If the ordering is inherent part of the domain it should go in the model.
Views are the part of MVC which is supposed to contain presentation logic.
Model layer is where business logic is contained.
Controllers only change the state of both, based on user input.
So the choice is - do you think that this is part of the domain business logic or presentation logic.
If you were implementing a proper MVC Model2 or classical MVC pattern, then I would say that the ordering of data provided by the model layer should be triggered by the view's request to the model layer. View asks for ordered data, model layer provides it.
But, since you are using ASP.NET MVC's interpretation of MVC pattern, which is a bit different then your standard MVC - the ViewModel instance should request ordered information from the model layer (for some reason ASP.NET framework thinks that templates should be called "views" and views should be called "viewmodels" .. it's strange).
I would usually do it in the controller to remain in line with the pattern as per the other answers. See below for reasoning.
I've been mulling this over and reading the answers and related material and pragmatically speaking I would say it would depend on your application for instance:
Is it a medium/large application and/or has multiple UI's associated with it (i.e. a Windows App, Web interface and Phone interface).
In this case I would probably construct a service layer and put it in
the business object and then call the appropriate method from the
controller.
If its a well defined single UI website and you're using something like EF Code First and you do not have or have no intention of creating a service layer and plan on using a simple out of the box Extension method to acheive it:
In this case I'd probably put it in the controller as pragmatically
its the best fit with regard to time/budget.
If its the same as the above BUT cannot be implemented with an out of the box extension method.
I may well choose to pop it in the Model class (if its truely bespoke
to that single type) as it would be more appropriate here than in a
controller. If the sort could be applied to more than one class then
I'd implement it in an extension method and then call it in the
controller.
To sum up:
Dogmatic answer: Service Layer
Pragmatic answer: Usually the controller
I would suggest sorting data from a table-data that is small enough to be useful in a dropdown list-should come from the DB already sorted via the query. To me, that makes the model the place the sort is applied.
If you are determined to do the sort by hand, I think there are good arguments for using either the model or controller as your preferred spot for logic. The limitation would be your particular framework. I prefer to manage data solely in the model. I use the controller to marry data(model) and presentation(view) as I've been (self)taught.
Whilst I agree in principle with the idea that sorting is Business Logic because by breaking it down to it's origin you would end up with something like "The client would like the Product page to display with the images sorted by date" then it becomes clear that the sort order for data is typically not arbitrary - even if there is no sorting as that's still a business decision by omission (an empty list is still a list).
BUT... These answer don't seem to take into account the advances in ORM technology, I can only talk in relation to the Entity Framework (let's avoid an argument about whether this is true ORM, that's not the point) from Microsoft as that's what I use, but I'm sure other ORMs offer similar functionality.
If I create a Strongly Typed view for a Product class using MS MVC and the Entity Framework and there is a foreign key relationship between the Product and Image table (e.g. FK_Product_Image_ProductId) then I would out-of-the-box be able to quickly sort the images during their display using something like this in the view:
#foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder)){ //etc etc... }
There was mention of a specific Business Logic layer, which I also use to perform 80% of my business logic, but I'm not going to write sort functionality into my Business Logic layer that mimics something that comes out-of-the-box from the Entity Framework.
I don't think there's a correct answer to this question, other than to say that; you should abstract complex business logic where possible but not at the cost of reinventing the wheel.
Assume that you have MVC website, WebForms website and a mobile application.
If you want sorting to be consistent between these presentation layers, then I'd say sort outside of the presentation layer. Service would be a good candidate.
Otherwise, I would store that logic in a view model. Why? Because it'll be reusable and easily testable.
Out of the three you have listed, I would say that it belongs in the controller. I don't really like placing this sort of logic in the controller, though. I usually create a service layer that the controller communicates with that will be responsible for communicating with the data store and handling sorting logic. For small applications it is fine sitting in the controller, though.
This is a question asked with the asp.net in mind, but since somebody did mention Rails, I thought it would be interesting to consider the problem in that context. In Rails, it is natural and pretty common to perform the sorting along with the retrieval as a controller action, since the framework and ActiveRecord/ActiveQuery api provisions for it. On the other hand, it is possible to define some sort of custom sort order for static items and put that in the model to be used by the controller, so the model can play a part in the sorting logic even though it does not carry out the operation directly. Whatever it is, it can be safe to say that putting the sort logic in the view is generally frown upon.
I'm slightly amused that some answers are absolutely against putting the sort in either the controller or the model, and I find them too pedantic for my taste, but I suppose it depends on the nature of the framework used and the usual conventions associated with it. I also agree with Bill K's comment that having the separation in the first place is more important.

Scope of viewmodels in asp.net MVC 3

I have read online that it is bad practice to use a "kitchen sink" model:
Rule #3 – The View dictates the design of the ViewModel. Only what is
required to render a View is passed in with the ViewModel.
If a Customer object has fifty properties, but one component only
shows their name, then we create a custom ViewModel type with only
those two properties.
Jimmy Bogard's subsequent explanation of how this is good, however, left me a little questioning. It'd be so easy to have my Model just contain a list of Customers, I could even use my POCO's.
So now I get to create custom little view model fragments for every page on the site? Every page that uses a Customer property would get one, but of course could not be shared since some of the information is extraneous, if one page used Age but not Name, for example. Two new mini view model classes right?
This is very time consuming, and seems like it'll lead to a million little custom view models - can someone elaborate as to the utility of this approach and why the easier approach is bad?
View model class can be used not only to transfer values, but it also defines data types (data annotations), validation rules and relations different then ones used in model. Some advantages that come to my mind right now:
There are different validation rules when you change user's password,
change his basic data or his subscription setting. It can be
complicated to define all these rules in one model class. It looks
much better and cleaner when different view models are used.
Using view model can also give you performance advantages. If you
want to display user list, you can define view model with id and name
only and use index to retrieve it from database. If you retrieved
whole objects and pass it to view, you transfer more data from
database than you need to.
You can define display, and editor templates for view models and reuse them on different pages using html helpers. It looks much worse, when you define templates for model POCOs.
If you would use your POCO objects as view models, you would essentially be showing your private objects and break the encapsulation. This in turn would make your model hard to change without altering the corresponding views.
Your data objects may contain details that are appropriate only to the data access layer. If you expose those things to the view, someone might alter those values that you did not expect to be altered and cause bugs.
Many of the same reasons as for having private members in OO languages apply to this reasoning. That being said, it's still very often broken because it's a lot of extra work to create all these "throw-away" models that only gets used once. There exists frameworks for creating these sorts of models, though the name eludes me, that can tie objects together and pick out the interesting properties only which takes away some of the drudgery from creating specific view models.
Your View Model tells the View how data should be shown. It expresses the model. I don't think its necessary to have two view models unless you have two ways to express your model. Just because you have two pages, doesn't mean you will be showing the data any different way, so I wouldn't waste time making two mini View Models when it can be in one reusable view model, Imagine if later you have a page that needs Name and Age, you would create another view model? It's absolutely silly. However, if you had two pages both showing 'Age' and it needed to be shown in a different way, then I would create another one.

In MVC3, should I have separate "edit" models vs. "display" models?

With MVC3, should I design my view models such that there is one that is bound to the view (DisplayModel), and one that is posted back to the controller (EditModel)?
To clarify, I am not asking about data models vs. view models -- I know it's not good to bind my views/controllers to data/domain models.
Nor am I asking about sharing one model across two separate views, one view that is used for displaying the data, and another view that is used for editing the data.
Rather, I am asking about one view that is used for editing data, and the model that is bound to the view vs. the model that is bound to the controller action.
In other words, if this is my view:
#model MyApp.Models.CustomerModel
Should my controller action look like:
public ActionResult Index(CustomerModel model)
Or:
public ActionResult Index(CustomerEditModel model)
At one point, we were doing the latter (separate). But lately, we've started doing the former (shared).
The reason for this change was because:
With MVC3 unobtrusive validation, if I'm using DataAnnotations on my model for validation, this is needed in both models if they are separated (on the display model to map client-side validation, and on the edit model for server-side validation).
As our application matured, we realized that our display and edit models were 95% identical, with the exception of the select lists that were in our view models. We've now moved these to a shared class and are passing these in via the view now.
But I've seen some other discussions that point to having shared models for view/controller to be a bad idea, and that it violates separation of concerns.
Can someone help me understand the tradeoffs for these two approaches?
I've seen perfectly good arguments for and against, it just depends what works best for your application. There's no one size fits all approach that can be applied!
If you haven't read it Jimmy Bogard has written a very good post about how his team does MVC here, which covers this topic.
I agree with rich.okelly's answer that there's no right approach.
There are a couple of concerns I have with using one model, though.
It's going to be very to always use one model without having unneeded properties when the view needs to display a selectable list of objects. The model will need to have the list of objects as well as a property to accept the POSTed value the user chooses. These unneeded properties add a small amount of code clutter and overhead.
(One way around this is to have the model contain only selected ID and have HTML helpers to build the lists.)
Another concern is more related to security.
A common scenario is displaying information in a form that should be considered read-only.
In the case of a ViewModel and an EditModel, the EditModel will only contain properties that are expected to be POSTed, whereas the ViewModel will contain all of the properties.
For example, if a form displays a user's salary, a user will be able to POST a 'salary' and have it bound to the ViewModel's Salary property automatically by MVC.
At this point, something has to be done to ensure it doesn't end up in the database. It could be if/else logic, a Bind attribute, Automapper logic or something else, but the point is that it's a step that could be overlooked.
When considering the lifespan of an application, I like the explicitness of the EditModel over time.
These concerns don't mean that two models are good and one model is bad, but they should be considered when choosing a design.
If the properties are the same for display and edit view models I see no reason to have separate classes.
I think you'll find that it's hit or miss no matter what way you go but if you can take the path of easiest maintainability then you should do that. In my experience, having a single model is much easier to maintain, obviously, but it seems that there is always some business decision that is made that forces me to split the models. If you're in that 95% then I think you are in really good shape. Your application, from a maintainability perspective related to your models, will be easy to maintain. When a change comes along, you have one place to make that change, for the most part. The issue I always seem to run into is scaling business changes across multiple models. Copy/paste issues, or simply forgetting about some property somewhere, always seems to hurt me because of the multi-model issue.
we realized that our display and edit models were 95% identical, with the
exception of the select lists that were in our view models. We've now
moved these to a shared class and are passing these in via the view now.
Are they 95% identical in data and operations or only in data? Remember that classes encapsulate data and behavior.
If they are 95% similar in properties but have totally different operations you might benefit from splitting them in two classes. Or you might not :)
As others pointed out there is no one-size-fit-all answer and in your case it seems that one class is OK...but if you start noticing that the behavior on each of them is unrelated don't be afraid to rethink you approach.
No - one view model for both directions. Mixing it up is not only harder to follow, but one could easily inject invalid values into the page that then get automatically bound. I could overwrite your customerid (or create one) for example.
Inherit from a base view model if you must or don't rely on data annotations at all and use the fluent api on your model save.
A great link (somewhat unrelated but the auto map is nice)
edit
(sorry someone else previously posted this below I just realized)
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
Also
ASP.net MVC - One ViewModel per View or per Action?
You (IMHO) should be generally binding to your method specific VieWModel rather than a shared view model. You could get caught in a trap of missing properties, etc. but it may also work just fine for you.
Use auto mapper to go between both. Jimmy also has a nice AutoMap attribute when returning to the View. Going back the other way I would not use a CustomerModel in general as there may be fields required in there that are not coming from my say, create view. For example a customer id may be a required field and for a "create" action it won't be present. But - if you find in the most of your cases this to actually work for you, then there is no reason at all not to use it.

best practice for what is in a ViewModel

I am wondering if it is a good idea or bad, placing things like a List of countries in ViewModel, for binding to a drop down list? For example on a site's Registration page.
I was under the impression that a ViewModel is supposed to represent an instance of the filled out form, but I think I may be wrong as I have seen other people put things like lists in their ViewModel.
Would it not be better to put it in a static class somewhere and called directly from the View?
Like CommonData.ListCountries(); and then using Lambda to convert to SelectList item list in the view Directly?
As you've realized there are a variety of ways to accomplish your goal. While the MVC design pattern encourages certain application organizations how you organize your models, views and controllers is ultimately a matter of preference.
Scott Allen discusses his preference for dealing with ASP.NET MVC drop down lists in a blog post. Scott uses an extension method to convert an enumerable of a complex type into an IEnumerable<SelectListItem> on his model. He then describes that upon post back ASP.NET MVC will not be returning the IEnumerable<SelectListItem> he sent to the view, but only the value the user selected. He then suggests that utilizing two models can simplify things.
This is a reasonable description of what I refer to as ViewModels and FormModels. A ViewModel carries the display data to the view and a FormModel is used for carrying collected data back to a controller action. To explain further:
ViewModels contain data that help render views. By organizing my ViewModels this way I can place all necessary information to render a particular view into an associated model. This prevents me from having to use ViewData for anything that's not truly temporary.
FormModels are used to gather user input. FormModels (almost) never contain references to other complex types and are made up of primitives, DateTimes, and strings.
In either case I have a hard rule to never reuse a model for a different view. Having your models closely aligned with the views used to render them makes your views easier to write. You don't have to worry about things like static methods because your models should be carrying data to their associated views in a form that is easy for them to render. Tools like AutoMapper can help "flatten" domain objects into models for display purposes.
For additional reading checkout: ASP.NET MVC terminology is tripping me up - why 'ViewModel'?
Whatever data your View needs, put it in the ViewModel.
The way i see it, once your view is going through the rendering process, it should have all the info it needs from the Model it is bound to.
If you start to use helper methods, then the View is "going back to the controller" in a sense. Extension/helper methods are fine for formatting, etc, but they should not call through the model.
Don't forget, you also have ViewData (basically HttpContext.Current.Items, lives for single request), which is a lightweight storage mechanism that can be used to share data across partial views (for example).

When is it right to use ViewData instead of ViewModels?

Assuming you wanted to develop your Controllers so that you use a ViewModel to contain data for the Views you render, should all data be contained within the ViewModel? What conditions would it be ok to bypass the ViewModel?
The reason I ask is I'm in a position where some of the code is using ViewData and some is using the ViewModel. I want to distribute a set of guidelines in the team on when it's right to use the ViewData, and when it's just taking shortcuts. I would like opinions from other developers who have dealt with this so that I know my guidelines aren't just me being biased.
Just to further Fabian's comment; you can explicitly ensure viewdata is never used by following the steps outlined in this article. There's really no excuse not to use models for everything.
If you have no choice but to use ViewData (say on an existing project); at the very least use string constants to resolve the names to avoid using 'magic strings'. Something along the lines of: ViewData[ViewDataKeys.MyKey] = myvalue; Infact, I use this for just about anything that needs to be "string-based" (Session Keys, Cache Keys, VaryByCustom output cache keys, etc).
One approach you may wish to consider as your views become more complex, is to reserve the use of Models for input fields, and use ViewData to support anything else the View needs to render.
There are at least a couple of arguments to support this:
You have a master-page that requires some data to be present (e.g. something like the StackOverflow user information in the header). Applying a site-wide ActionFilter makes it easy to populate this information in ViewData after every action. To put it in model would require that every other Model in the site then inherit from a base Model (this may not seem bad initially, but it can become complicated quickly).
When you are validating a posted form, if there are validation errors you are probably going to want to rebind the model (with the invalid fields) back to the view and display validation messages. This is fine, as data in input fields is posted back and will be bound to the model, but what about any other data your view requires to be re-populated? (e.g. drop-down list values, information messages, etc) These will not be posted back, and it can become messy re-populating these onto the model "around" the posted-back input values. It is often simpler to have a method which populates the ViewData with the..view data.
In my experience I have found this approach works well.
And, in MVC3, the dynamic ViewModels means no more string-indexing!
I personally never use ViewData, everything goes through the Model, except when im testing something and i quickly need to be able to see the value on the view. Strongtyping!
In terms of ASP.NET MVC 2, ViewModel pattern is the preferred approach. The approach takes full advantage of compile time static type checking. This in combination with compiling mvc views will make your development work-flow much faster and more productive since errors are detected during build/compile time as opposed to run time.

Resources