Handling multiple submit buttons in ASP.NET MVC action methods

You can have multiple non nested forms all posting to different action methods from different submit buttons, you can also have multiple submit buttons posting to the same form and hence action method. In an MVC action method which is posted to by multiple submit buttons, how does one tell which button was responsible for the form post? Two easy ways are outlined on stackoverflow which I’m reposting as is here just to add a bit of extra ‘commentary’. Author is highlighted in yellow.

  1. In your razor mark-up each submit button has a different name property. Since only the name of the button which caused the submit will be posted in the HTTP request header, in your action method you can check the Request.Form collection to see which submit button property name exists and take action accordingly. In this case you don’t have to change your action method signature and given that the value property of your submit buttons is insignificant to determining which button was pressed, all your submit buttons can have the same label/text if needs be.
    image003
  2. In your razor mark-up each submit button has the same property name but different value, since only the name (and significantly value) of the button which caused the submit will be posted in the HTTP request header, you can add a property to your action method signature for MVC to bind to and populate. You can then check the value of that property and take action accordingly. This is the more MVC (and perhaps elegant) way I guess as your using default model binder rather than checking form collections directly, personally however I prefer the approach above as you don’t have to change the action method signature and the button test is not based on some visible on page property which could matter in some scenarios.image007

    Related Links

    http://stackoverflow.com/questions/19650345/mvc-razor-form-with-multiple-different-submit-buttons – Stackoverflow page with a number of solutions including the two above and an AJAX based one too.

Excluding $(this) from jQuery selector

If you want to attach a click (for example) event to a set of elements but then do something with all those elements except the one clicked that can be achieved easily with the .not() function in jQuery:

Var $contentLinks = $(“.content a”);
$contentLinks.click(function() {
$contentLinks.not(this).hide();
});

Note, caching of the set outside the click function to help from a performance point of view.

Related Links

http://api.jquery.com/not/

Viewing raw HTTP post name/value pairs sent to MVC action method

When using ASP.NET MVC sometimes after a request viewModel properties you expect to be binded and populated are not. For HTTP GET action methods debugging why this might be is easy as the params are visible in your URL.  For HTTP POST requests the name/value pairs are sent in the header so they are not as easy to review.

One could use Fiddler or the Chrome/IE developer tools to look at the raw name/values pairs being posted across from the view but the Visual Studio Locals window gives you access to this information too. Just set a breakpoint in your action method and examine the current request object in the Locals window as shown below, the particular property you want to look at is Form. In the example below we can see the raw name/value pair string isSelectedCity=4&Country=United+States

 

image001 (1)

Forms authentication failed for the request. Reason: The ticket supplied was invalid

If your using forms authentication in .net and the application that creates the authentication cookie is different than the one that consumes it (i.e. Web farm scenario), the consuming application may not be able to decrypt the authentication token in the cookie and hence you might see something similar to ‘Forms authentication failed for the request. Reason: The ticket supplied was invalid’ in your event log. I had this recently and two common causes were:

  1. Machine key is different between application creating the authentication cookie and the application(s) using it.
    Keys must match. You can edit machine keys through IIS (as in below image) or directly through the web.config. Restart IIS/App pool shouldn’t be required.

image002

  1. Application creating the authentication cookie and the application(s) using it use a different cryptography core due to one targeting .net 4.5 and the other targeting 2.0 or 4.0. The method of decrypting tokens has changed since 4.5 and so an authentication token created by an application targeting 2.0/4.0 cannot be validated by an application targeting 4.5. The 4.5 cryptographic core is opt in (so not to break 2.0/4.0 applications running on machines which happen to have 4.5 installed) but the Visual Studio 4.5 project template includes one of the two different tags required to opt-in in the generated web.config. In our case our login app was a 2.0 app, but our new app was targeting 4.5.1 and so the default web.config included the following tag:

    <httpRuntime targetFramework=”4.5.1″ />

    which meant our new 4.5.1 app couldn’t decrypt the generated auth cookie. We simply changed that to <httpRuntime /> and things worked then. The second way to opt in is via the machinekey tag i.e:

    <machineKey compatibilityMode=”Framework45″ />

    so if you having problems decrypting make sure your apps have compatible runtimes set.

Related Links

Cryptographic Improvements in ASP.NET 4.5, pt. 2 – Great blog post detailing the cryptographic core changes in 4.5 and how to preserve compatibility with older versions of the framework.

Viewing SQL generated by Entity Framework when querying or calling SaveChanges()

When using Entity Framework, in an effort to track down bugs or performance problems, it’s very handy to see what SQL Entity Framework is generating and sending to the DB when you run a lambda/linq query or indeed make a call to SaveChanges().

This is easy once you know how. Simple add this.Database.Log = x => System.Diagnostics.Debug.WriteLine(x); to the constructor of your database context class (the one that derives from DbContext):

dbcontext

Afterwards you should see all the queries Entity Framework is sending to the DB in your output window.