ASP.NET detection of HttpHandler MVC vs. WebForms - c#

I'm trying to understand and learn the architecture and pipeline of ASP.NET. So far I understand the architectural overview:
on how we get from client to the IIS webserver (request)
via ISAPI extension to the ASP.NET runtime
from there on into the HTTP Pipeline
and ASP.NET calling the HttpModules and HttpHandler
in case of using MVC, selecting the MvcHandler
which is returned by the MvcRouteHandler
etc etc
Now what I don't understand (or can't find any resource on the web documentating this part), is how does the asp.net runtime detect which HttpHandler it has to select for it's request? So how does it know based on my Visual Studio solution that it's an MVC application for example? How does it figure it out that it should use the MvcHttpHandlers? Is there an assembly scan with Reflection somewhere in the HTTP pipeline? Because it certainly isn't a configuration telling the runtime to use the MvcHandler, or is it?
So basically at what exact point is the HttpContext.CurrentHandler being set?

Application_Start
When the request arrives to IIS and the endpoint corresponds to an
Asp.Net application, then the first event raised is the
Application_Start in the System.Web.HttpApplication object.
RouteTable.Routes.Add
Into this event of an Mvc app you can set the routing rules that do
match endpoint urls with Controllers and Actions methods
in the application and the relative IRouteHandler object type,
that will be typeof(MvcRouteHandler).
(see Scott Guthrie post)
HttpApplication.MapRequestHandler
Therefore, soon after that, when the routing table has been setted up,
in the subsequents events (or better in the methods that compose the
pipeline orchestrated by the Asp.Net Framework under IIS control
(integrated pipeline)) of the Asp.Net http request management,
when it needs to know how to manage the http request itself
(HttpApplication.MapRequestHandler), it get parsed the url in
the HttpContext object against the rules in the routing table,
and when it get found a matching, it is instatiated the right type of
its handler, MvcRouteHandler in our case, which will return the
IHttpHandler object by the method GetHttpHandler(RequestContext): MvcHandler .
(see Msdn MvcRoutHandler.GetHttpHandler)
MvcHandler.ProcessRequest
MvcHandler in turn, will give start to the real MVC request handling
through the Asp.Net pipeline event ProcessRequest: and so will
be instatiated the right Controller through the
ControllerFactory, and will be called the Execute method of the Controller abstract base class of the instatiated
controller object, and finally the right Action through the
ActionInvoker.
(see Msdn MvcHandler.ProcessRequest, and The Asp.Net Mvc pipeline)
final note on RouteCollection.MapRoute The Visual Studio starter template for MVC projects creates project that use MapRoute extension method
instead of RouteTable.Routes.Add. This method is very useful
because avoids to have to use always typeof(MvcRouteHandler)
expression when adding new url routing to the project.
(see Asp.Net Routing and Asp.Net Mvc)

Related

How to delete a specific cookie on startup, using .net core 2?

I need to delete a specific cookie when my app starts, before heading to home page.
I had this inside a controller action method, with a redirect to home page, setting up my startup class to use as route template this controller and action method.
However, there must be a way I can set up a method to delete this cookie, and execute it from startup?
In ASP.NET, this would be done in the methods of global.asax (often in Session_Start(...)). Read more here and here.
In ASP.NET Core, the startup.cs class is where all configurations of services are defined, as well as pipeline requests are managed.
You need to make your own custom middleware for this. Middleware is software that's assembled into an app pipeline to handle requests and responses.
There is another SO question on this topic here (with an answer):
ASP .NET Core webapi set cookie in middleware
For more in-depth cookie management look at this article:
https://www.seeleycoder.com/blog/cookie-management-asp-net-core/
More on middleware:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-2.2

Separate MVC application as a folder using Handler Mapping

We have a legacy webforms app and a new section of our site developed with MVC. It works a treat as an application in the Default Web Site in IIS.
Only downside is that the root site's session object isn't passed to the application. We have a work around for this.
A consultant is convinced that we don't need to set it up as an application and it can all be done via handlers and route mappings. He conveniently has not provided us with any details though and I have been tasked to implement it.
The best I have achieved was to add a Module Mapping to the Handler Mapping section in IIS. This filters coolmvcapp/* with Module isapimodule to a virtual directory who's physical path points to our new MVC app. The result is an empty page with a 200 response. Most other combinations I have tried resulted in a variety of errors. (Turns out an empty page is returned without adding the handler mapping - hey ho)
So, is this approach even possible?
I am aware that MVC and webforms can be merged together but for reasons this is something that we want to avoid.

ASP.NET WebApi specify action

I need to create ASP.NET WebApi with couple operation, for example RegisterAppStart, RegisterStep and RegisterAppEnd. And I want to place all this actions in one controller. As I read, usually in WebApi action name is not using.
And my question - is this a bad idea to rewrite default route config with actions using?
ps. sorry for my English
You can give actions arbitrary names using the [Route("/api/FooController/BarMethod"] attribute routing.
This usually overrides the "REST"yness of your service (where the request method indicates which method should be called), but as you aren't really building a REST service, you shouldn't care.

Request to a IIS server (when ASP NET WebForms + MVC co-exist)

Well, there are many questions on SO which proves that you have the possibility to hold both ASP WebForms as well as ASP NET MVC Applications running together.
Note:
In MVC, What happens ? The short answer is Every requests to the webserver first goes through aURLRoutingModule object which reads the request and performs route-selection (depending upon global.asax file). The MvcRouteHandler then handles the controller method invocation.
That is okay.
All I am trying to understand is what happens when a user sends a request to the browser when the web server contains both Web-Forms as well as an ASP.NET MVC Application.
Who reads the URL and understands whether it is an .aspx extension or it is a request to mvc ?
How exactly the ISAPI.dll function in this case?
It's actually fairly simple: the URLRoutingModule checks the disk to see if there is a physical file which matches the current request URL. If there is a match, the Routing module assumes that it shouldn't run for this request, and ASP.NET's default behavior is then to look up and invoke the default handler for this extension. In the case of .aspx, that would be the Web Forms handler.
You can change this via the RouteCollection.RouteExistingFiles property in your RegisterRoutes method. This property controls whether the Routing module should intercept the request regardless of whether there is a physical file on the hard drive.
To understand better what happens when a user sends a request to the browser when the web server contains both Web-Forms as well as an ASP.NET MVC Application is by knowing on how ASP.Net runtime perform the Url routing which it is actually done by the ISAPI filter plugin.
Below are the detailed steps for Webform request:
1) When user enter a url like website1.com/page1.aspx in the browser.
2) Browser will send a Get Request to the IIS server asking for Page1.aspx file.
3) Then ISAPI filter is the first process to access the Http data before IIS can start to do anything. Here it act like a router for IIS request.
4) ISAPI filter will then check the url whether the filename has any extension (.aspx) and check whether the (.aspx) extension is mapped to the aspnet_isapi.dll or not.
5) If ".aspx" is mapped, it will invoke the ASP.net UrlRoutingModule and mapped the HttpHandler for ASP.net files.
For MVC request:
1) It follow the same step like webform request until the ISAPI filter found that there is no filename and file extension exist in the Url since MVC Url only contain the controller and action name.
2) All Url need to be mapped to a handler when the request initially received because routing will not work with unmanaged handler request
3) To direct this unmanaged request to managed code, it can be done by setting wildcard mapping to aspnet_isapi.dll for IIS6. For IIS7, we can just set the runAllManagedModulesForAllRequest="True".
4) Then only ASP.Net UrlRoutingModule will be invoked and try to match the Url with the application defined route.
5) If there is a match, it will direct to HttpHandler of Asp.net MVC framework. But if there is no match, the default Asp.net webform mapping will be used and most likely the request will return a HTTP 404 error result.
For more details you may refer to this web:
Mixing Web Forms and ASP.NET MVC
Web Server and ASP.NET Application Life Cycle in Depth

Restfull urls for ASP.NET page on IIS

Ok I had a huge Issue giving this a proper title, my excuses for that.
Anyways I have started slowly to look at Web and ASP.NET again, I am a C# developer but I have mostly worked with Windows applications the past 5 years or so, It is not that I haven't touched the web as such in that time, but this is as web services (Restfull as well as the ugly SOAP services) I have also worked with more "raw" web requests.
But I have not worked with IIS or ASP.NET in all that time.
What I would like to do is hos a web page that uses a URL style I could best describe with "like rest", hence the "Restfull urls" title. Because I think most people thinks of such URL's in terms of:
http://example.com/item/
http://example.com/item/23/
and so forth. Not that they have to look like that, however I would like to use such URL's instead of
http://example.com/item?id=23
I know subtext does this, but i have not had any luck finding it in their code base.
Now as far as I can tell I could just implement some IHttpHandler's, but at least for the examples I have seen of that, they write the page source back in code, and I still have master pages etc. I wish to use instead of taking over all that stuff my self, I really just kinda wants to route http://example.com/item/23/ to http://example.com/item and asking for the item with id 23...
I hope this makes sense at all >.<... And that someone has some better examples at hand that what I have been able to find.
You can achieve this using Routing here is a link to an MSDN blog, The .Net Endpoint - Using Routes to Compose WCF WebHttp Services that should get you started.
If you're looking at asp.net/IIS, another option to look at is ASP.Net MVC. It's pretty straight forward to create RESTful services.
Here's a tutorial:
http://www.codeproject.com/Articles/233572/Build-truly-RESTful-API-and-website-using-same-ASP
So here are your options-
For .net 3.5 sp1 framework with IIS7 you can use asp.net routing feature to have MVC style urls that you mentioned should create a custom route handler implementing IRouteHandler interface as explained here How to: Use Routing with Web Forms and register your route rules in Application_Start method in Global.asax. For your example you can register a route like this
routes.Add("ItemRoute", new Route
(
"item/{itemId}",
new CustomRouteHandler("~/item.aspx")
));
and then you can access itemId in your routed item.aspx page by checking request context item
requestContext.HttpContext.Items["itemId"]
For .net framework 4 MVC you dont have to create a custom handler, you can directly use
routes.MapPageRoute("ItemRoute", "item/{itemId}", "~/item.aspx");
in you global.asax Application_Start method.
This link explains more about the Routing
A way of achieve this is using URL rewriting.
If you're planning to host your Web application in Internet Information Services 7.x, you can take advantage of IIS URL Rewriting Module:
http://www.iis.net/download/urlrewrite
URL rewriting is just mapping a friendly URL to an unfriendly, common one, which is programming-friendly to inspect GET parameters.
For example:
http://yourdomain.com/item/48 => http://yourdomain.com/Items.aspx?Id=48

Categories

Resources