Initial setup for a new ASP.NET MVC site in IIS7

Background Over the years, I have spent far too many hours running the same set of commands against ASP.NET and ASP.NET MVC sites to bring them up to what I consider a starting point. Most of the time, I have to refresh myself about how to do at least one of them. This is a list of those commands in a central location for myself and anyone else to use. As with any good instructions, there is no guarantee you won’t completely destroy your server, site, or soul using these commands. I can only say they worked for me once. Remove unnecessary HTTP headers Server X-Powered-By X-AspNet-Version X-AspNetMvc-Version Adding dynamic content compression (e.g., GZIP) GZIP for JSON and JSONP content types (e.g., “application/json”) Complete appcmd command-line list Remove unnecessary HTTP headers By default, IIS and ASP.NET give you a few headers in each and every HTTP response sent out. Server: Microsoft-IIS/7.5 (or 7.0, or whatever IIS version you have) X-Powered-By: ASP.NET X-AspNet-Version: 4.0.303319 (or 2.0.50727, or 1.1.4322, or whatever version you have) X-AspNetMvc-Version: 3.0 (or 2.0, or 1.0, or whatever version you have) People will rant and rave about removing these headers for security and whether that helps. I am… Continue reading

Subtleties with using Url.RouteUrl to get fully-qualified URLs

At some point I missed the Url.RouteUrl overload that took a protocol and returned an absolute URL based on the current context. It is quite handy when you are sending URLs out into the world (e.g., RSS feed link). I ended up using the less-handy overload that took an explicit host (same as the current, in this case) and passing it in. When someone pointed out the simpler overload, I did the obvious and deleted the host from the call. That didn’t quite work. For those looking for a way to get a fully-qualified URL through the route system, the less-than-obvious answer is to call the overload for Url.RouteUrl that gets a URL with a different protocol (Url.RouteUrl(string, object, string)), passing in Request.Url.Scheme for the current protocol. Url.RouteUrl(“Default”, new { action = “Index”, controller = “Department”, id = 1 }, Request.Url.Scheme); // https://www.currentdomain.com/department/index/1 Say you want to send someone to a different subdomain in your app while using the same routes. There’s an overload for that: Url.RouteUrl(string, RouteValueDictionary, string, string). Combined with the above example, here’s how these all play out if you are currently handling a www.currentdomain.com request and your route table includes the fallback default ({controller}/{action}/{id}). Url.RouteUrl(“Default”, new… Continue reading

Handling case-insensitive enum action method parameters in ASP.NET MVC

Skip to solution Using enums as action method parameters Say you have a enum, a sorting enum in this case. public enum SortType { NewestFirst, OldestFirst, HighestRated, MostReviews } ASP.NET will gladly let you use that enum as an action method parameter; you can even make it an optional parameter. To make it optional by routing, you need to make it nullable for the action method function parameter in your controller and add some guarding logic (!sort.HasValue or the like). routes.MapRoute( “DepartmentProducts”, “Department/Products/{sort}”, new { controller = “Department”, action = “Products”, sort = UrlParameter.Optional } ); public ActionResult Products(SortType? sort) { SortType requestedSort = sort ?? SortType.NewestFirst; … } To make the parameter optional by function parameter, just give the parameter a default value. routes.MapRoute( “DepartmentProducts”, “Department/Products/{sort}”, new { controller = “Department”, action = “Products” } ); public ActionResult Products(SortType sort = SortType.NewestFirst) { … } Both work just fine, though I lean toward the function parameter default. Regardless of implementation, you can call the method by a number of different URLs: https://www.somedomain.com/department/products/ (sort == null or SortType.NewestFirst, respectively) https://www.somedomain.com/department/products/OldestFirst/ https://www.somedomain.com/department/products/HighestRated/ https://www.somedomain.com/department/products/?sort=MostReviews Unfortunately, it requires the route value to be an exact match for the enum name, proper case included…. Continue reading