November Happy Hour will be moved to Thursday December 5th.

Question about Routing

Vote:
 

Hi, I have been trying to understand how the routing work and the model binding and I think I have started to understand some parts but there is still some things that I don't fully understand. I start to make two "statements" which I hope is correct otherwise I have misunderstood something. Then my question comes after but it would be great it the "statements" also could be confirmed or if they are wrong explain what I have missed =)

1. The class EPiServer.Web.TemplateResolver is responsible to find out what template to use. So in the case of MVC it finds out which controller to use.

2. The class EPiServer.Web.Mvc.ContentDataModelBinder which implements the interface IModelBinder and hence got the method BindModel(...) is responsible to actually bind the parameter of type IContentData to the corresponding content. So in the case of an action method like this:

public ActionResult Index(StandardPage currentPage)

it will bind currentPage to the correct instance of StandardPage ( that is if the parameter is called currentPage, currentContent or currentBlock). Basically what happens in the method BindModel is that if RouteData.DataTokens[RoutingConstants.NodeKey] contains a ContentReference that one is used to grab the proper IContentData from IContentRepository. If it does not RouteData.Values["currentContent"] is checked and if it is not null the contained IContentData is used.

QUESTION

I guess the first part when handling a request is to find out what controller to use in the case of MVC. So here the TemplateResolver comes into play. I guess some of the Resolve(..) methods is called which in turn calls ResolveInternal which triggers the event handling and eventually a template is returned. I can't say I fully understand the event handling but my knowledge about events might be to bad. But I guess the "functions" that is executed when RaiseEvent(...) function is called ( the line "eventHandler((object) this, e);" ) must be added from outside. Or I may totally wrong here and totally misunderstood =)

However the main question is really where does all the parameters that is fed into Resolve comes from. For example there is one signature for Resolve that looks like this ( and some others with slight changes )

public virtual TemplateModel Resolve(HttpContextBase httpContext, ContentType contentType, TemplateTypeCategories templateTypeCategory, string tag)

Where does the ContentType comes from? I guess there is some routing magic here based on what type the page is of in the URL. What happens from that when I enter my URL in the browser and click enter to the point when I reach Resolve(...) in TemplateResolver? Same question goes for the data in RouteData.DataTokens and RouteData.Values that is used in BindModel(...) in ContentDataModelBinder. How do they end up in there? I was trying to find the startpoint and ended up in MultiplexingRouteHandler but I have no idea if that was right.

I hope someone can help me on this ( what I think ) interesting question.

#68210
Mar 19, 2013 0:58
Vote:
 

Anyone have some input on this? I realised that it was quite a huge question or was I so wrong that it was not even worth answering =). But to make the question no so huge what I really wonder is how the IContent becomes input to an controller action method. I mean in a ordinary asp.net mvc application if I have an url like 

mySite/foo/edit?version=123 it will go to the controller class FooController and the action method Edit(int version). Here it is quite easy to understand how it works. The request will be mapped to the controller and the version=123 will be bound to the parameter "int version" in the controller signature. But here the value that is binded is actually a part of the request, it is declared in the actual URL.

But in the case of EPiServer if I enter an URL like mySite/TestStuff, TestStuff is basically the name(by default?) of a Page Type instance of whatever type. If it is of type StandardPage I will get to my StandardPageController's Index action method which may be declared like:

public ActionResult Index(StandardPage currentPage)

However in this case the StandardPage is not part of the original request context. When I enter the URL in my browser there is no knowledge about any StandardPage. So compared to the original asp.net mvc case where the data was in the request context from the beginning in the episerver case some data must be added somewhere between where I click enter in my browser and where I enter the correct controller. My question is really how/where does this occur?

#68326
Mar 20, 2013 11:19
Vote:
 

EPiServer CMS will during initialization register a route with a pattern like {language}/{node}/{partial}/{action}. So the first segment of a url is an optional language segment (if it is present or not is dependent on language settings for the site). The second part of the pattern {node} will match a content item (this can span over zero to several segments in the Url). The NodeSegment will start from the start page of the site and look for a child with a EPiServer.Web.Routing.IRoutable.RouteSegment that matches the first url segment. If it finds a match it will continue to look among the found content items children for a child with a RouteSegment that matches next segment in the url. It will continue so until it found no match or the whole url is consumed. 

The Route handler will then look at the type of the content routed to (e.g. it might be an instance of a StandardPage) and ask TemplateResolver for a suitable template. In case the matching template is a MVC controller the request is hanlded over to an MvcRouteHandler (together with controller and action).

#68344
Mar 20, 2013 13:01
Vote:
 

Thanks Johan, very good answer as usual. One fast more question thou. Where does the default route registration occur( the {language}/{node}/{partial}/{action} part), in what class? I assume MultiplexingRouteHandler gets registered there as IRouteHandler when creating the Route?

#68375
Mar 20, 2013 22:10
Vote:
 

The registration of routes are triggered from EPiServer.Global and the actual registration is located in EPiServer.Web.Routing.RouteCollectionExtensions.RegisterRoutes

#68378
Mar 21, 2013 9:22
This thread is locked and should be used for reference only. Please use the Episerver CMS 7 and earlier versions forum to open new discussions.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.