ASP.NET MVC, Custom VirtualPathProvider and IIS6 - asp.net-mvc

I have implemented my own VirtualPathProvider for loading 'embedded' views.
This works very well when running from Visual Studio, but I get the 'The view not found' message when running on IIS6.
Is there anything missing in web.config, or could there be any other problem?
I have added some logging and it seems that even though I register the Custom VirtualPathProvider in Application_Start, the System.Web.Hosting.MapPathBasedVirtualPathProvider is still used.

For the combination Custom VPP + IIS6 + Precompiled site, we need to add the VPP from AppInitailize();
public static class AppStart
{
public static void
{
// code to be executed automatically by the framework
}
}
See also:
http://sunali.com/2008/01/09/virtualpathprovider-in-precompiled-web-sites/

Is yours not used at all? VirtualPathProviders operate in a stack so, in your VirtualPathProvider, you should notice that the base class member "Previous" is actually the instance of "MapPathBasedVirtualPathProvider".
If you:
Attach your debugger to IIS
Make a change in your web.config, then change it back, then save (to trigger an recycle) - while still attached!
Place a breakpoint in your VPP in FileExists
Hit a page
Does your VPP get hit? If so, it may be an issue that after the first request, MVCs ViewEngine caching is preventing your VPP from getting hit for additional requests...

Related

MVC 6 with vNext: Do we still need the Global.asax?

I'm developing an application using MVC6.
I noticed that the Global.asax file disappeared by default there is startup.cs file that calls the config. My question is how do I grab the Application_Start event method ?
Do I still need the Global.asax ?
Why has it been removed by default ?
Global.asax is only present when there is a reason to hook into it. The default MVC6 project has no hooks into it, therefore it doesn't provide one. Just add new item, global.asax
I should also suggest, that I would avoid creating a global.asax unless you need absolutely need it. People tend to reach for Application_Start or Session_Start first when there are probably better places to do what you need to do. Consider creating an OWIN module, or consider adding your own Startup module.

MvcSiteMapProvider causing authorization issues with MVC4 website

I'm trying to implement MvcSiteMapProvider with my new MVC4 website, but I've run into something that I can't seem to fix.
I setup authorization with Active Directory (no role provider currently), and everything was working as it should. When you try to get to any page other than the login page, you're redirected to the login page. The Account controller's action methods have the [allowAnonymous] attribute to allow unauthenticated users to access them so that they can login.
For some unknown reason, adding MvcSiteMapProvider to the project stops this from working and now unauthenticated users can get to any page. The Menu that MvcSiteMapProvider creates works correctly and only authenticated users can see it, but if the unauthenticated user types in a direct link they aren't redirected to the login page as they used to be.
I've removed MvcSiteMapProvider from the project and authentication started to work correctly again.
I believe this has something to do with MvcSiteMapProvider overridding the authorizeAttribute filter in some way, but I can't figure out where/how.
I can put [Authorize] on top of the controller and the redirect works with MvcSiteMapProvider, but that's against the whole reason for using MVC4.
//this is supposed to set authorize for the entire app
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new System.Web.Mvc.AuthorizeAttribute());
}
I have a feeling this issue is coming from MvcSiteMapProvider/External/AuthorizeAttributeBuilder.cs, but I'm not experienced enough to figure this out.
UPDATE:
Turns out that I had just setup my global filters incorrectly. For some reason that RegisterGlobalFilters method was in my global.asax file, so my FilterConfig.cs file didn't have the line:
filters.Add(new System.Web.Mvc.AuthorizeAttribute());
I removed the method from my global.asax file then updated the FilterConfig.cs file with the above filter and everything is now working as expected. Not sure how I got into this situation, but I'm glad I figured it out.
Someone on the mvcSiteMapProvider GitHub project had mentioned that he had MVC4 and mvcSiteMapProvider working seamlessly, so I created a new MVC4 app and added the mvcSiteMapProvider before making any changes and then added the authorize global filter. Everything worked as expected, so I compared projects and found where I had gone wrong. Hopefully this info helps someone, but I doubt it as it's a pretty unique case.
Turns out that I had just setup my global filters incorrectly. For some reason that RegisterGlobalFilters method was in my global.asax file, so my FilterConfig.cs file didn't have the line:
filters.Add(new System.Web.Mvc.AuthorizeAttribute());
I removed the method from my global.asax file then updated the FilterConfig.cs file with the above filter and everything is now working as expected. Not sure how I got into this situation, but I'm glad I figured it out.
Someone on the mvcSiteMapProvider GitHub project had mentioned that he had MVC4 and mvcSiteMapProvider working seamlessly, so I created a new MVC4 app and added the mvcSiteMapProvider before making any changes and then added the authorize global filter. Everything worked as expected, so I compared projects and found where I had gone wrong. Hopefully this info helps someone, but I doubt it as it's a pretty unique case.

Creating a custom error page for asp.net MVC 3, need to disable http modules

I've a MVC 3 web application using WIF (only thing that matters here is that it's a http module and integrated into the processing pipeline), I've added in normal error handling via global.asax.cs's application_error handler. This works well for most of the cases where the basic application is up and running.
however, there is a class of errors where if the web.config is not configured correctly. (i.e. after a fresh install), the http modules, i.e. WIF assemblies throw exceptions.
I'm trying to put a custom error page for that as well to ask the user to look at the configuration,
however, any page hosted on the same website, even for static html still goes to the standard asp.net error page. My guess is that its still invoking the modules for static pages. Any one have idea on how to disable the httpmodules for certain areas or what the standard practice is?
This is how i'm configuring the custom error page
<customErrors mode="RemoteOnly" defaultRedirect="~/error.htm">
it's a simple static html page. page loads fine when the website is configured properly, but does not show when there is a http module level problem.
You can specify default websites setting in machine.config file. And even protect them from overwrites.
The machine.config file is located in x:\\Microsoft.NET\Framework\\config\machine.config
So if after deployment web.config file will be broken (or some settings) - proper settings will be taken from machine.config.

Exceptions in N2cms page

i'm using n2cms + asp.net mvc,
when the site is uploaded to a webserver, and an exception is thrown in the aspx page, the page appear blank, and there is nothing in the page, even if i turned off the CustomErrors in web.config
but when the site is running on my computer visual studio simply show me the exception,
is there a way to catch the exception in this situation?
This may be due to your hosting configuration. You could take a look at ELMAH for an easy way of logging exceptions.
You can handle all global errors in your Global.asax's method called Application_Error - http://msdn.microsoft.com/en-us/library/24395wz3.aspx . It will work for simple cases. But I strongly recommend to use ELMAH
N2CMS makes calls to SwallowExceptions(). This is why you are receiving a blank page instead of an exception. You could look for that method call and comment it.

Why does not the Application_Start() event fire when I debug my ASP.NET MVC app?

I currently have the following routines in my Global.asax.cs file:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Arrangement", action = "Index", id = "" }
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
// Debugs the routes with Phil Haacks routing debugger (link below)
RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
}
Routing debugger...
When I hit F5, the application fires up and unless I have a view named Index.aspx in the ~/Views/Home/ folder, I get the "View missing" error message, although I have re-defined the default route and removed the HomeController. I would expect to get the routing debugger, and if not that at least a request for ~/Views/Arrangement/Index.aspx.
A breakpoint on RegisterRoutes(Routetable.Routes); is never hit when debugging.
I have tried building, rebuilding, restarting VS, cleaning, rebuilding again etc, but nothing seems to work. Why doesn't the application run the current version of the code?
I found the following answer on forums.asp.net:
Are you using IIS7 as the server or the built-in web server? I noticed when using IIS7 that if you start the debugger, let a page come up, then change Global.asax (the markup file, not code-behind) while the debugger is still running, then refresh the page, breakpoints in Application_Start will be hit.
I think what's happening is that pressing "play", VS just fires up the process, then attaches to it, but by the time it attaches to it the start event has already run. By changing Global.asax, you cause the app to restart and since the debugger's already attached you can hit the breakpoint. Not a great solution, but it seems to work.
Thats's what was happening in my case.
Add a System.Diagnostics.Debugger.Break(); to Application_Start().
This will force a breakpoint.
This line should be commented out to avoid the breakpoint to happen and #ifdef debug to get sure never gets to production.
NOTE: this is a problem with IIS. Since I wrote this answer, things have changed, and you can avoid doing this by using other servers, like IIS Express.
The problem is Application_Start() triggers first then the debugger attaches.
So the goal is to do something that would cause Application_Start() to trigger again while its still running. For debugging purposes, just run the debugger like you normally do then edit (eg add a newline) and save the web.config file.
I believe you have to shutdown/stop the local debugging server in order for the Application_Start() event to fire again... you should be able to right click on it in the system tray and choose "Stop".
I hit with the same problem today and was using Local IIS.
I believe this arises because because of the way page is loaded.
All you need to do is, put a breakpoint in Application_Start. Run the application(In my case, it took to Login Screen ) and then go to web.config. Edit it - by adding some spaces. and then refresh in Browser.that will hit the breakpoint on Application_Start.
I found the problem:
This MVC application was part of a larger solution, in which I had at one point set another project to build for an x86 environment (I'm running x64). When I did that, apparently all other projects - even those added later - were set not to build on Ctrl+Shift+B, and I suppose that's why the debugger didn't hit my breakpoint.
Solution:
Go into the solution build properties (right-click Solution, select properties, and select Build on the menu on the left), and put a check in the Build checkbox next to the project name in the list.
In my case the problem was between chair and keyboard - after renaming mvc project assembly, I forgot to update Global.asax to point to the correct class. So check the "Inherits" in Global.asax (in visual studio right-click on Global.asax -> View Markup)
<%# Application Codebehind="Global.asax.cs"
Inherits="Monster.MgsMvc.Web.MvcApplication"
Language="C#" %>
if it really matches your Global.asax.cs class/namespace declaration
In my case was I using
Local IIS Web server in web project settings
and I change to Use Visual Studio Development Server, and this works.
Below technique worked for me:
Simple workaround is to touch global.asax after the debugger is attached in order to force an application recycle. Then during the next request, the break point that you set on Application_Start will be hit.
I found this here: http://connect.microsoft.com/VisualStudio/feedback/details/634919/cannot-debug-application-start-event-in-global-asax
Maybe my solution will help someone:
Stop the debugger.
Update the RegisterRoutes code (example - add\remove int i = 1;).
Rebuild.
Place a break point in RegisterRoutes.
I've just had this problem and swapped from Local IIS to IIS Express in project properties -> web to sort it out
project -> property -> web
check "Native code".

Resources