Different ASP.NET MVC master page for authenticated and unauthenticated users

I guess this is a common problem: you need to have different web site layout for unauthenticated users. In simple cases this is very easy: just use masterPageFile attribute on views. But it gets more complex when you have views that are used in both authenticated and unauthenticated context. Luckily MVC lets you plug into almost anything, and this can be solved with an action filter like this: using System.Web.Mvc; /// <summary> /// A globally registered attribute to change view master /// page based on whether user is authenticated or not. /// Uses magic strings for the file names, could /// be changed to something more elegant. /// </summary> public sealed class SwitchMasterPageFilter : IActionFilter { public void OnActionExecuting( ActionExecutingContext filterContext) { } public void OnActionExecuted( ActionExecutedContext filterContext) { var result = filterContext.Result as ViewResult; if (result != null) { bool authenticated = filterContext.HttpContext .User.Identity.IsAuthenticated; result.MasterName = authenticated ? "~/Views/Shared/Site.master" : "~/Views/Shared/SiteUnauthenticated.master"; } } } Remember to register the filter on your site bootstrapper and you are good to go.

January 11, 2012 · 1 min · Tero Teelahti

SSL, IE8 and strict cache headers (will not work)

Recently I encountered a bug that only some users saw, and which did not reproduce locally on development environment. The setup was: An intranet page has an IFrame …that is dynamically changed to point to an attachment …which is served from MVC action returning FileContentResult This is a pretty common pattern to open files on browser without leaving the current page. And it worked like charm in all browsers, except on Internet Explorer 8 on testing environment, where IE just showed an error message that the address cannot be opened. IE 7 might be affected too, but I did not test on that. ...

December 15, 2011 · 3 min · Tero Teelahti

How ASP.NET Web forms feels after 3 years of not using it

I have been an ASP.NET developer since it was invented, and a legacy ASP developer before that. For long I spent most of my time doing ASP.NET Web Forms and it was OK: I remember lots of weird problems that needed extensive trial and error –debugging, but things weren’t that bad. Then ASP.NET MVC came and I got interested. In the (massive) client project I worked for at that time I bent some Web forms concepts to the extreme and didn’t like it too much. MVC felt very light and as it embraced HTML it was very good for the new rising of HTML(5). ...

November 11, 2011 · 3 min · Tero Teelahti

How-to localize jQuery UI Datepicker within ASP.NET MVC site

JQuery’s date picker UI component is very easy to localize on Javascript level. On this blog post I’ll describe how to ensure that date picker culture follows site’s server side culture. This is pretty trivial to accomplish, but it won’t hurt to document it here. First, you need to pick the translations you need from jQuery UI trunk. Place these files on your script folder and include them on your page (or master page), here I’m using my favorite static content bundler SquishIt to combine and minify scripts: ...

May 16, 2011 · 1 min · Tero Teelahti

Disable submit buttons on form submit with jQuery.validate and ASP.NET MVC 2

I had a very common requirement to fill: when user clicks form submit button (or enter on keyboard) the button needs to be disabled in order to prevent double submits. Double submits could of course be filtered at server side with various timestamp mechanisms, but this was not what I was after this time. The first option that came into my mind was of course just to subscribe into form submit and disable buttons there like this: ...

April 29, 2011 · 2 min · Tero Teelahti

Controller dependency missing on test? Try MvcContrib TestControllerBuilder

Ever faced this situation: You have nice and easy controller method, say: public ActionResult Demonstrate(string id) { this.Repository.Demonstrate(id); string url = this.Url.Action(MVC.Errors.Suck(id)); return this.Redirect(url); } Then you go and create test for it (or created the test before, whatever suits you): [TestMethod] public void Demonstrate_ValidInput_Redirects() { // Arrange var controller = new MyDemonstratingController(); // ... mock something here // Act controller.Demonstrate("kaboom"); // Assert // ... test that everything was called } …only to get NullReferenceException, since you did not set everything up that is needed by the UrlHelper class (controller’s Url property). ...

April 26, 2011 · 1 min · Tero Teelahti

Selecting MVC action method based on any named form value

Yesterday I blogged about using form button names to select action methods on an ASP.NET MVC controller. After using that attribute for a while I realized that I can make a generalization out of that: why not use any form value in the action method selection process? This way I can avoid code like this: [HttpPost] public ActionResult Fruit(SampleModel model) { if (!ModelState.IsValid) { return View(model); } if (model.IsApple) { // Do something EatApple(model); } else { // Do something else SmashOthers(model); } TempData["Message"] = "Saved"; return RedirectToAction("Index"); } That is not too bad, but when more choices are introduced it gets worse and worse (i.e. more if-then-else’s). Solution for this is very similar with the ButtonAttribute approach: introduce an attribute that takes form element name, and list of accepted values. If there is a match the action method is selected, otherwise the search continues. Usage example: ...

March 26, 2011 · 4 min · Tero Teelahti

Selecting MVC action method based on the button clicked

Very common problem in form-heavy solutions is to be able to have one HTML form, but two different submit buttons for it. Think “Save” and “Delete”: <div id="buttons"> <button name="Save">Save</button> <button name="Delete">Delete</button> </div> On controller side this poses a problem: these actions do very different tasks; Save usually validates data and saves it, Delete does not validate and deletes (and so forth). They might also have different access rights. So having these on one action breaks (at least my) principles. Fortunately ASP.NET MVC has a thing called ActionMethodSelectorAttribute that you can extend. With that you can divide the logic into separate action methods, like: ...

March 25, 2011 · 3 min · Tero Teelahti