Why can't I get the MvcHttpHandler to handle my .mvc requests? - asp.net-mvc

I have a project using Asp.Net 3.5 and MVC 1.
Everything runs perfectly on my local IIS, but not after I deployed it to the hosted server.
The web server is IIS7 with integrated pipeline activated (according to the hosting company).
When I go to the root of the web site, www.site.com, the default.aspx makes a redirect to a controller like so:
public void Page_Load(object sender, System.EventArgs e)
{
string originalPath = Request.Path;
HttpContext.Current.RewritePath(Request.ApplicationPath + "Controller.mvc/Action", false);
IHttpHandler httpHandler = new MvcHttpHandler();
httpHandler.ProcessRequest(HttpContext.Current);
HttpContext.Current.RewritePath(originalPath, false);
}
This works and the correct view is shown. However, when I type the same address in the browser, www.site.com/Controller.mvc/Action I get a 404.0 error. So it seems the MvccHttpHandler is not invoked correctly(?).
The web.config is set up with runAllManagedModulesForAllRequests="true", and a MvcHttpHandler is configured to handle .mvc extensions.
What am I doing wrong, any ideas?

Here's a good article which covers different deployment scenarios. There are no particular steps required when deploying to IIS 7 in integrated mode. You don't need a default.aspx file and association of MvcHttpHandler with the .mvc extension in your web.config. Here's how your routes might look like if you want to handle both extensionless routes in IIS 7.0 and the .mvc extension in IIS 6.0.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// This is for IIS 6.0
routes.MapRoute(
"DefaultWithExtension",
"{controller}.mvc/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
// The default extensionless route working with IIS 7.0 and higher
routes.MapRoute(
"Default",
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The .mvc extension is needed only for IIS 6.0:
<httpHandlers>
<add verb="*" path="*.mvc" validate="false" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpHandlers>

Turned out my hosting company did not run my application in integrated mode, even though they told me. Solved my problems, but I also got a few helpful tips from Darin.

Related

Static File Routes in ASP.NET MVC

I'm working on an ASP.NET MVC app. In this app, I need to dynamically generate the sitemap when its requested. I know how to configure routes in general. However, I'm not sure if I can create a route for a specific file. Currently, I have the following in RouteConfig.cs:
routes.MapRoute(
name: "Sitemap",
url: "resources/sitemap.xml",
defaults: new { controller = "Site", action = "Sitemap" }
);
In my SiteController, I have the following:
public ActionResult Sitemap()
{
// I will build my sitemap.xml file here and return it.
}
When I enter /resources/sitmap.xml into the browser's address bar, I noticed that my Sitemap() action never gets tripped. Is it even possible in ASP.NET MVC to setup a route for a specific file? If so, how?
Thanks,
So you got to do in some steps -
Step 1 - Map the xml extension to take care of by .Net for routing
Add following section in Web.config under <system.webServer> -
<handlers>
<add name="HtmlFileHandler" path="*.xml" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
Step 2 - Define your routes and override requests that match an existing file.
routes.RouteExistingFiles = true;
routes.MapRoute(
name: "Sitemap",
url: "{site}.xml",
defaults: new { controller = "Site", action = "Sitemap", site = UrlParameter.Optional }
);
then step 3 - Try to access /SiteMap.xml, you will get Controller action hit.

ASP.NET MVC 4 Catch-all only firing on local, not on remote requests

In an ASP.NET MVC 4 application, we have set up a catch-all route as follows:
routes.MapRoute(
name: "UnKnown",
url: "{*url}",
defaults: new { controller = "CatchAll", action = "UnknownUrl" });
The UnknownUrl method in the CatchAllController correctly loads its view in our development environment.
However, the production IIS 7.5 shows its standard 404 page if a non-existing remote request arrives. A local request, sent using RDP on the server itself, works fine.
The web.config is set tp
<customErrors mode="Off"/>
What other difference is there between a local call and a remote call? How can we make the MVC HttpHandler catch those requests?
A hint might be that we were also unable to make the IIS show any detailed status 500 error messages when called remotely.
I have had problems with IIS showing default errors instead of .NET errors, which I've fixed with the following in system.webServer in the web.config:
<httpErrors existingResponse="PassThrough"/>
I think this would happen if in your UnknownUrl action you are setting Response.StatusCode = 404;. By default IIS sees you are returning an error code so shows a default error message, which you can override with that config setting.
I'm not sure this would be different on local v remote but could be worth a try.
Can you try setting the host header - I believe this is what causes the difference between local and production:
new { controller = "CatchAll", action = "UnknownUrl", host = HttpContext.Current.Request.Url.Host}
Register this route from Application_BeginRequest of Global.asax. Also, ensure that this is done only once - perhaps by a check similar to:
if (routes["UnKnown"] == null)
{
routes.MapRoute(
name: "UnKnown",
url: "{*url}",
defaults: new { controller = "CatchAll", action = "UnknownUrl", host = HttpContext.Current.Request.Url.Host}
);
}

MVC route to capture file name as a parameter

I am attempting to produce a simple WebDAV server using MVC, and I have finally reached the stage where I need to serve up a requested file to the user.
I have a route set up that deals with traversing the directory structure "webdav/{*path}" which works fine, right up until the point where that path ends in a file name. At this point, it appears that IIS decides that it is a static file, and attempts to serve that file from the disk. As it isn't in the location specified in the URL, it returns a 404 error.
I don't have any freedom to change the url, I basically need it to be in the form, otherwise Windows Explorer can't work with it as a mapped drive:
GET /webdav/Test/Test2.txt
I've set the route to greedily match, as the directory structure can have as many levels. I've also set routes.RouteExistingFiles = true;
This is using IIS Express 8.0 on my development machine.
I've gone as far as setting up a blank MVC project just to test this, and this is the RegisterRoutes method:
routes.RouteExistingFiles = true;
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "WebDAVGet",
url: "webdav/{*path}",
defaults: new { controller = "WebDAV", action = "Get", path = "" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index",
id = UrlParameter.Optional }
);
So, going to /webdav/Test/Test2 hits the breakpoint in my controller, but going to /webdav/Test/Test2.txt gives me a 404.
Any suggestions?
I needed to add
<modules runAllManagedModulesForAllRequests="true">
to the web config.
Ah, I've been struggling with this for a few days now, I knew posting here would shift the blockage!
Another option is to add this to the <system.webserver> node in web.config:
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>
I can vouch that this works on IIS 7.5.
For the record, I found this solution here.

MS MVC Preview 2 and .NET 3.5 sp1

I have a site built with MVC Preview 2 and have not got around to upgrading to latest release, mainly because of the number of changes required and I have not had time. Anyway, last night my host installed .NET 3.5 sp1 and it killed my site. It is an identified problem (thats what you get for using pre betas) on this site http://haacked.com/archive/2008/05/12/sp1-beta-and-its-effect-on-mvc.aspx and it says to go to this site for a work around http://www.asp.net/downloads/3.5-SP1/Readme/default.aspx.
Unfortunately the work around seems to have been taken down. Can anyone shed some light of what it did say and what the work arounds are.
Maybe this instructions are useful, they are to migrate the site on mvc preview 2 to mvc preview 3. As preview 3 sites are not affected by the beta sp1, I hope it helps:
Upgrading an Existing Preview2 Application to Preview 3
The information in this section describes the changes you must make to modify an ASP.NET MVC application that was created with the Preview 2 release so that it works with the Preview 3 release.
Code Changes
Update the references to the following assemblies to point to the new Preview 3 versions of the assemblies:
System.Web.Abstractions
System.Web.Routing
System.Web.Mvc
By default, these assemblies are located in the following folder:
%ProgramFiles%\Microsoft ASP.NET\ASP.NET MVC Preview 3
For all existing action methods, change the return type from void to ActionResult.
Anywhere you call RenderView, change it to a call to return View. You can search for RenderView( and replace it with return View(.
Anywhere you call RedirectToAction, prepend the call with the return keyword. Search for RedirectToAction( and replace it with return RedirectToAction(.
If you use a strongly typed page, replace <%= ViewData.PropertyName %> with <%= ViewData.Model.PropertyName %>. Rather than replacing the ViewData object with your strongly typed object, the MVC framework now sets the Model property to the instance that you provide.
In the Global.asax file, remove the route definition for Default.aspx. In the default Preview 2 template, the route looked like the following example:
routes.Add(new Route("Default.aspx", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }),
});
In the Global.asax file, find the following default MVC route:
routes.Add(new Route("{controller}/{action}/{id}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { action = "Index", id = "" }),
});
Replace it with the following route:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
Add the following line at the very beginning of the RegisterRoutes method:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
Edit the Default.aspx file and add the following line:
<% Response.Redirect("~/Home") %>
This redirect is not necessary for IIS 7. This is a workaround for an issue with how the Web server that is built into Visual Studio (the ASP.NET Development Server) works with routing.
Configuration Changes
In the Web.config file, you must change the type attribute of the httpHandler entry in the section for UrlRoutingHandler to System.Web.HttpForbiddenHandler.
To do this, search for the following string in the file:
path="UrlRouting.axd" type="System.Web.Routing.UrlRoutingHandler, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
Replace it with the following string:
path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
Because the version numbers of the System.Web.Abstractions and System.Web.Routing assemblies have been changed to 0.0.0.0, you must update version information in the Web.config file. In the Web.config file, search for the following string:
System.Web.Routing, Version=3.5.0.0
Replace it with the following string:
System.Web.Routing, Version=0.0.0.0
Search for the following string:
System.Web.Abstractions, Version=3.5.0.0
Replace it with the following string:
System.Web.Abstractions, Version=0.0.0.0

ASP.NET MVC on IIS 6 - wildcard mapping - the incoming request does not match any route

I have been trying to set up my Beta 1 MVC app on IIS 6 and cannot get it to run correctly. I have added a Wildcard mapping to the .net isapi DLL as suggested in other blog posts but get the following error when I access the root of the website:
The incoming request does not match any route.
..
[HttpException (0x80004005): The incoming request does not match any route.]
System.Web.Routing.UrlRoutingHandler.ProcessRequest(HttpContextBase httpContext) +147
System.Web.Routing.UrlRoutingHandler.ProcessRequest(HttpContext httpContext) +36
System.Web.Routing.UrlRoutingHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext context) +4
HCD.Intranet.Web.Default.Page_Load(Object sender, EventArgs e) +81
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +33
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +47
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1436
I am using the Default.aspx page supplied in the MVC template application that rewrites access to the root of the website properly.
public partial class Default : Page
{
public void Page_Load(object sender, System.EventArgs e)
{
HttpContext.Current.RewritePath(Request.ApplicationPath);
IHttpHandler httpHandler = new MvcHttpHandler();
httpHandler.ProcessRequest(HttpContext.Current);
}
}
If I try and access a route within the application, such as /Project, I get the standard IIS 404 error page, not the .net error page.
I tried adding the following line to my Web.config httpHandlers section:
<add verb="*" path="*" validate="false" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
This gave me a different error - the .net 404 error page.
I added the following to my Global.asax, which did nothing:
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (Context.Request.FilePath.Equals("/"))
Context.RewritePath("Default.aspx");
}
I am using the following route configuration (uses the restful routing supplied by the MvcContrib project):
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
SimplyRestfulRouteHandler.BuildRoutes(routes);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
Any suggestions would be grealy received as I've exhausted all options for the time I have right now.
Many thanks.
Here's what I did to get extensionless URLs working with IIS 6 and ASP.NET MVC Beta 1.
Create a default ASP.NET MVC Beta
project and compile it.
Create a new IIS website pointing to
the application directory.
In the IIS properties for the
website, click the HomeDirectory
tab.
Click the "Configuration..." button.
In the "Mappings" tab, click
"Insert..."
Next to the "Wildcard application
maps" label In the textbox, type in
"c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll"
Uncheck the box labelled "Verify
that file exists" Click OK
Navigate to /home It worked!
You shouldn't need to change web.config at all. You just need to map all requests to IIS to the ASP.NET Isapi dll otherwise ASP.NET will never get those requests.
OK, got it working.
The problem was that I was using msbuild automation to package up the files that I needed to deploy, and I was missing global.asax.
So it looks like if global.asax is not deployed to the site then none of the routes get hooked up. This means that hitting the website root correctly results in the error 'The incoming request does not match any route.', and any other requests no longer get routed through to your controller classes, so result in a 404.
HTH.
Unfortunatly IIS 6 needs a file extension to map the request to the right handler which means you will have to use the .mvc suffix on your controller names, such as /{controller}.mvc/{action}
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
SimplyRestfulRouteHandler.BuildRoutes(routes);
routes.MapRoute(
"Default",
"{controller}.mvc/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
However, the are ways around this depending on your level of control on the IIS 6 server. Please refer to the following pages for more information
http://biasecurities.com/blog/2008/how-to-enable-pretty-urls-with-asp-net-mvc-and-iis6/
http://www.flux88.com/UsingASPNETMVCOnIIS6WithoutTheMVCExtension.aspx

Resources