Page initialization patterns with ASP.NET MVC and MVVM like knockoutjs - asp.net-mvc

When creating an interactive form or other kind of web page, there are a couple of options with knockoutjs. One could create a strongly-typed view and pass a model to it from a controller. On the other hand, one could just as easily start with a plain old html document, and have it initialize itself by calling action methods (JsonResult or otherwise) after the initial load.
Also when starting out the page as an MVC view, you could use HtmlHelpers along with plain old html markup to initialize the view. Another option is to serialize the model state as json to a hidden field, and use that to initialize the view.
In my experience, during first load, there can be a delay when you let ko initialize the view. Whether you construct a viewmodel by passing json from a serialized hidden field, or rely on it to invoke various services to load the data, there is a moment before the page is "ready". These kinds of delays can be avoided by initializing the page with HtmlHelpers, etc, but such initialization could also incur additional costs (extra initialization logic in the controller, default content in the views, etc).
Which way of initializing a page is the most MVVM? Is it a bad idea to use HtmlHelpers in the views, or to use cshtml at all? If not, where do you draw the line between view and viewmodel?

"The most MVVM" is a hard question to answer, especially considering that we are already mixing patterns with MVC and Knockout.
I would think that letting Knockout do all the work of initilization would be "the most MVVM", but rigid adherance to a pattern when you are having issues is not a good idea. If KO setting values after the DOM is ready causes problems that you can fix by letting the HtmlHelpers initialize the page, then do what works. Since the HtmlHelpers will let you set the data-bind attributes at the same time, this feels like a good solution, and I have done this before with good results.
I would say that storing JSON in a hidden field is not a good idea though. You can directly encode your model into JSON by using this in your javascript:
var initialData = #Html.Raw(Json.Encode(Model));
This is a good solution since the page starts out with the data your controller sends it, without needing a second request.
You may have to think about what trade-offs you want to make. If you want purity and no code duplication, you might have to accept the issue of KO taking a little time to initialize the page. If you want a perfect User Experience, you may have to sacrifice a little purity.

Related

g:include vs g:render

I have a question about pros and cons of g:render and g:include.
In my application I have a piece of code that shows some information that have to be repeated in some gsp, what it show depends on a little bit of logic.
I have a doubt is it better use a g:include or a g:render???
So, is it better to execute the logic on a controller that pass a model to the page that use a layout included with the g:render, or is better to put a g:include to another action in another controller in the gsp that execute the logic of that piece?
I prefer the second choice, but how much it impact on the performance?
They are just used in different cases. You use <g:include .../> when you have a controller that is returning a piece of content that is easily embedded in multiple GSPs. This is also useful if you have a high volume of traffic where you are actually caching at the controller level since you can eliminate a lot of overhead.
<g:render.../> is useful when you need modularity within your page. Especially for AJAX calls where you may initially load one portion of the page then want to update it based on some AJAX event.
Both can be used to reuse content, and both are appropriate in the right context.
g:render is useful while you are working on partial templates and you have the model you need etc.
However, when you need additional (or extensive) progress to pass extra, more meaningful things to your view(template), it is better to use g:include.
By using g:include you will also have a nice controller and that means much more readable code using that controller.
And there would be no performance comparison between 'passing to a controller action and render a view with doing no additional operation' and 'render a view'.

How should we pass a data to a view in a big ASP.NET MVC web site

First of all, I have been a php programmer for a long time and I am a mvc programmer newly. I did a few minor web sites that each have one or two controller at most. But I've started a website that will be very major web site. There will be a lot of data to pass to views.
Now, normally I try to use model approach every time instead of ViewBag or ViewData approach. If the view demands more data, then I change the model class and then recompile the project. Especially, if the topic is an index page, the data to pass to the index's view changes every time. In a big web site, I'll use a lot of partial view that uses different models. So every time, I will have to change the index's model to support those partial views in the index view. if I add a new partial view into index view, I have to add the partial's model into the index's model.
I implement an IndexModel class for an index view every time when I start a website. Then I add properties to this model every time when I add a new partial view to the index.
Now is this a correct approach or should I use ViewBag or ViewData for partials' models. I think the real question is when we should use the model approach and when we shouldn't...
If you share your experiences, I would be grateful.
The MVC approach you should use always, especially for simple sites, it's save your time and make application more understandable.
If you write something larger than two pages, you need to use MVVM pattern (growth of MVC), in that case you will escape from using "partial models" with ViewModels.
Model must contain only busines logic.
Be better if you will always use ViewModel (not a Model) for returning data from a view and pass it to view, because it provides some safety.
For facilitate the procedure of copy data from Models to ViewModels use the things like AutoMaper and EmitMapper.
ViewBag and ViewData you should use only for additional data's like item colections for DropDown, or some view-text like page title.
One more advantage of MVVM pattern is better testability. If you write and support really hugh site you may write tests for some responsible parts of code.
For more details you can look at google - MVVM, ASP-MVC.
If i something not understad in you question or miss, write it in the comment ("add comment" ref).
I personally prefer to keep my sites consistant and always use Model + Viewmodel (no matter how big the site is) despite the extra work (which isn't much anyway).
It helps with maintainability. I know where and how everything is stored and coded into the site.

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.

MVC reusable propertygrid

In my web application framework (currently WebForms) I have a control that behaves like a classic propertygrid. It is initialized with an object ID (database key), then it reads metadata to determine the type of the object and the attributes of the object. It displays the attributes, string attributes as textboxes, bool attributes as checkboxes, enum attributes as dropdown lists. On page submit there is a method of the control ctrl.SaveData() that saved the changed attribute values back to the database.
The WebForm control tree and event model supports this approach quite nicely. Now I am asking myself if it is possible to achieve a similar solution for ASP.NET MVC. The main objective is to have a generic, reusable component that can be applied in a variety of situations with not much hassle. Additionally the solution must be flexible enough to put multiple instances of the component for multiple objects on a single page. Here the auto-generated WebForms HTML IDs also helped.
I am very curious about your ideas! Thanks a lot for answering!
You could achieve this effect using a custom ViewModel that contains enough metadata to identify the object being edited/saved. You would use this in conjunction with a partial view that renders the ViewModel. The main page would use the metadata in the ViewModel to either direct the post to a specific controller action to save that particular object or pass the metadata back to a common action (as hidden inputs, perhaps) in order that that action can choose the proper table in which to persist the data.
Personally, I would not take this approach. My feeling is that the more general you make a view/action, the more work it becomes to adapt it for different circumstances. I have done similar things for viewing sets of objects, but for a detail view or editing I like to work with more specific models and views.

Resources