ASP.NET MVC 2 AJAX dilemma: Lose Models concept or create unmanageable JavaScript - asp.net-mvc

Ok, let's assume we are working with ASP.NET MVC 2 (latest and greatest preview) and we want to create AJAX user interface with jQuery. So what are our real options here?
Option 1 - Pass Json from the Controller to the view, and then the view submits Json back to the controller. This means (in the order given):
User opens some View (let's say - /Invoices/January) which has to visualize a list of data (e.g. <IEnumerable<X.Y.Z.Models.Invoice>>)
Controller retrieves the Model from the repository (assuming we are using repository pattern).
Controller creates a new instance of a class which we will serialize to Json. The reasaon we do this, is because the model may not be serializable (circular reference ftl)
Controller populates the soon-to-be-serialized class with data
Controller serializes the class to Json and passes it the view.
User does some change and submits the 'form'
The View submits back Json to the controller
The Controller now must 'manually' validate the input, because the Json passed does not bind to a Model
See, if our View is communicating to the controller via Json, we lose the Model validation, which IMHO is incredible disadvantage. In this case, forget about data annotations and stuff.
Option 2 - Ok, the alternative of the first approach is to pass the Models to the Views, which is the default behavior in the template when you start a new project.
We pass a strong typed model to the view
The view renders the appropriate html and javascript, sticking to the model property names. This is important!
The user submits the form. If we stick to the model names, when we .serialize() the form and submit it to the controller it will map to a model.
There is no Json mapping. The submitted form directly binds to a strongly typed model, hence, we can use the model validation. E.g. we keep the business logic where it should be.
Problem with this approach is, if we refactor some of the Models (change property names, types, etc), the javascript we wrote would become invalid. We will have to manually refactor the scripting and hope we don't miss something. There is no way you can test it either.
Ok, the question is - how to write an AJAX front end, which keeps the business logic validation in the model (e.g. controller passes and receives a Model type), but in the same time doesn't screw up the javascript and html when we refactor the model?

Stick with Option 2, but there are ways to test the code. You can use a web application testing tool like WatiN or Selenium to perform integration tests on your HTML pages. Also, FireUnit gives you the ability to unit test your JavaScript code (you'll need Firefox and Firebug in order to use it).
In the spirit of full disclosure, I haven't tried out MVC 2 yet. However, I've been using MVC 1 for some time now and have used these tools with some pretty good results.

Problem with this approach is, if we
refactor some of the Models (change
property names, types, etc), the
javascript we wrote would become
invalid.
I dont see how changing a property of the model changes javascript-code. Usually you hijack the submit event of a form and submit it via ajax. No properies envolved, a long as you take option 2.
Changing properties might break your MVC - application, but thats not specific to ajax.

Related

ASP.NET MVC List of Web Components in Model

I need to get dynamically a list of Web Controls from View to be used in the model(dropdownlists, inputs, checkboxes, ...). Is it possible? I generate the controls in Razor.
My application should store last values of all controls for each user into the database and use them as predefined values for the next call of the form.
Any advice would be appreciated.
I need to get dynamically a list of Web Controls from View to be used in the model
First of all, you're probably going to find MVC a lot easier to understand if you abandon terms like "web controls" and the like. Your view, which may not may not be utilizing helpers to do so, is simply building HTML. Nothing more.
But more to the point, what you're proposing is exactly the opposite of what MVC does. Your model should have no knowledge of the structure of the view. (inputs, selects, other form elements, etc.) The model contains the data and business logic necessary to render the view. The view then uses that data and logic to build its interface.
You can post the values from the resulting HTML form to a server-side action. Then from that action you can store those values in a database or do whatever you like with them. If the key/value pairs of those values can logically be structured into the form of a model then the action can accept that model as a parameter, if not then it can also just as easily accept parameters for each individual value. (Though if you find yourself using a lot of parameters it would be better to build a simple view model just to encapsulate them.)
The order of operations is something like:
A request is made to a controller action.
That controller action invokes logic on a model and provides that model to a view.
The view binds its UI elements to the model's data and renders the interface.
The user interacts with the interface and uses it to perform a request to another controller action.
That controller action receives the data from that request, performs server-side logic, etc.
and so on...

Creating a model for MVC

I'm building my first MVC project and I have a question about the model.
Each webpage can only contain 1 model, yet my page will require 2 models, one is the search option (the ability to narrow your search such as selecting price range, colour etc) as well as the data.
Is it really as simple as creating a new Model, similar to a ViewModel which in this case would only have 2 properties, a SearchModel and a ProductModel?
Yes, there are really two "models" which is sometimes confusing. There's the "View Model" and the "Domain Model." The view model is passed directly to and from the view. The domain model describes the real-life domain that you're dealing with and is what the database persists. Often, they are the same thing, such as if you're displaying information for a single real domain object (e.g., a car). If you have two domain models that go on one page, you should make a view model with both as properties.
If you are looking to have two models in a view then this question might provide useful information:
multiple-models-in-a-view
Edit:
A good example is the 'Manage' view in the default 'Account' controller of a fresh mvc app. It uses a partial view to handle the changing of a user's password. Whilst both views are using the same model type it shows how to implement a partial view. In this case both the main view and the partial are submitting to the same method on the controller, hence they need to use the same model (which is a parameter for the controller method). But if the partial were to invoke a different controller method then the submitted model could be different. Hope this makes sense :)

Returning ad-hoc view models from ASP.NET MVC2 Controllers

I'm porting an existing system to ASP.NET MVC2. In the current legacy app, the user can select from dozens of available fields to customize CRUD forms for different entities in the domain model, similar to the way ERP systems allow customization of core modules.
My question: I'm looking for a good pattern or example for this kind of behavior in ASP.NET MVC2. It seems to me it's rather like creating a ViewModel dynamically based upon user choices, or perhaps the right approach is data-driven view pages that aren't strongly-typed where I can reflect over the results client-side to determine field headings or something -- if that makes sense :). Or maybe I can drive AutoMapper or similar dynamically # runtime based on user choices?
The underlying domain model is EF4-based and I'm using a simple Repository pattern # present for the ViewModel.
TIA for any input! Michael
If I didn't find anything else that matched the needs and went on to do it custom, I would:
Use the ViewModel with all the fields / not just the ones the user picked.
Pass both the ViewModel and the view configuration to the view
Call some html helper that for each item in the configuration adds a field with the corresponding property in the model
The configuration could be passed as either part of a containing ViewModel or in a separate entry in ViewData
Depending on what you need, building/passing the view configuration could be put in an Action Filter. Alternatively the helper could pull it directly.
A different approach is if you need completely custom fields. I mean user defined fields. If that's the scenario, that's not typed at the controller level already, so I'd pass the list of fields/values to the view. The view can do a foreach on those adding the fields. Again that could be moved to a HtmlHelper.

How to update Model in MVC

I'm wondering how you keep a constant value of the Model in an ASP.NET MVC framework. Like when adding something to the Model through the view. You go back to an action in the controller but where do you keep the Model? Is it a private in the controller? or is it passed back and forth from the view to the controller because if it gets big then you are passing alot of data back and forth to add/delete a single item from the Model.
Also any small examples to show this?
Thanks
What are you referring to? Are you meaning a database table loaded up into an object such as Ruby on Rails's ORM -- typically the 'Model' is a series of interfaces or domain objects that load data into objects from the database .. or more simply just the database period.
Please be more specific. There are many MVC frameworks and many different kinds of 'Models'
I think you should check out a ASP.NET MVC tuturial like NerdDinner (from "Professional ASP.NET MVC 1.0"). Scott Guthrie has posted a html version of the tutorial on his site. It's a fairly simple site that they build in the tutorial, and is a great intro to ASP.NET MVC (in my opinion).
There are also some good tutorials on the ASP.NET site.
Hope these help you with .NET MVC, it's a great framework to use!
You can pass the model to the page and you can then use UpdateModel(model name) within your controller.
Each member in the model must be a property with a getter and a setter.
On the page you can hold the data in say a hidden field if you need to maintain the value outside of state.
If you have problems using UpdateModel then you can use the following in your controller;
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyAction(int? id, FormCollection collection)
{
string commentText = collection["myFieldName"];
}
This will normally get your values from the model.
Hope this is what you were asking.
Think of the model as a data transfer object. In a list, display only or edit page, you pull it out of a data layer as a single object or a list of objects. The controller passes it along to the view and it gets displayed.
In the case of an insert, a new data transfer object is instantiated upon post back and is updated with the posted values. Then sent back to the the data layer for persistence.
In the case of an edit, it comes from the data layer on the HTTP GET request and is used to pre-populate the HTML form. Then on post back, the data transfer object gets updated with the posted values and sent back to the the data layer for persistence.
Definitely checkout NerdDinner or Stephen Walther's samples.

Validating posted form data in the ASP.NET MVC framework

I've been playing around with the ASP.NET MVC Framework and the one thing that's really confusing me is how I'm meant to do server side validation of posted form data. I presume I don't post back to the same URL, but if I don't, how do I redisplay the form with the entered data and error messages? Also, where should the validation logic go? In the model or the controller? This seems to be one of the few areas where web forms are much stronger (I miss the validation controls).
Here's an overview of the flow in MVC:
/new - render your "New" view containing a form for the user to fill out
User fills out form and it is posted to /create
The post is routed to the Create action on your controller
In your action method, update the model with the data that was posted.
Your Model should validate itself.
Your Controller should read if the model is valid.
If the Model is valid, save it to your db. Redirect to /show to render the show View for your object.
If the Model is invalid, save the form values and error messages in the TempData, and redirect to the New action again. Fill your form fields with the data from TempData and show the error message(s).
The validation frameworks will help you along in this process. Also, I think the ASP.NET MVC team is planning a validation framework for the next preview.
You might want to take a look at ScottGu's latest post for ASP.Net prev 5. It walks through a validation sample that is very interesting:
http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx
As far as I can tell everyone is still trying to figure out the "standard" way of doing it. That said definitely check out Phil Haack and Scott Guthrie's latest posts on MVC and you'll find some interesting info on how they did. When I was just playing around with it for myself I created a ModelBinder for the LinqToSql data class that I had generated. You can check out this post to find out how to put together a basic ModelBinder:
ASP.Net MVC Model Binder
The in your action if you had created a "Product" ModelBinder you would just declare the action like so:
public ActionResult New(Product prod)
And the model binder will take care of assigning posted data to the objects properties as long as you've built it right anyway.
After that within your GetValue() method you can implement whatever validation you want, whether using exception's, regex's, or whatever you can make a call like:
(ModelStateDictionary_name).AddModelError("form_element_id", "entered_value", "error_message");
Then you can just throw a <%= Html.ValidationSummary() %> in your view to display all your errors.
For client-side validation I just used jQuery. After you get a basic sample set up though you can start doing some interesting things combining all that with Partial Views and Ajax calls.
Have you taken a look at this?
http://www.codeplex.com/MvcValidatorToolkit
Quoted from the page
The Validator Toolkit provides a set
of validators for the new ASP.NET MVC
framework to validate HTML forms on
the client and server-side using
validation sets.
I'm afraid that someone more MVC-savvy than me would have to speak to where in the architecture you should put things.
I'm just learning the MVC framework too so I'm not sure how off this is, but from what I understand you would have a form on a View such as Edit.aspx. This form would then post to the controller to another action method such as Update() passing in the contents of the form that you set in Edit.aspx as parameters.
Update(int id, string name, string foo)
You could do the validation within that method. If all is ok,
return View("Item", yourObject)
There is Castle.Components.Validator module in Castle project. It's very agile and powerfull. It generates validation rules based on model attributes (or any other source) and even able to generate JS validation using jQuery, Prototype Validation, fValidate and other.
Of course it's wise to abstract validator away behind IValidationEngine interface.

Resources