I have to build an xml output that represents a data structured for a flex chart placed in the view.
I have several options:
have the controller create the xml (using data from the DB), and return it to a view that actually does nothing, since everything is ready.
have the view strongly typed to the data model from the DB, and render the xml declaratively in the view.
create an Html extension method that will contain the logic to create the xml and use it on the view.
in terms of separation of concern, what would be the best option?
in the future I don't expect many changes to the xml structure, maybe now and then.
I tend to select option 1 as it is more testable, and I feel more comfortable with the controller preparing the xml data.
I'd go for option number 1, as I feel it fits the MVC pattern the best. It's not the responsiblity of the View to create an XML file based on some data model. That's business logic and is therefor better off in the controller.
And equally important like you say, if you have your controller create the xml file you can create a unit test for it that asserts that the output xml is valid, contains all necessary nodes, etcetera.
Option 2 is the best. Your model has the data, your controller asks for it and offers it to the view. The view just has a tag to say where it goes. That to me is separation of concern.
Seeing Razzie's answer, I liked 1 as well, and I suppose that the model would have to provide some method for serializing some entity class (your chart results) into xml, in order for your strongly typed view to be able to make use of it.
Anyway I hope the answer helps, basically I don't think 3 is very good. :-)
I would say it depends on what you are more comfortable with as both options 1 and 2 are viable. People will say that option 1 is good as you can use an XmlWriter to make sure you've got valid xml to be returned and people will say option 2 is valid as mvc is all about having complete control on what is rendered in your view (which can be xml).
However, I would personally go with a variation on option 1 to keep the functionality independent of the controller and have it as a standalone utility method which takes in the data and outputs the xml. This will be easier to test but also be available to be called from other places in your code if this is needed in the future. In addition to this it also keeps the code in your controller cleaner.
And I agree with Mark I don't think option 3 is a good way to go.
That's just my thoughts, hope this helps :-)
Related
I'm using ViewModels in MVC. I'm find them incredibly klutzy and wonder if I'm doing something wrong. (Let's leave Automapper out of this for the sake of discussion.) I use viewmodels to send data to the client as well as receive form submissions. Some properties are sent to the browser for display only, others are sent & retrieved (eg. fields).
I typically have to implement the following to make a viewmodel work:
1) Create a view model class
2) Create a general function to initialize the view model & copy the properties from my entities & other sources
3) Write more code to write some values from the viewmodel back to the entities (or other destination) on submission
4) If there are server side validation errors, I need to write more code (particularly messy) to repopulate the read-only parts of the viewmodel (which were included in the submission), while taking care to not overwrite the user submitted data.
For a simple property (eg. "myViewModel.FirstName") this requires code to be written in no less than 4 places. That's not including the stuff in the Domain and Views. This pattern seems fragile to me - it's easy to break code eg. forget to implement a change in all locations. Definitely not DRY.
Am I missing the point or do all patterns using ViewModel have this kind of klutziness?
I'm not sure what you find klutzy? MVC is about separation of concerns. Keeping your business logic, data layer and GUI code separate. This in itself makes your code easier to manage, easier to test and far less confusing to debug.
And lets look at your four points.
Point 1. Firstly is creating a POCO for your view model really that much of an issue? I'd say not, since you can accomplish this in around 3 lines of code, given your example. And should your model need to change, would it not be more beneficial for it to be in its own view model class rather than in code directly in every action method in every controller where you may have used it?
Points 2 + 3. Here you speak about going from data layer to logic layer to view and back again. This is the whole point of MVC. Just because you have to possibly code three classes (model, service, repository) to handle this transaction does not make this cumbersome, it makes it clean. Just imagine if you dumped all this together on the controller action method. How would you handle re-use? How would you prevent repetition of code in other actions or controllers? Things would start to get very difficult.
Point 4. I don't really see this as a valid argument since you can just pass back the model submitted by the user without any need to update it or edit it. By using data annotations and ModelState for validation it is very simple to create a clean and testable unit of code. So I imagine that its not the fact your using a ViewModel but perhaps more to do with your implementation.
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.
This might be similar to ASP.NET MVC - Populate Commonly Used Dropdownlists.
I want to populate DropDownLists. Some of it is static data. Some of it comes from the Database. A couple of times I found myself forgetting to call the code that populates my lists and sets the ViewBag accordingly. It is almost worth adding a unit test for this. The only way I think that this suits a unit test is if you place it in model/service. Is there a best practice for this kind of thing?
I'd suggest that the data is contained within the model but is perhaps constructed by a html.helper method. this way, you keep the plumbing markup out of the view and leave the controller free to invoke the neccesary view and model.
You could also of course hand it off to a partialview with an <IList<SelectList>> model.
cats and their skin :)
If you follow the spirit of the pattern then the Model should supply the View with everything it needs to present to the user that's not static. If you have static dropdown lists then you could say that these could be constructed within the mark-up. If you are passing a SelectList to the View from your Action then I'd stick it in the Model to make things simpler and more coherent.
My rule of thumb is that the data must somehow be in the model, either as a ready to use SelectList or at worst in some container that can easily be turned into a SelectList using a LINQ-to-object call.
The bottom line is that the view should never contain any non trivial code.
EDIT (answer to your comment):
I try not to put too much code in models. Models are more like a simple bunch of data gathered by the controller and used by the view.
Regarding simple and/or common things such as the days of week, I believe an HTML helper is the most elegant solution. See WayneC's answer in this question.
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.
I'm an ASP.NET MVC newbie, but have used many Model-View-Controller frameworks previously.
I recently came across the convention of gathering up the pieces of data that your particular view needs (indeed, it's assigned to the ViewData) into a new class called (NameOfView)ViewModel.
Gathering up this data so that it's associated with the functions provided by the View/Controller interaction strikes me as a helper struct, or even closure mechanism (in the 'encapsulates a collection of variables' sense).
So why is it called 'ViewModel', given that it's neither a View or Model?
Does anyone else find the name confusing?
EDIT: What's wrong with just putting properties onto the View so that the Controller can populate them (as in other MVC frameworks)?
In my reading on this topic I've come across a variety of arguments as to why a developer would or would not want to use a ViewModel. Some even argue that a ViewModel should never expose anything more than strings. At this point I am not that extreme in my thinking. I will agree however, that it is not a good idea to expose Domain/Core Objects to the view. After some first hand experience it feels cleaner to remove this dependency.
While I don't agree with everything below Daniel Root makes a pretty good case for a ViewModel:
Most MVC examples show directly using
a model class, such as a LINQ-to-SQL
or Entity Framework class. The Visual
Studio wiring for MVC even steers you
into this concept with it's default
"Add View" code-generation, which lets
you quickly gen up views based on a
single model class. However, in
real-world-apps you often need more
than just a single table's data to
build out a page. Some examples get
around this by stuffing secondary data
into ViewData, but a better way to do
this is to create a "roll-up" class to
contain properties for everything
your view will need. This has the
added benefits of being more
strongly-typed, supporting
intellisense, being testable, and
defining exactly what a view needs.
Jeff Handley gives a nice description of the ViewModel pattern which he argues can be used in conjunction with MVC.
Edit
I've recently brought my thinking in line with Jimmy Bogard's regarding view models. After a fair amount of pain with each implementation I've tried having one view model per view creates a much cleaner development experience.
The model is a view-agnostic representation of the data. The view model is a view-specific representation of the data: it's the model as it might appear from a given viewpoint.
Consider a model that consists of raw data points; a histogram view might then have a view model consisting of a set of buckets and totals drawn from that data.
Logically, it's a subset or transformation of the model - it could be generated on-demand with a view-specific function and the model as its only input.
Regarding properties on the view vs. a property bag or custom object... I'm sure someone has strong feelings on this, but personally I don't see the big difference. You're producing a view-specific representation of the model and passing it somehow; the exact mechanism doesn't seem all that important.
Re: why can't the controller populate properties on the view?
Because the view doesn't exist at the time the controller action is executing. The idea behind returning an ActionResult from your action is that something later in the processing pipeline will evaluate the result and determine the best course of action (perhaps rendering a view, or maybe selecting a view to match the request (like special views made for mobile devices)).
I did a view posts on selecting the right kind of model object here: Putting the M in MVC Part I, Part II, Part III.
And yes, the term "ViewModel" term is en vogue right now, but it is in the spirit the original MVC adopters had in mind.
This isn't actually an answer but I highly recommend you watch the MVC2 Basics video by Scott Hanselman. It explains everything, and even though I have done ASP.NET MVC before it made a lot of things clear for me.
Its here: http://channel9.msdn.com/Blogs/matthijs/ASPNET-MVC-2-Basics-Introduction-by-Scott-Hanselman
It's called that because it's a "Model made for a View". I understand why the choice of term is a bit confusing.
It's a helpful approach if you don't want all your data passed to the view as a big hash array. It gives you a strongly-typed class dedicated to the UI, which pollutes neither the core Model or the View. It also allows you to encapsulate UI logic -- views should be kept dumb.