Is using jquery to call a WCF Data Service from the UI violating the MVC pattern - asp.net

I'm fairly new to ASP.Net MVC 2 and understand the MVC pattern in itself. But my question is what's the best way to populate dropdownlists in the UI sticking to the MVC pattern. Should I be going through the controller?
Every article I've seen to do this shows how to do it using javascript and jquery. I have a test application that I'm re-writing in MVC2 I have my dropdowns working with jquery basically calling a WCF Data Service that returns JSON which populates the dropdowns. Seems to me though that this is bypassing the controller and going straight to the model therefore strictly violating the MVC pattern.
Or am I missing something obvious here. You thoughts or best practices would be greatly welcome here.
Thanks

One of the great things about MVC is that the controllers can couple as 'web services' or sort. Meaning, you can easily specify a return type of 'JsonResult' for example (instead of a view - ActionResult).
The MVC framework will handle all the serialization for you.
You can easily call the controller action method from jQuery and populate the dropdown.
In your example, i would create a Json controller method, decorate it with some custom action filters (check http headers that its a json http get request, etc), call it from jQuery and bind to your dropdown.

If your drop-down list is static (i.e. not a cascading drop-down list) then you can add an AvailableItems property to your model, set its value in your controller, and populate the list from that. If your list needs to be updated based on other user selections then you need to call back to an AJAX service of some type.
In general, if your application has script code that runs on the client, that code is going to be in your views. I personally don't see that as a violation of MVC.

I think your best bet is to give View Models a try.
You can build fill out data for special UI oriented models in the controller and pass that to the view. For drop downs, is there a reason you're loading through ajax? In most cases I've found you can just build a normal select list and sprinkle with javascript for dynamical functionality.
Your view model could have a IEnumerable<String> CityNames property that you then load into a dropdown in the view.

Related

Returning custom data along with actionresult from an action method

I am sure many people have had this question but I failed to get any results after searching the web and SO or the search keywords were different.
I am working on a new asp.net mvc web app where I get a plain template returned by the index action method on the controller. Later in the document.ready event handler I build the ui dynamically and append the dom elements to the blank template and this just works fine. My issue is I need 2 server calls here,
1) to get the view from the index action method
2) an ajax call inside the document.ready{} to get the data using which I build the ui.
I was wondering if there is any method using which I could pass back the data from the index action method along with the blank template view and use this data to create the ui inside the document.ready event handler. This will save that one additional hit to the server.
The reason for not using partial views is
1) we have some functionality already developed in jquery and
2) in my org people think making the functionality using razor and partial view will not be as flexible, for example building and raising customevent in js is a great feature that helps to keep the functionality loosely coupled from other features. (please correct if we are wrong)
Edit: I thought an example will explain this better,
Say I need to create a list of users, but the entire list and its functionality like checkboxes selection etc are built by a js module. So along with the blank view i want to pass the "users" object which is a class in my models currently.
Kindly suggest.
You have a couple of options:
1) Server-side rendering:
Putting the necessary data into the model would seem to be the obvious thing to do...that's what MVC models are for.
During the building of the HTML your View code runs - so you can access the model values in Razor code, which you can use to build your view and influence the final HTML. So in this scenario you build your view using Razor, rather than constructing it using JS code. You can of course still use JS to change it after the page has loaded, but it would be downloaded into the browser with the HTML already in the desired starting state.
2) Client-side rendering, but with necessary data pre-populated:
If you'd rather stick with your existing client-side rendering code, you could use Razor to inject some ready-made JSON into the JavaScript, so it's effectively hard-coded into the page when it first runs, rather than having to fetch it from the server separately via AJAX.
For example, if you have some object in C# which holds the data, you can serialise it to a JSON string and then use Razor to write that string into your JS in the correct place.

Which ASP.NET Page event is the best place for this type of code?

I have a relatively simple page that will do most of its operations on the client side using Javascript or JQuery. However, initially I do need to retrieve some data from the DB server based on QueryString parameters.
I plan on passing this data in the form of a JSON string to the script by an old-fashioned ASP manner ( var severData = <%=MyPublicData %>) block where MyPublicData is defined in CodeBehind as:
Public string MyPublicData;
The question is, which event in the ASP.NET page lifecycle is the best for this? Page_Init ? Page_Load? Also, is it worth the effort to do this in ASP.NET MVC. I did look at this possiblity but it seemed a little too much for a simple page like this where I do more 90% of the work on the client. Any thoughts on this?
Page_Load is more appropriate, but either will work.
It's very difficult to say if MVC is more appropriate for you application than webforms without knowing more about the application. However, if you don't want to abstract away the traditional web model then I'd go with MVC.
This kind of simple property or field assignment can go anywhere in the lifecycle. For lack of any other reason, you might as well stick it in Page_Load, since that method is usually waiting for you in the code-behind anyway.
well, on the contrary, if it uses mostly javascript with jQuery, I would recommend you to use MVC. you will not have any problem with the ids for instance.
There are workaround to use jQuery with webforms, but it is never perfectly clean regarding selecting the DOM.
MVC : a single action method where you will retrieve your data (preferably from a small repository) and 1 view where you display your data with total control over your html elements.
and jQuery will just fit perfectly for your clientside work.
You can get either to work; you can write public variables/fields to the client in ASP.NET web forms, although MVC has an edge due to the way it renders the UI.
So for MyPublicData, you could assign it a value at any part of the lifecycle; you can assign it in code-behind to a label or something like that, or if it's JS markup you can write it out using Page.ClientScript.RegisterStartupScript or RegisterClientScriptBlock... so you have multiple options.
In MVC, you would assign the value in the controller and render it in the UI, or with JQuery you can do controller requests real easy with $.ajax.

ASP.NET MVC - How to achieve reusable user controls and maintain DRY?

First post so please be gentle :)
When creating user controls in ASP.NET MVC, what is the best way to structure the code so that the controllers that invoke views that use the user controls do not all have to know so much about the controls? I would like to know a good way to maintain DRY while using user controls in ASP.NET MVC.
Please note, this question only pertain to user controls that require special handling and logic on a postback. I have no problem creating nice DRY code for user controls that are either view only (using RenderPartial) or that require some pre-processing to create the appropriate ViewModel (using RenderAction).
Also, this question pertains only to achieving reusable controls within an application. I am not worried about reusability between applications at this point.
To give a specific example, let's say I would like to create a 'Quick Add' user control which contains three entry fields, First Name, Last Name and Company Name and a submit button. When the QuickAdd functionality is used, the following steps should be performed independent of what page the control is on:
Validate that the fields were not empty, if they are, show an indicator.
Perform a lookup to a repository to see if the Company already exists, if not; create it.
Create a new contact associated to either the existing company or the newly created company
Re-render the existing page. If no validation errors, the user would see the exact same page again, otherwise the same page with validation errors.
My main problem with achieving DRY has to do with all the controllers that invoke views that contain the partial view end up having to have an Action Method to process the form submission from the Quick Add. Even if I break out the logic for processing the information into a separate controller and invoke that method from each of the other controllers it seems like a burden that each and every controller that invoke views that have reusable controls have to have that knowledge.
The other option I looked at was to have the reusable control always submit to a specific action method / controller but then there is no way for that controller to know how to re-populate the model appropriately for the specific controller that invoked the view that contained the reusable control (in step 4).
I am aware that there is talk of subcontrollers in MVC 2 (from this question ASP.NET MVC - Contained User Controls) but since it is not there yet, what is the best way to structure the code to achieve maximum reusability while maintaining DRY?
Is there an alternative to having to have all the controllers that invoke views that use a reusable control (with the characteristics of the one described above), having to have an Action Method to process the information from the control?
At the end of your post, you ask "Is there an alternative to having to have all the controllers... having to have an Action Method to process the information from the control"
The answer for that question is to write a custom model binder. Your custom model binder can be responsible for the populating the values from the incoming form control(s) into model or properties used by all of the controllers. Normally, you want to separate the validation from the model binding, but there is no reason that you couldn't combine them as well.
I highly recommend 6 Tips for ASP.NET MVC Model Binding for a deeper discussion of the topic along with some good references.
I'm not sure why you say the Quick Add form has to have an action method in each controller that uses it; if you wrap the Quick add functionality in a Html.BeginForm(); Html.EndForm() combo, you can have the beginform method specify the name of the action and controller, so you only need one controller.
I understand where you are coming from; it's something I have been thinking about to. While I don't know all the answers, I have some ideas for you to consider. Every controller action method is invoked via a ControllerActionInvoker class, which you can customize. This class handles invoking all of the action methods, so here you could embed certain aspects of reusable code across all or certain action methods.
Look into filters too, as there are a variety of filters that you can use or customize that fire for action methods that implement it. This way, code can run before and after the action method execution and result execution.
For validation, there is already validation components built in that will prevent page submission... you could also consider XVAL which has some other nice features. The Unity framework is an IOC container framework, which dynamic injection keeps things loosely coupled and DRY, as you can inject all kinds of references.
Also, you mentioned subcontrollers; the MVC preview has additional features you may be interested in... for instance, it has a RenderAction method that can render an action method within another action's view.
Hopefully that helps... so what am I missing?
Have a look at RenderAction and RenderPartial. Those are the canonical ways to arbitrarily inject a common control into a view.
Use RenderPartial when you want to include the data as part of your ViewData infrastructure.
Use RenderAction when you want the data to be separate from the ViewData infrastructure. The data will come from the controller method you specify in RenderAction.
Check out the NerdDinner tutorials, if you haven't done so already.

What is the unit of reusability in .NET MVC apps?

In traditional ASP.NET Web Form applications, UserControls are a great way to encapsulate functionality so that it can be reused. However, UserControls don't fit well into the MVC model. They often make heavy use of ViewState and they blur the seperation of concerns that MVC promotes.
My question is, how do you best bundle a piece of functionality so it can be shared across MVC applications?
As an example, consider a from/to date-selector UserControl that:
allows a user to select two dates, either using a javascript overlay or by typing in day, month and year into seperate fields
can be configured to default to either today and tomorrow's dates or to dates of the developer's choosing
validates the dates that comes back from the user to ensure the from date is before the to date
exposes From and To properties that can be accessed by code-behind
How would I best build something like this in .NET MVC so that I can easily reuse it?
Note that to fully emulate User Control's functionality the MVC component would have to manage the submitted form data and validation - not just the presentation.
In general I would agree that user controls are nice in terms of encapsulating UI stuff, but I don't think too much has really changed in MVC. If I remember right re-using user controls across classic Asp.net projects was a pain and was never really the best way to truly create reusable components. Most UI toolkits that you bought for classic ASP.net didn't give you user controls, they gave you essentially server controls and javascript controls.
In your example, I would probably create or find a jquery (or ur framework of choice) plugin that did what you wanted on the client side. You could also build a C# wrapper around it similar to what Telerik did with some of the jquery UI controls. I do think that the word code-behind and even viewstate will disappear from your vocabulary the more you get into MVC.
If you look at what open source projects are out there for MVC you will get your answer in terms of what you should be doing.
The MVC Contrib app adds a lot of features by creating extension methods and helpers. Their grid control is a typical way to create a reusable component that you could use across projects
Telerik, created some extensions that wrap jquery controls and do asset management.
Finally I think if you look to the future, MVC has areas, which if I interpret it right will give you the ability to break your project apart into multiple smaller projects.
Besides what is already suggested, ASP.NET MVC v2 will have generic templated input controls, see here. You can read how other people do similar techniques, for example, here:
We have
exactly 1 method call for generating a
form element, “Html.InputFor”. As
part of that “InputFor”, it examines
an input specification, that collects
the PropertyInfo, any attributes, the
type, any modifiers called, and
selects an appropriate InputBuilder.
Call InputFor(p => p.Id) and Id is a
GUID? That creates a hidden input
element. Call InputFor(p =>
p.Customer.Address) and Address is a
complex type? That looks for a
partial with the same name of the type
Having considered the helpful answers from others, I will have a go at answering my own question.
It seems to me that the key difficulty with emulating UserControls in MVC is that they crosscut the concerns that MVC aims to seperate. The from/to date selector UserControl in my example incorporates elements of Model, View, Control and interation. UserControls' ability to bundle all this together is exactly the reason that they don't fit well into MVC.
That means that to create a psuedo-UserControl in MVC requires four seperate pieces:
A Model class - in this case an Interval class or similar
A PartialView that knows how to render the Model to HTML
A jQuery script to layer interactivity on top of the PartialView's HTML
A ModelBinder that can deserialise postdata into an instance of the Model class.
The ModelBinder is important because it deals with data coming back from the user. Without it, every Controller that wanted to display a to/from date selector in any of its Views would have to know how to assemble the six postdata fields - and how to cope if they were invalid or some were missing.
Two ways that I can think of. A partial view though this doesn't really transfer well from app to app because you are moving around ascx files. Not a big pain but not my flavour.
I prefer to use WebControls. They are super easy in mvc and all you need to do is reference the library in the project and possibly in your config file and there you go.
I think some of the answers have missed out on the postback functionality of controls. One way you could handle that is to pass any generic information via ViewData when rendering your partial view. That could then post back to its own control, which in turn could redirect to the UrlReferrer.
Its a little messy and use of UrlReferrer poses a security risk. But it is one way around the problem
You can create a jQuery plugin.
As user-controls provided in ASP.NET Webforms, MVC provide a lot of ways to make the controls and code that can be reused in other app.
Using Partials If your partial code have some C# logic and render the html using Razor/aspx code then it's bst to maintain them in razor file.
Write JavaScript Functionality as plugin If you maintain your code and write it as better as it can be used in other app then it would be a huge advantage for you. Next time when you work on other app just open this solution copy it and modify it. Write JavaScript code that can be used as plugin maybe take some more brainstorming.
Write Code As a Separate C# library If some code is too common for every app you make.for example you write a member authentication system or some global function (C#) that are used in every app you made then maintain them in a separate solution so it can be used in other app you made whenever you trying to make a new app in future.

Using a Base Controller for obtaining Common ViewData

I am working on an ASP.NET MVC application that contains a header and menu on each page. The menu and header are dynamic. In other words, the menu items and header information are determined at runtime.
My initial thought is to build a base Controller from which all other controllers derive. In the base controller, I will obtain the menu and header data and insert the required information into the ViewData. Finally, I will use a ViewUserControl to display the header and menu through a master page template.
So, I'm trying to determine the best practice for building such functionality. Also, if this is the recommended approach, which method should I override (I'm guessing Execute) when obtaining the data for insertion into the ViewData.
I'm sure this is a common scenario, so any advice/best-practices would be appreciated! Thanks in advance!
EDIT:
I did find the following resources after posting this (of course), but any additional anecdotes would be awesome!
http://www.singingeels.com/Blogs/Nullable/2008/08/14/How_to_Handle_Side_Content_in_ASPNET_MVC.aspx
How do you use usercontrols in asp.net mvc that display an "island" of data?
Depends on where your information is coming from. We have standard view data that we use to generate some of the information we have on screen that we create in just this fashion. It works well and is easily maintained. We override the View method to implement strongly typed view names and use this information to retrieve some of the data that the master page requires as well.
You could write a helper extension to render the header/menu
That way you could have it show in different places in the view should you need to, but only one place for maintenance.
public static HtmlString MainMenu(this HtmlHelper helper)
Use a base controller class to implement generell filter methods. The controller class implements some filter interfaces IActionFilter, IAuthorizationFilter, IExceptionFilter and IResultFilter which are usefull to implement some common behavior for all controllers.
If the menu data is the same on all pages but different for each unique user.
Generate the menudata in an OnAuthorization or Initialize method of your controller base class. First will be called on authorization. Initialize will be called before every action method. You have access to ViewData Context. Generate the menudata there.
Put the view content for menu and header into the master page and access generated ViewData there.
I tackled a similar design challenge a couple months ago - implementing a breadcrumb feature that changes as user navigates from page to page.
I overrided the OnActionExecuting method to gather the breadcrumbs and store them in ViewData (I use the name of the action as the breadCrumb of the view). Then I updated the Master page to include a user control that takes the ViewData and renders the breadcrumbs.
One thing to be aware is that if you were using the default ASP.NET MVC error handling attribute [HandleError] and your error page is using the same Master page that attempts to read the ViewData, you will soon find out that you can't access ViewData from your error page and it will raise an exception. Depending on whether you need the ViewData for failure scenarios, the viable solution is to use a separate Master page or do this: How do I pass ViewData to a HandleError View?
I'll answer your question with another question. Will the base controller have to determine what type it really is in order to generate the proper menu data? If so, then you're defeating the purpose of polymorphism and the code to generate the data should go in each controller, perhaps in OnActionExecuting if the menu is the same for all actions. Pushing it back down into a parent class seems likely to end up with some switch statement in the parent class doing what each derived controller really ought to take care of.

Resources