Install ASP.NET MVC 3 Manually

Update 14-jan-2011: I found the root solution to all my problems with msiinv, check my post on the subject.

I don’t know exactly why but I can’t install the MVC 3 package provided by Web Platform Installer nor the standalone one, so I uncompressed it and tried to figure out how to install it manually.

The problem I have is with vs10-kb2465236-x86.exe that gives me a “failed with 0x8007066a” error. It seems to be for enabling Razor syntax but the prerequisites are Visual Studio 2010 Ultimate ENU. I have Visual Studio 2010 Professional ESN and that may be the reason or may not.

Anyway, I found the way to install the package manually, although the Razor Intellisense stuff is not available in my setup.

First you have to uncompress the AspNetMVC3Setup.exe into a folder and then install the following files (I got the sequence from the parameterinfo.xml file, which describes the installation process):

  • VS10-KB2465236-x86.exe (it fails in my case, I don’t install it)
  • AspNetWebPages.msi – ASP.NET Web Pages
  • AspNetWebPagesVS2010Tools.msi – ASP.NET Web Pages Visual Studio 2010 Tools
  • AspNetMVC3.msi – ASP.NET MVC 3 Runtime
  • AspNetMVC3VS2010Tools.msi – ASP.NET MVC 3 Visual Studio 2010 Tools
  • NuGet.msi – NuGet

And that’s all. In case you have Web Developer Express instead of full Visual Studio, you have ton install the tools specifically for that edition, AspNetWebPagesVWD2010Tools.msi instead of AspNetWebPagesVS2010Tools.msi and AspNetMVC3VWD2010Tools.msi instead of AspNetMVC3VS2010Tools.msi.

Good luck!

Get MAC from IP address in .NET

After dealing with several options, most of them involving a call to a command line tool and parsing the output, which is not really elegant. Other solutions were based on obsolete VBScript client code and ActiveX, even worse.

Finally I found in the excellent pinvoke.net site a very nice and simple example using a simple call to iphlpapi.dll’s SendARP method. The trick was to use ARP to get the MAC from the IP.

Note that this has it’s limitations, as I will only work if the remote machine is in the same network and the packet does not need to go through a router. I was enough for our needs.

Here’s the code I adapted from the example:

public static string GetMAC(IPAddress ipAddr)
{
var mac = new byte[6];
var len = (uint)mac.Length;

var result = SendARP((int)ipAddr.Address, 0, mac, ref len);

if (result != 0)
{
return "MAC not found!";
}

var str = new string[(int)len];

for (var i = 0; i < len; i++)
{
str[i] = mac[i].ToString("x2");
}

return string.Join(":", str);
}

[DllImport("iphlpapi.dll", ExactSpelling = true)]
private static extern int SendARP(int destIP, int srcIP, byte[] pMacAddr, ref uint phyAddrLen);

Enjoy!

ASP.NET MVC and ReturnUrl

I’ve seen many ASP.NET MVC samples and some of them do not honor de ReturnUrl parameter, rendering this unusable.

Classic ASP.NET has the login form component that puts the same exact URL used to access the login page in the form action URL, preserving the ReturnUrl parameter and then, FormsAuthentication.GetReturnUrl() gets it from the Request.QueryString collection.

Fortunately, the GetReturnUrl() method looks as well in Request.Form in case there’s nothing in the query, this way, we can use a hidden field as well to store the ReturnUrl in the View and pass it through POST when the login form is submitted.

So, in ASP.NET MVC we have two options:

  1. Use simply Html.BeginForm() without parameters, which will put a simple form tag, with the same URL as the current one and use POST by default
  2. If we want to have more control on the Html.BeginForm(), put a hidden field with the value of the ReturnUrl, only if the ReturnUrl is not empty, or it will fail. This can be obtained from the Request.QueryString collection, the ViewData if we put it previously on the Controller action or even better store it in the ViewModel and have a strong typed reference.

And that’s it. Then, FormsAuthentication.GetReturnUrl() will get the proper URL and other methods like FormsAuthentication.RedirectFromLoginPage() will also work seamlessly.