Monday, November 7, 2011

PRG Pattern - How to Keep MVC ModelState

According to the definition of the HTTP POST and GET verbs:

  1. HTTP GET is used for non-changing (idempotent) data to your model.

  2. HTTP POST is used for changing data to your model.


Given this clear delineation, when receiving form data in your post back action method, return RedirectToAction(), which will result in a HTTP 302 (temporary redirect) and will generate a GET on the. This results in Post-Redirect-Get pattern.

One of the issue with this pattern, when using Asp .Net MVC, is that when validation fails or any exception occurs you have to copy the ModelState into TempData. Kazi Mansur has a great solution posted here under the sub section "13. Use PRG Pattern for Data Modification".

The examples he shows is:

[sourcecode language="csharp"]
public abstract class ModelStateTempDataTransfer : ActionFilterAttribute
{
protected static readonly string Key = typeof(ModelStateTempDataTransfer).FullName;
}

[AcceptVerbs(HttpVerbs.Get), OutputCache(CacheProfile = "Dashboard"), StoryListFilter, ImportModelStateFromTempData]
public ActionResult Dashboard(string userName, StoryListTab tab, OrderBy orderBy, int? page)
{
//Other Codes
return View();
}

[AcceptVerbs(HttpVerbs.Post), ExportModelStateToTempData]
public ActionResult Submit(string userName, string url)
{
if (ValidateSubmit(url))
{
try
{
_storyService.Submit(userName, url);
}
catch (Exception e)
{
ModelState.AddModelError(ModelStateException, e);
}
}

return Redirect(Url.Dashboard());
}
[/sourcecode]

and for the Action Filter itself

[sourcecode language="csharp"]
public class ExportModelStateToTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//Only export when ModelState is not valid
if (!filterContext.Controller.ViewData.ModelState.IsValid)
{
//Export if we are redirecting
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
{
filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState;
}
}

base.OnActionExecuted(filterContext);
}
}

public class ImportModelStateFromTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;

if (modelState != null)
{
//Only Import if we are viewing
if (filterContext.Result is ViewResult)
{
filterContext.Controller.ViewData.ModelState.Merge(modelState);
}
else
{
//Otherwise remove it.
filterContext.Controller.TempData.Remove(Key);
}
}

base.OnActionExecuted(filterContext);
}
}
[/sourcecode]


I like the way this has been handled but because I like to learn from other people's ideas I also like to use the workflow for HTTP POSTs as described by Jimmy Bogard in his post, Cleaning up POSTs in ASP.NET MVC.

In short each action that requires a POST using the following ActionResult:

[sourcecode language="csharp"]
public class FormActionResult<T> : ActionResult
{
public ViewResult Failure { get; private set; }
public ActionResult Success { get; private set; }
public T Form { get; private set; }

public FormActionResult(T form, ActionResult success, ViewResult failure)
{
Form = form;
Success = success;
Failure = failure;
}

public override void ExecuteResult(ControllerContext context)
{
if (!context.Controller.ViewData.ModelState.IsValid)
{
Failure.ExecuteResult(context);

return;
}

var handler = ObjectFactory.GetInstance<IFormHandler<T>>();

handler.Handle(Form);

Success.ExecuteResult(context);
}
}[/sourcecode]

Which not only cleans up the POST workflow and makes testing so much easier but it also helps separate application concerns. In the original Action Filter there is a guard clause to ensure that the Filter Context result is either a RedirectResult or a RedirectToRouteResult

[sourcecode language="csharp"]
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
[/sourcecode]

So how do we add the clause so that the result can be of the Generic type of FormActionResult? By using reflection.
[sourcecode language="csharp"]
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult) || (filterContext.Result.IsTypeOfGeneric(typeof(FormActionResult<>))))
[/sourcecode]

where the signature IsTypeOfGeneric is an extension method which looks like the following:
[sourcecode language="csharp"]
public static bool IsTypeOfGeneric<T>(this T source, Type genericTypeToCompare)
{
if (!genericTypeToCompare.IsGenericType)
throw new ApplicationException(@"Compare type needs to be generic");

if (!source.GetType().IsGenericType)
throw new ApplicationException(@"Base type needs to be generic");

return source.GetType().GetGenericTypeDefinition()==genericTypeToCompare;
}
[/sourcecode]

The msdn definition of the method GetGenericTypeDefinition is here

Now we can use FormActionResult within our code and the ModelState will be saved from the POST to the GET.

Tuesday, September 6, 2011

ASP Webforms Lifecycle

Last week the following question came up at work:
what's the event order for a masterpage with usercontrols?

In response I pointed to a blown up printed version of the ASP .NET page Lifecycle for .Net 2.0 runtime Cheat sheet ASP .NET page Lifecycle for .Net 2.0 runtime.

I've found it to be an exceptional resource tool.

The blog post relating to the cheat sheet can be found at Kris' blog. Kudos for Kris for sharing it.

All credits go to the original designer of the diagram: Léon Andrianarivony.

Friday, July 8, 2011

MVC3 Security: A Fluent Way

In Asp MVC you can control user authorization by using security attributes to decorate the controller actions for authorization, for example, in the following AccountController class, the Authorize attribute decorates the ChangePassword action method so it will only allow logged in users to change their passwords. One way to test this is,


Code Snippet

[Test]
        public void Verify_ChangePassword_Method_Is_Decorated_With_Authorize_Attribute()
        {
            var controller = new AccountController();

            var type = controller.GetType();
            var methodInfo = type.GetMethod("ChangePassword", new Type[] { typeof(ChangePasswordModel) });

            var attributes = methodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), true);
            Assert.IsTrue(attributes.Any(), "No AuthorizeAttribute found on ChangePassword(ChangePasswordModel model) method");
        }



While the above code certainly tests that the Change Password method has the Authorize Attribute the usage of Reflection is quite heavy. For me it makes the test a bit too verbose. Enter the Fluent Security framework. To quote the website “Fluent Security provides a fluent interface for configuring security in ASP.NET MVC. No attributes or nasty xml, just pure love.” Also available via NuGet:

[sourcecode language="csharp"]
PM> Install-Package FluentSecurity
[/sourcecode]

Fluent Security enables the implementation of configuration based security. Let’s start by removing the Authorize attribute from the Account Controller:


Code Snippet

[HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {
                // ChangePassword will throw an exception rather
                // than return false in certain failure scenarios.
                bool changePasswordSucceeded;
                try
                {
                    MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
                    changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }



Now to configure Fluent Security to secure the ChangePassword action, you can place the code the the Application start event of the Global.asax file. I prefer keep as much code out of that as possible and use a Application Bootstrapper.


Code Snippet

public class SecurityBootstrapper : IBootstrapThisApp
        {
            public void Execute()
            {
                SecurityConfigurator.Configure(configuration =>
                {
                    // Let Fluent Security know how to get the authentication status of the current user
                    configuration.GetAuthenticationStatusFrom(() => HttpContext.Current.User.Identity.IsAuthenticated);

                    // This is where you set up the policies you want Fluent Security to enforce
                    configuration.For<HomeController>().Ignore();

                    //configuration.For<AccountController>().DenyAuthenticatedAccess();
                    configuration.For<AccountController>(x => x.LogOff()).DenyAnonymousAccess();
                });

                GlobalFilters.Filters.Add(new HandleSecurityAttribute(), 0);
            }
        }

        public interface IBootstrapThisApp
        {
            void Execute();
        }



By default Fluent Security will throw an exception if a missing configuration is encountered for a controller action. If you don't want Fluent Security to handle security for all controllers you can tell it to ignore missing configurations. You can do this by adding configuration.IgnoreMissingConfiguration(); to your configuration expression. Testing becomes pretty simple using Fluent Securities Test Helper, available as a NuGet package.



Code Snippet

[Test]
        public void Should_Have_Correct_Security_Configuration()
        {
            new SecurityBootstrapper().Execute();
            var results = SecurityConfiguration.Current.Verify(x =>
            {
                x.Expect<HomeController>().Has<IgnorePolicy>();
                x.Expect<AccountController>().Has<DenyAuthenticatedAccessPolicy>();

                x.Expect<AccountController>(y => y.LogOff()).Has<DenyAnonymousAccessPolicy>().DoesNotHave<DenyAuthenticatedAccessPolicy>();
            });

            Assert.That(results.Valid(), results.ErrorMessages());
        }




I've only just started to implement security using the above methods and so far I am liking the framework. Testing becomes easier and it's a lot easier to get an overview of your Web Applications Security configuration

Monday, March 28, 2011

Presenter Discovery Strategy WebformsMVP

[Update: As per comment posted by Anonymous, Get at least the changeset from March 29th (http://webformsmvp.codeplex.com/SourceControl/changeset/changes/8d76d88f629e) for the following code to work]

Fearing the start of a flame war, I do like the WebformsMVP framework. It's opinionated and it's works well. That's not to say I don't like Asp MVC, I do but I don't believe it's the only weapon in the .Net web developers arsenal. That's like saying I should always use a hammer to drive in a nail, what happens if the nail weighs 5kg.... you need a sledgehammer. While that certainly is drawing an extremely long bow (Being a guy the true answer if you can use a big electric tool use it, if not use a 20 pound sledgehammer or gaffer tape anyhow...) You should use the correct tool for the right job, for instance if I require a rich internet application I will use MVC, otherwise I will use Webforms.In saying the above Webforms certainly can be a pretty rich client experience.Anyhow enough of the ranting and onto the real purpose of this blog post.Previous to version 1.0 of the WebformsMVP project the only way to override the default behaviour of presenter discovery was by using Attributes such as

[sourcecode language="csharp"]
[PresenterBinding(typeof(ProductsAdminPresenter))]
public partial class ProductsAdmin : MvpUserControl, IProductsAdminView
[/sourcecode]

With the release of version 1.0, if you don't like the default Presenter discovery strategy you can now roll your own because the Presenter discovery strategies are now pluggable.Let's say, for instance, that my Presenter classes are in the namespace MyProjectName.Core.Presenters. To allow for custom presenter discovery I can create a new class inheriting from the type ConventionBasedPresenterDiscoveryStrategy.
[sourcecode language="csharp"]
public partial class CustomPresenterDiscoveryStrategy: ConventionBasedPresenterDiscoveryStrategy
{
public override CandidatePresenterTypeFullNameFormats
{
get{new[]{"{namespace}.Core.Presenters.{presenter}"};}
}
}
[/sourcecode]
If the code is trying to resolve the presenter for the ProductsAdmin partial class the above code will tell the PresenterBinder to look for MyProjectName.Core.Presenters.ProductsAdminPresenter.To plug the custom implementation into the framework in the Application_Start method of the Global.asax file (or where ever you do Bootstrapping)
[sourcecode language="csharp"]
protected void Application_Start(object sender, EventArgs e)
{
PresenterBinder.DiscoveryStrategy = new CompositePresenterDiscoveryStrategy( new AttributeBasedPresenterDiscoveryStrategy(), new CustomPresenterDiscoveryStrategy());
}
[/sourcecode]

By including the AttributeBasedDiscoveryStrategy class you can still use attribute overrides for tasks such as using shared presenters, but it'll fall through to your custom strategy for everything else.

Sunday, March 27, 2011

NuGet Packages and Dependencies

I admit that I've always liked the Ruby package management system, RubyGems. Until a few months ago I never even thought about a similar mechanism for the .Net Developer then along came NuGet. NuGet has the potential to really help push open source on the .NET platform and at the same time make the rigor of managing packages somewhat easier.

I am not saying NuGet isn't with it's pain points at times, but overall it's a fantastic tool.

One pet peeve I do have from time to time is dependencies within a package.

For instance Fluent NHibernate when installed through NuGet references NHibernate, Version=3.0.0.2001. I always try to use the latest and greatest versions of Libraries I work with. Whenever I build a web project referencing FluentNHibernate I get the following error bubbled up from StructureMap

StructureMap configuration failures:
Error: 170
Source: Registry: StructureMap.Configuration.DSL.Registry, StructureMap, Version=2.6.2.0, Culture=neutral, PublicKeyToken=e60ad81abae3c223
Unable to find the exported Type's in assembly BasilBee.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null. One or more of the assembly's dependencies may be missing.

Could not load file or assembly 'NHibernate, Version=3.0.0.2001, Culture=neutral, PublicKeyToken=aa95f207798dfdb4' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
System.IO.FileLoadException: Could not load file or assembly 'NHibernate, Version=3.0.0.2001, Culture=neutral, PublicKeyToken=aa95f207798dfdb4' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'NHibernate, Version=3.0.0.2001, Culture=neutral, PublicKeyToken=aa95f207798dfdb4'
at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes)
at System.Reflection.RuntimeAssembly.GetExportedTypes()
at StructureMap.Graph.TypePool.c__DisplayClass2.b__0(Assembly assembly) in c:\code\structuremap\Source\StructureMap\Graph\AssemblyScanner.cs:line 24


Luckily NuGet has a command for just this scenario which I discovered at David Ebbo's blog.

First you need to build your project and from the package manager console type:
PM> Add-BindingRedirect


This will add the minimal set of binding redirects to config to get everything working.

Once I ran the command my project starting running as expected.

Personally I think this is a great addition to the NuGet commands. Package Managers certainly can't be always up to date with the latest package references.[UPDATE]No longer relevant with the release of version 1.2

Wednesday, January 19, 2011

Using StructureMap Automocker To Make Writing Tests fun.

I have for a period of time been a big fan of Jeremy Miller’s StructureMap library for Dependency Injection/Inversion Of Control. I particularly enjoy the Auto Registration and Type Scanning features of the library.

For instance within the Data Layer a registry such as:
[sourcecode language="csharp"]
public class DataRegistry : Registry
{
public DataRegistry()
{
Scan(x =&gt; { x.AddAllTypesOf(); x.ConnectImplementationsToTypesClosing(typeof(IRepository)); x.TheCallingAssembly(); });
}
}
[/sourcecode]

This class, which inherits from StructureMap.Configuration.DSLRegistry, will scan the types in the assembly that contains the Data Registry class, adds all implementations of IQuery to the the container and connects all implementation to the open generic IRepository.

I have recently discovered another feature that makes StructureMap one of my essential tools in my Development Toolkit. The aforementioned feature is Automocker, which comes in flavours such as RhinoAutoMocker and MoqAutoMocker. Automocker repurposes an IoC container to automate the creation and attachment of mock objects to a concrete class within unit tests. Certainly is a mouthful but hopefully an example will shed some light on the some of the advantages.

Let’s say you are writing Unit Tests for a Child Sponsorship website for Worldvision (something that happens quite a bit to me) and you have a class whose responsibility is to lock a user chosen child so that the child cannot be sponsored by another user of the site.

The class could look something like this:
[sourcecode language="csharp"]
public class ChildChosenForSponsorshipCommandHandler : ICommandHandler
{
private readonly IRepository _childRepository;
private readonly IChildOnHoldTimer _childOnHoldTimer;

public ChildChosenForSponsorshipCommandHandler(IRepository childRepository, IChildOnHoldTimer childOnHoldTimer)
{
_childRepository = childRepository;_
childOnHoldTimer = childOnHoldTimer;
}

public void Handle(Child child)
{
_childRepository.PlaceChildOnHold(child);
_childOnHoldTimer.Start();
}
}
[/sourcecode]

One test which could be written for this user story is
[sourcecode language="csharp"]
[Test]
public void ShouldPlaceChildOnHoldWhenChildIsChosenForSponsorship()
{
//arrangevar mockChildRepostory = MockRepository.GenerateMock();
var mockChildOnHoldTimer = MockRepository.GenerateMock();
var childChosenForSponsorshipCommandHandler = new ChildChosenForSponsorshipCommandHandler(mockChildRepostory,mockChildOnHoldTimer);

var child = new Core.Handlers.Child();

//actchildChosenForSponsorshipCommandHandler.Handle(child);

//assertmockChildRepostory.AssertWasCalled(x =&gt; x.PlaceChildOnHold(child));
}
[/sourcecode]

The way in which can be written using StructureMap’s AutoMocker assembly is:
[sourcecode language="csharp"]
[Test]
public void ShouldPlaceChildOnHoldWhenChildIsChosenForSponsorship()
{
//arrangevar childChosenForSponsorshipCommandHandler = new RhinoAutoMocker();

var child = new Core.Handlers.Child();

var classUnderTest = childChosenForSponsorshipCommandHandler.ClassUnderTest;

//actclassUnderTest.Handle(child);

//assertchildChosenForSponsorshipCommandHandler.Get().AssertWasCalled(x=&gt;x.PlaceChildOnHold(child));
}
[/sourcecode]

A whole ONE line less code, I’ll have that new feature out before lunch! On the surface in may not look like much but if the class under test (CUT) has three, four or more dependencies you’ve made the arranging of the Unit Test much easier. The greatest benefit of the AutoMocker that I can see is that it helps keep the content of your tests focused on what needs to be tested, the functionality of your system. It also helps to keep your tests less brittle as your objects evolve. That is, if you add another dependency as your code evolves and you’ve got 15 tests under this Test Fixture you won’t have 15 tests to fix so that you can get the green light. In other words you can concentrate on what is important the context of the next test.

Monday, January 3, 2011

MVC: Making my life a bit easier using UrlHelper and HtmlHelperExtensions

In this post I’m going to outline some of the Extension methods that I use to make my life a bit easier when authoring views pages in MVC.

Through the process of developing code I do my best to avoid “Magik Str!ngs”.. sorry I mean “Magic Strings”. They are prone to misspellings and can add a headache especially if you have variants of the some Html snippet throughout your views that can be avoided with some forethought.

For View pages in MVC I do my best to avoid

[sourcecode language="html"]
<link href="/css/sidebar.css" id="Link1" rel="Stylesheet" type="text/css" />
<link href="/css/styles.css" id="cssStyleSheet" rel="Stylesheet" type="text/css" />
<link href="/css/custom-theme/jquery-ui-1.7.2.custom.css" type="text/css" rel="stylesheet" />
<link href="/css/standard.css" rel="stylesheet" type="text/css" />
<link href="/css/custom-theme/jquery-ui-1.7.2.custom.css" type="text/css" rel="Stylesheet" />

@Html.ActionLink("About", "About", "Home")
[/sourcecode]

To help me avoid passing the controller, action or route name as string, I create extension methods for UrlHelper and HtmlHelper to encapsulate the required Html Output:

[sourcecode language="csharp"]
public static class UrlHelperExtension
{
public static string About(this UrlHelper urlHelper)
{
return urlHelper.Action("About", "Home");
}
}
[/sourcecode]

Combining this with a HtmlExtension:

[sourcecode language="csharp"]
public static class HtmlHelperExtension
{
public static IHtmlString AnchorLink(this HtmlHelper htmlHelper, string url, string anchorDisplayName)
{
return new HtmlString("<a href=\"{0}\">{1}</a>".FormatWith(url, anchorDisplayName));
}
}
[/sourcecode]

I use an extension method called “AnchorLink” to which I pass two string variables, one for the required Url and another for the display text for the anchor link. Note that I also use IHtmlString. If I returned a string object from this method I would always have to remember to use Html.Raw or HtmlString in my views, which certainly opens up the possibility of adding some rendering issues to some of the views.

[sourcecode language="html"]
@Html.AnchorLink(Url.About(), "About")
[/sourcecode]

which will output the following HtmlSnippet

[sourcecode language="html"]
<a href="/Home/About">About</a>
[/sourcecode]

I use a similar pattern for Css and Javascript registration in the Views using the following signatures:

[sourcecode language="csharp"]
public static IHtmlString StyleSheet(this UrlHelper urlHelper, string css)

public static IHtmlString Javascript(this UrlHelper urlHelper, string js)
[/sourcecode]

then in my view for the registration of css I just use

[sourcecode language="csharp"]
@Url.StyleSheet("style.css")
[/sourcecode]

I will also register the Namespace of my Helpers in the config file. If you are using the Razor ViewEngine note that the namespace needs to be be registered as such

[sourcecode language="xml"]
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="CUSTOM_NAMESPACE_HERE" />
</namespaces>
</pages>
</system.web.webPages.razor>
[/sourcecode]

Hope this post helps someone else’s development sanity.