How does IIS server identify that request is mvc request? - asp.net-mvc

In asp.net life cycle, on basis of the extension (.aspx), the request would be identified and handled by aspnet_isapi.dll and then httpapplication object is created followed by request and response objects and then request is processed by ProcessRequest() method.
I was going through mvc page life cycle
I have doubt about how the IIS server is able to identify the incoming request is MVC request?

Both the answers with some research I did, collectively resolves my question.
Step 1:
From the below mentioned article #1 (which I found during my research):
From a very high view, IIS is just a process which is listening on a
particular port (usually 80). Listening means it is ready to accept a
connections from clients on port 80. A very important thing to
remember is: IIS is not ASP.NET. This means that IIS doesn't know
anything about ASP.NET; it can work by itself.
Step 2:
Note: When we deploy and start the application in IIS, it would call Application_Start which would register the routes.
So, when MVC request comes to IIS, we are ready with our Route Table to handle this request.
Step 3:
As mentioned by #Babin, IIS doesn't know how to handle the request but because of ASP.NET framework, the request automatically goes to managed handlers.
Step 4:
As mentioned by #Rune, the request is intercepted by the UrlRoutingModule which in turn gets object of MvcRouteHandler class that will ultimately map to controller and action to handle the request.
Step 5:
As mentioned in one of SO question's comments:
If no routes match, the UrlRoutingModule object does nothing
and lets the request fall back to the regular ASP.NET or IIS request processing.
References:
I found good articles to read through and clear out the doubts in IIS request processing.
1) The following link has in-depth explanation for how IIS handles ASP.NET WebForms request:
http://www.codeproject.com/Articles/121096/Web-Server-and-ASP-NET-Application-Life-Cycle-in-D
2) The following links explains how IIS handles MVC requests using managed handlers:
http://blogs.msdn.com/b/tmarq/archive/2010/04/01/asp-net-4-0-enables-routing-of-extensionless-urls-without-impacting-static-requests.aspx
3) MVC Lifecycle:
http://pratiktips.blogspot.de/2012/08/the-magic-of-aspnet-mvc-model-binding.html

IIS 7+ can run in two pipeline modes: "Classic mode" and "Integrated mode". The latter mode means that ASP.NET sees all incoming requests and can handle / manipulate them.
If you are asking how ASP.NET knows to invoke MVC, that is described in step 4 of the diagram you linked to: The UrlRoutingModule matches the request against all registered routes. When using MVC, you will have registered a route with a MvcRouteHandler. From MSDN:
A MvcRouteHandler instance is registered with routing when you use the MapRoute method. When the MvcRouteHandler class is invoked, the class generates an MvcHandler instance using the current RequestContext instance. It then delegates control to the new MvcHandler instance

IIS doesn't know; ASP.NET knows via HTTP Handlers
Both WebForms and MVC are built on top of ASP.NET, and both use HTTP Handlers to deal with per-request execution:
WebForms has .aspx files mapped to the PageHandlerFactory: PageHandlerFactory implements IHttpHandlerFactory::GetHandler() returns HttpHandler
MVC integrates into the Routing infrastructure as an IRouteHandler implementation. Routes is notified of requests via the UrlRoutingHandler URLRoutingHanlder implements IHttpHandler. ASP.NET MVC is just a custom handler added to the ASP.NET pipeline.
Below is MVC 4.0 & ASP.NET 4.0 onwards These rules can be defined at any level in IIS. Most MVC applications define the handlers at the application level in the web.config file
<handler>
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit"/>
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0"/>
</handlers>

Related

How and is it possible to have one Mvc and one webapi project operating under same domain name

I have two separate projects
http://www.local.mysite.com (mvc websites)
http://api.mysite.com (webapi)
I'd like to avoid using CORS, (currently required for my web ajax calls) (as they are across origin).
So could I in theory, host the webapi under the same domain, using a suffix:
http://www.local.mysite.com/api ? (with an IIS binding to this for the api)
Would this work? My concern is the Mvc website will intercept the requests also, or that maybe it is a bit dodgey.
CORS is involved when you're making Ajax call cross-origin. Origin is defined by 1) host, 2) port, and 3) protocol.
Here's a good article that discusses the protocol:
http://msdn.microsoft.com/en-us/magazine/dn532203.aspx

How does IIS recognize that request is for MVC Controllers or webforms Pages?

When the Application pool receives a request, it simply passes the request to worker process (w3wp.exe) . The worker process “w3wp.exe” looks up the URL of the request in order to load the correct ISAPI extension. ISAPI extensions are the IIS way to handle requests for different resources. Once ASP.NET is installed, it installs its own ISAPI extension (aspnet_isapi.dll) and adds the mapping into IIS.
Si If that's true, my question is how does it recognize which extensions to be loaded
for that request?? MVC / Web Forms?
When and where does the IIS come to know that a request is for MVC or WebForms Application?
How framework decide which Modules should handle the request and decide to render page content or views in MVC.
hen and were the IIS come to know that request is for MVC or WebForms Application?
They are both ASP.NET applications so it doesn't need to recognize that. The aspnet_isapi.dll is perfectly capable of serving both types of applications (which are actually a single type called ASP.NET).
ASP.NET MVC is just a custom handler added to the ASP.NET pipeline.
That all is about the standard IHttpModule and IHttpHandler infrastructure. See complete description here Routing with ASP.NET Web Forms and here How ASP.NET MVC Routing Works and its Impact on the Performance of Static Requests

Design of a web application with ServiceStack

After getting an advice about using ServiceStack for my asp.net MVC website
(Maintaining state in Asp.Net MVC website), I started implementing it in my project - but some stuff is still unclear for me.
Currently I have two projects: one is the asp.net MVC project and the other is the BL project (a class library that holds all the business logic).
All controllers in the MVC project make calls to classes/functions in the BL project.
For now, the mvc project loads the BL's DLL, but in the future when the website will grow, the BL's project will run on separate machines.
I would like to use ServiceStack for session management/caching and authentication (which both of them usually depended on each other).
My questions:
1) Is it possible to use only these two features without the functionality of message based web service? ServiceStack need to be initialized, and it throws me an error when initialized twice (in both projects).
2) Is it possible to split the implementation of ServiceStack between the two projects? I would like to maintain the process of authentication in the BL project using the ServiceStack's authentication providers, but handle all the UI/cookies by myself (or with the help of ServiceStack) in the mvc project.
3) I would like to use ServiceStack's caching in the BL project, but I guess that I still need to maintain some session cookies to receive the session id. What is the right way to do it? Are there any built-in helper functions for this purpose?
Thanks in advance!
1) Is it possible to use only these two features without the functionality of message based web service? ServiceStack need to be initialized, and it throws me an error when initialized twice (in both projects).
If you install the latest ServiceStack.Mvc NuGet package you will get the base ServiceStackController which is an MVC Controller providing convenient access to ServiceStack's built-in providers. Although you still need to auto-wire your controllers with the dependencies it needs, e.g. an injected ICacheClient.
Although even if you're not using ServiceStack's WebFramework, having an AppHost is a convenient place to register your dependencies. ServiceStack is triggered by ASP.NET's IHttpHandler mappings specified in the Web.config, so if you don't have any mappings specified ServiceStack is never able to be called externally, but the registered dependencies are still able to be accessed internally with:
var cache = AppHost.Resolve<ICacheClient>(); //Get ICacheClient for SS IOC
2) Is it possible to split the implementation of ServiceStack between the two projects?
If you do have an AppHost, you cannot have more than one instance in a host project (by design) since an AppHost should be analogous to a host project where all your service dependencies should be registered and settings configured that apply to your entire web application or service.
You can however split the implementation of your services across multiple assemblies and have ServiceStack scan them all by specifying them in your AppHostBase constructor, e.g:
public class AppHost : AppHostBase
{
public AppHost() : base("My Service",
typeof(AServiceInDll1).Assembly, typeof(AServiceInDll2).Assembly/*, etc.*/){}
}
2) cont. I would like to maintain the process of authentication in the BL project using the ServiceStack's authentication providers, but handle all the UI/cookies by myself (or with the help of ServiceStack) in the mvc project.
Look at the ServiceStack.UseCases CustomAuthenticationMvc example project for an example of using MVC but authenticating with ServiceStack.
3) I would like to use ServiceStack's caching in the BL project, but I guess that I still need to maintain some session cookies to receive the session id. What is the right way to do it? Are there any built-in helper functions for this purpose?
You can use any of ServiceStack's Caching providers just like any other C# class, i.e. have your Business Logic binded to ICacheClient and inject the concrete implementation in your IOC.
For sessions you can use the base.SessionAs<T> method in the ServiceStack.Mvc ServiceStackController to access the session. To Save back the session you can use the IHttpRequest.SaveSession() extension methods. Although both these methods require the ASP.NET context (it uses ASP.NET's HttpContext singleton if not provided) to work since it relies on ServiceStack's ss-id/ss-pid cookies that are automatically instructed to be added on the client (by the server) whenever you access the Session.
If you don't want your business logic services to have a dependency on ASP.NET's System.Web I recommend accessing and saving the session to be done in your controllers and passed to your business logic.
I recommend reading the Sessions Wiki Page for more background info on how ServiceStack's sessions work.
Integration of ASP.NET Context between ServiceStack and ASP.NET or MVC
I'll add this info since it's useful for anyone doing advanced integration between ServiceStack and ASP.NET or MVC as some of ServiceStack's extension methods rely on these built-in types.
You can create a ServiceStack IHttpRequest or IHttpResponse (within any HTTP/Controller request) with:
var ssHttpRequest = System.Web.HttpContext.Current.Request.ToRequest();
var ssHttpResponse = System.Web.HttpContext.Current.Response.ToResponse();
Finally you can create a complete request context (that encapsulates both a IHttpRequest and IHttpResponse) with:
var ssRequestContext = System.Web.HttpContext.Current.ToRequestContext();
Not sure I fully grasp your questions and how you would like to split the projects across multiple servers. I'll try my best to answer your questions...
Is it possible to use only these two features without the functionality of message based web service? ServiceStack need to be initialized, and it throws me an error when initialized twice
It seems like you're trying to run 2 instances of ServiceStack (maybe even 2 websites) within one solution (one in your web project and once in your BL layer). I don't think that's possible. Your BL layer can share ServiceStack libraries and you can configure (within AppHost.Configure method) those in your web project that references your BL project.
Is it possible to split the implementation of ServiceStack between the two projects?
I think the answer is yes, but you would have have one instance of ServiceStack used by both the projects. This would share the Session state across the projects. There might be a way to have two projects with there own instances of ServiceStack...see https://github.com/ServiceStack/ServiceStack/wiki/Self-hosting.
I would like to use ServiceStack's caching in the BL project, but I guess that I still need to maintain some session cookies to receive the session id.
If ServiceStack is being used across both projects you can access all session data in UserSession (https://github.com/ServiceStack/ServiceStack/wiki/Sessions). If you MVC Controllers inherit from ServiceStackController you can use SessionFeature.GetSessionId() to get the session Id. In your ServiceStack Service (classes that implement Service) you can get the session data from using base.Session.
Hope this helps.

Database driven asp.net MVC application

I have a CRUD application written in Classic ASP (not .net) which transfers (routes) page requests to relevant servers using a loadbalancer DLL.
It works like this:
Someone requests for www.mywebsite.com/products
There is an index.asp under folder products that redirects the request to either:
http://www1.mywebsite.com/products
or
http://www2.mywebsite.com/products
based on a loadbalancer logic.
Another scenario:
Someone requests for www.mywebsite.com/products/details
There is a index.asp under the sub folder details within the products folder that redirects the request to either:
http://www1.mywebsite.com/products/details
or
http://www2.mywebsite.com/products/details
based on loadbalancer logic
The main issue with application is whenever I include a new page, I need to create a folder and index.asp page to redirect the page.
We have a CMS database which contains the details of all pages. So I want to create an MVC application to replace the existing Classic ASP application.
But I didn't find any database driven MVC applications and I'm bit confused by routing. Do I need to create a separate route for each main folder I have or should I create a generic route for all pages.
Any help would be appreciated.
You don't have to migrate to ASP.NET MVC just for the URL rewriting.
IIS 7 does have an integrated URL rewrite module and ASP.NET 4 includes routing as well.
IIS URL Rewriting and ASP.NET Routing
URL Rewriting in ASP.NET
Anyhow, if you search e.g. on Codeplex for ASP.NET MVC projects, you'll find a lot of them which are database driven.
You don't need to create individual routes for each seperate item. Think about the concept of querystrings (?id=15&day=monday). URL rewriting is pretty much the same.
Update
I've overseen that your talking about classic ASP.
The build in URL rewrite module in IIS 7 works also fine with classic ASP. If you are having an older IIS version you need a 3rd party ISAPI rewrite module.
Anyhow, switch it to ASP.NET MVC ;)
MVC would lend itself very well to sorting your routing problem. So would ASP.NET 4.
However, the problem you have is that you don't know enough to ask a precise question. Hence your confusion with routing in MVC.
I would therefore suggest reading the nerddinners tutorial. You can get a PDF download for free. To go a step further, read Stephen Sandersons book on MVC 2 (or MVC3 in a couple of months).
If you follow the nerddinners tutorial and Stephen Sanderson's tutorial, that will give you a better idea of how it works.
In short, this is how MVC works:
In MVC, you forget about files and folders.
Instead, you have Controllers and actions. The routes map the requests to the right controller and action.
The code in the actions then decide which View to stuff full of data (from a database or wherever, it doesn't matter). The Views are just templates that are told what to do and what data to display.
The Controllers ask the Model for the data that they want.
Ie, the data access is all done in the Model, neatly separated from the User Interface.
M: Model
V: Views
C: Controller
The above is probably meaningless to you. It is a VERY different mindset to ASP classic.
If you are coming from old ASP, you will have a long hike, but it can be done. I came from Access. Anyway, read the books, follow the tutorial and see if it is for you.
When you are ready, we will still be here to help with more precise questions.
Asp.net MVC routing in your migrated application
Based on requests you've shown here you can sort everything up with just default route:
{controller}/{action}/{id}
In your case you'd have a ProductsController with all the actions you need.
Load balancing application
But having an Asp.net MVC application is just one part. This application will run on both load balanced servers. All redirecting should be done before they hit the MVC application.
If you intend to continue using the same loadbalancer DLL you could create a different Asp.net MVC application with only one route definition:
{*path}
and a single controller and action that does it all:
public Load: Controller
{
public ActionResult Balance(path)
{
// decide for web server and attach path to subdomain
}
}
This should do the trick just fine as long as the overhead of this action is very small. Otherwise your load balancing logic will become the bottleneck of your application since all requests go through this load balancer (it does that now as well so bare in mind this is no different now; never mind the authentication process on different subdomains you may be using).
Load balancing alternative
You should consider using the web farm balancing capabilities on the IIS 7 that will run your application on several web servers (because that's what your load balancing does in the first place). Search the web for web farm information. You can start with this:
http://www.iis.net/download/webfarmframework

MVC2 + ASP.NET 4.0 + IIS6 + extensionless URLS, no longer need wildcard mapping?

I noticed that asp.net 4.0 now installs a top-level isapi plugin (in iis6), such that it can inspect every request coming to the server. Should this now allow us to run MVC applications with extensionless URLS and have the aspnet isapi process them correctly without requiring the wildcard mapping (and avoid the performance penalties associated)? I havent found anything written about this yet, and havent had time to investigate. Thanks
ASP.NET 4.0 installs the C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll ISAPI filter in order to map incoming request to the new CLR, but this filter is not registered as wildcard mapping but is associated only with known extensions. It does not intercept every incoming request. If you want to have extensionless urls you will need to perform the same steps as for ASP.NET 2.0 but use the new ISAPI filter instead.
found the answer:
Link
appears that there are new features in asp.net 4.0 that enable extensionless urls. I need to do more research on this to find out how to utilize it.
Basically it appends /eurl.axd/GUID to each routed request, which then gets passed to aspnet_isapi.dll to be processed. the eurl.axd is then removed at this point.
The problems Im having is how these interact between my Ionics rewriter IIRF software and this new .net rewriting... they seem to be interfereing with each other at times.

Resources