Sitecore hits multible methods in MVC controller on submit

Sitecore’s implementation of MVC

Sitecore’s implementation of .NET MVC is sometimes a bit quirky. Every now and then, I run into some strange behavior, such as this example. This I have met before, but a colleague of mine presented me with a very nice solution, which i wanted to share.

A submit to a Sitecore controller hits all methods

As i’m sure many Sitecore developers that uses MVC has experienced, if you have a submit button on a page, Sitecore calls all the public methods that returns an ActionResult, which of course can have unfortunate consequences and is a strange behavior to begin with.

There are some ways to mitigate this, such as wrapping the button in a Html.BeginForm and passing the controller name and desired method to hit along like this:

@using (Html.BeginForm("MyController", "MyActionResultMethod"))
{
  <input type="submit" value="Confirm" />
}

However, this causes Sitecore to only return the rendered output from the view that the controller returns. So if your controller only is responsible for a small part on the entire page, you only get the output from that controller. This is another strange behavior from Sitecore’s MVC implementation.

Implement a custom ActionNameSelectorAttribute

A colleague of mine at Pentia showed me a elegant solution, implementing a custom ActionNameSelectorAttribute. This allows me to map the ‘name’ attribute of the submit button to an ActionResult method name. This way I no longer need to specify the method name in the BeginForm, which means Sitecore now returns the entire page as intended. The code looks like this:

using System.Reflection;
using System.Web.Mvc;
public class HttpParamActionAttribute : ActionNameSelectorAttribute
{
  public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
  {
    if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
      return true;

    var request = controllerContext.RequestContext.HttpContext.Request;
    return request[methodInfo.Name] != null;
  }
}

Now you need to add the name of the ActionResult method in your controller to the ‘name attribute of your button:

@using (Html.BeginForm())
{
  <input type="submit" name="MySubmitMethod" value="Confirm" />
}

And finally, your add the new attribute to your ActionResult method:

[HttpPost]
[HttpParamAction]
public ActionResult MySubmitMethod(…)
{...}

A nice solution to a quirky problem. Luckily Sitecore is reworking the MVC implementation. Hopefully it will be a bit more straight forward.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Sitecore tackled

Small posts about Sitecore and solutions

Cooking with Sitecore

Diary of my experience working on great CMS called Sitecore

Visions In Code

Never look back

Cook 4 Passion

Food food fooooood. We love fooooooooood !!!

Eldblom

Sitecore, Digital Marketing, Work, Life and so on...

SitecoreJunkie.com

Down the DLL Rabbit Hole

frontendrush

Arash Sarfehjou

DotNetCoder.dk

.NET code and tweaks

.NET code and tweaks

The grumpy coder.

.NET code and tweaks

Alan Coates - Sitecore/.NET blog

Pushing Sitecore to the limits and beyond

Patrick Delancy

i write code

Laub plus Co

.NET code and tweaks

iStern Blog

A simple Code Blog

Brian Pedersen's Sitecore and .NET Blog

Sitecore, C#, ASP.NET for developers

%d bloggers like this: