MVC sending a View based on the browser, not mobile - asp.net-mvc

I have a single form that I had created for up to date browsers, but have to also ensure I have a version that renders fine on an embedded IE6 (old call center), I'm looking for a way to tell MVC to send my IE6 friendly form when it loads in that browser..
All the documentation I read is mobile related and has me confused.

If you're using MVC3, I believe you're limited to checking the user-agent string in the controller method, and returning the specific view you want to be returned. Something like:
if(Request.UserAgent.Contains("MSIE 6.0"))
{
return View("IE6View");
}
else
{
return View();
}
Since you say you have a single form only, this might be the simplest direct solution.
If you're using MVC4, Display Modes is available, where convention is used to automatically select views based on conditions you outline in the Global.asax. Decent write-up for this approach at the link below. It's written for mobile-specific views, but could be easily applied to a different user-agent string condition.
http://msdn.microsoft.com/en-us/magazine/hh975347.aspx

Related

Razor templates, views and angular.js

TL;DR
What are the best practices when using .NET Razor views and AngularJS?
Context
We are developing a public website (not an intranet application) using mvc4 with razor, and we weren't very familiar with client script, so we started with what we knew: jQuery.
But now things are getting more complicated and we'd like to switch to AngularJS.
On the .NET part, we use Razor templates and UIHintAttribute (plus some custom ones) to render the right html "control". We also add custom html attributes to give extra information to the jQuery part (like title for a tooltip....)
So we already use a declarative way of setting the user interface behavior, that's why AngularJS seems a good option.
Questions
Since we already have models defined server side, and since AngularJS also uses models, wouldn't it force us to duplicate code?
How do we deal with data binding feature, since we already do some binding server side (in the views). Should we make a completely asynchronous application, making AJAX calls from AngularJS to load data, or can we mix both?
Anything else we should be aware of when trying to use both of these technologies?
I did some research on Google, but I can't find detailed ways of mixing Razor views and templates with AngularJS... Perhaps that's just not a good thing to do?
We dealt with this issue for months when working with MVC plus another JavaScript framework (Knockout). Ultimately, if you're going to be using a client-side MV* framework for rendering your user interface, you will find that mostly ditching Razor is going to be your best bet.
Most of the major MV* JavaScript frameworks, including AngularJS, assume you will be maintaining UI state and rendering your user interface based on JavaScript models or view models. Trying to mix in server-side rendering is just not going to work very well.
That's not to say there is no use for MVC when it comes to developing an Angular application. You can still take advantage of some great features like ASP.NET Bundling and Minification. And sometimes it works really well to embed JSON directly into the page using a Razor view or partial as opposed to making an additional AJAX call.
As for models, you may want to take a look at Breeze.js. It's a JavaScript library for data access that goes great with ASP.NET on the server side to share model metadata.
We wrote our own data binding mechanism that synchronizes the angular.js model with a view model on the server side. The javascript model is generated from a JSON serialization of the server-side view model to avoid the duplicate code that you were talking about.
We are using SignalR to update the client's view model from the server.
Server-side changes of the C# view model properties are sent to the client as a packet containing the path to the property, e.g. Persons[42].Address.City, and the value itself, e.g. New York. The view model inherits a base class that takes care of generating the property path, so the actual view model looks quite clean and we can concentrate on business logic.
Client-side changes of the javascript view model properties are sent to the server in the same way. To catch the change events, we encapsulate all fields of the original javascript model in get/set properties where the setter sends the update packet to the server.
Server-side methods of the view model can be invoked in a similar way. All objects in the view model have an invokeMethod function that can be used like this: Products[42].Manufacturer.invokeMethod('SendEmail', 'mailsubject', 'mailbody'). This will send a packet to the server containing the method path Products[42].Manufacturer.SendEmail and the arguments as an array of ['mailsubject','mailbody'].
In conclusion, the html view (kind of) binds to the view model on the server side where other systems, such as regular Razor views can work on the same objects.
The source code can be found here: SharpAngie.

Do a full non-ajax post from a partial view in asp.net mvc

This more of an out of interest question than an urgently need an answer one, but I have been trying to find a good example of how to deal with a full postback from a partial view in asp.net MVC. The obvious example is the case where you have a small login form on every page. You can easily accomplish this through an asynchronous post back using jquery, but I am wondering if there is a way to do it without the use of javascript. I know it may be pedantic, but I don't like the idea of assuming the client has javascript enabled, particularly in this day and age where responsive design/ progressive enhacements are the big buzzwords around, so having you log in tied to javascript means that anyone on a simple mobile device won't be able to use it since their device probably won't support it.
Anyone have any ideas / examples of how to accomplish this? It's such a simple thing to implement in web forms I can't believe it's as tricky as I've heard it made out to be in MVC.
You just need a form within the view, that's all. The form will POST to its controller action method and generate a full page refresh (if that's what you mean by a full postback - I guess it is) irrespective of whether its a partial or not.
You can have multiple forms on a MVC view, and each one of them will give you a full page refresh, whereas with WebForms the pattern was one main form per page.

Changing HTML output in MVC3

In my MVC3 application I want to remove all HTML5 tags for the output when the user is using IE < 9 to avoid using a frontend workaround.
I've looked in to using a HttpModule, ActionFilter, the OnResultExecuted method on a controller and inside Application_Start.
I've figured so far that I need to get the output as a string from HttpApplication.Context.Response.OutputStream using something like:
HttpApplication application = (HttpApplication)source;
HttpResponse response = application.Context.Response;
StreamReader sr = new StreamReader(stream);
string content = sr.ReadToEnd();
But all I get is the same error Stream was not readable.
I can write to the response with context.Response.Write.
From reading around on SO and google, MVC doesn't seem to have the same "page life cycle" has webforms(where I'm just overring Render and it works fine) which makes sens.
So my question is how do I get the HTML as a String in MVC? Have anyone tried to manipulate the html output?
I think you should be able to use an ActionFilter to do this. I've seen an example of someone modifying the output stream in this blog post. or in this post.
HTML5 is backwards compatible so feel more than free to use this default output with any browser. Obsolete browsers such as IE6 would still render correctly and even unobtrusive validation is going to work. So my advice is to leave the output as is.
Why dont you use javascript? Just determine what is user browser and remove html you want. JQuery has nice methods to do that.
To follow the concept of the MVC pattern, I'd look to use a different View implementation depending on whether the browser supports HTML 5 or not rather than trying to bodge the output. An alternative would be to use controls through a third party library that can decompose gracefully when the browser doesn't support all the latest features (or the library can implement the controls independently). JQuery, as supplied with ASP.NET MVC is an ideal with many, many controls available that cover most HTML5 tags.

HTML Submit button vs AJAX based Post (ASP.NET MVC)

I'm after some design advice.
I'm working on an application with a fellow developer. I'm from the Webforms world and he's done a lot with jQuery and AJAX stuff. We're collaborating on a new ASP.MVC 1.0 app.
He's done some pretty amazing stuff that I'm just getting my head around, and used some 3rd party tools etc. for datagrids etc.
but...
He rarely uses Submit buttons whereas I use them most of the time. He uses a button but then attaches Javascript to it that calls an MVC action which returns a JSON object. He then parses the object to update the datagrid. I'm not sure how he deals with server-side validation - I think he adds a message property to the JSON object. A sample scenario would be to "Save" a new record that then gets added to the gridview.
The user doesn't see a postback as such, so he uses jQuery to disable the UI whilst the controller action is running.
TBH, it looks pretty cool.
However, the way I'd do it would be to use a Submit button to postback, let the ModelBinder populate a typed model class, parse that in my controller Action method, update the model (and apply any validation against the model), update it with the new record, then send it back to be rendered by the View. Unlike him, I don't return a JSON object, I let the View (and datagrid) bind to the new model data.
Both solutions "work" but we're obviously taking the application down different paths so one of us has to re-work our code... and we don't mind whose has to be done.
What I'd prefer though is that we adopt the "industry-standard" way of doing this. I'm unsure as to whether my WebForms background is influencing the fact that his way just "doesn't feel right", in that a "submit" is meant to submit data to the server.
Any advice at all please - many thanks.
The thing you need to take into consideration is how the application will work if javascript is not available. You should strive to ensure that the basic functionality works without it. This is called progressive enhancement or unobtrusive javascript and is considered a best practice.
http://en.wikipedia.org/wiki/Progressive_enhancement
The way you should do it is to use a form with a real submit button and then hijack that form to use ajax if the User Agent supports it. This is usually pretty trivial to do using the jquery forms plugin. In your action method, you can check to see if the incoming request is an ajax request by checking the Request.IsAjaxRequest property. This is set by MVC automatically on requests that have the X-Requested-With header set to XMLHttpRequest. Then you would return a full view or just some json based on that.
Here's a short screencast demonstrating this: http://www.youtube.com/watch?v=YQsFR1rkgMU&feature=player_embedded
Both solutions are viable, though using submit buttons will make your application more accessible (i.e. JavaScript will not be required in order to use it).
You could also do the both - start with a page that has all the necessary logic using postbacks, and "upgrade" it with nice AJAX-y requests and animations. This way, users with JavaScript will get the eye candy, and the page will gracefully degrade when when a user without JavaScript visits the page, falling back to the postback mechanism.

What is the 'page lifecycle' of an ASP.NET MVC page, compared to ASP.NET WebForms?

What is the 'page lifecycle' of an ASP.NET MVC page, compared to ASP.NET WebForms?
I'm tryin to better understand this 'simple' question in order to determine whether or not existing pages I have in a (very) simple site can be easily converted from ASP.NET WebForms.
Either a 'conversion' of the process below, or an alternative lifecycle would be what I'm looking for.
What I'm currently doing:
(yes i know that anyone capable of answering my question already knows all this -- i'm just tryin to get a comparison of the 'lifecycle' so i thought i'd start by filling in what we already all know)
Rendering the page:
I have a master page which contains my basic template
I have content pages that give me named regions from the master page into which I put content.
In an event handler for each content page I load data from the database (mostly read-only).
I bind this data to ASP.NET controls representing grids, dropdowns or repeaters. This data all 'lives' inside the HTML generated. Some of it gets into ViewState (but I wont go into that too much!)
I set properties or bind data to certain items like Image or TextBox controls on the page.
The page gets sent to the client rendered as non-reusable HTML.
I try to avoid using ViewState other than what the page needs as a minimum.
Client side (not using ASP.NET AJAX):
I may use JQuery and some nasty tricks to find controls on the page and perform operations on them.
If the user selects from a dropdown -- a postback is generated which triggers a C# event in my codebehind. This event may go to the database, but whatever it does a completely newly generated HTML page ends up getting sent back to the client.
I may use Page.Session to store key value pairs I need to reuse later
So with MVC how does this 'lifecycle' change?
I'll attempt to comment on each of the bullet points you mentioned:
Your master pages still exist in MVC and are used to provide a consistent layout to the site. not much new there.
Your content pages will become views in the MVC world. They still provide the same content areas to your master pages.
The eventhandling of webforms should not be used in MVC, instead your Controller classes and their action methods will handle loading your data into a "model" that gets passed to the view.
Although webform style databinding is possible in MVC, I find that it is not the optimal solution. Better to place your data in a model class and strongly type your view so that you have direct access to that model. Then its simply a matter of using the <%= ViewData.Model.SomeProperty %> syntax to access your data and display it in the desired locations. As for viewstate, my recommendation is to forget that it even exists.
Remember that one of the advantages of using MVC is that you have control over the HTML you send to the client. Embrace that power and try to find solutions that allow you to maintain that control. Webform controls attempt to hide the the html from you and as such make it more difficult to customize the html when you need to.
I would highly recommend JQuery or one of the other similarly powerful javascript libraries. But learn to use them to access the HTML DOM directly and avoid the id mangling issues of webform controls.
You can use jquery to hook into the dropdown selection on the client side and submit standard or ajax style requests. Those request can return new pages, redirects, html fragments or even JSON data that can be used to update the existing page.
The asp.net Session can be used as needed.

Resources