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

EPiServer 7 custom routing problem

Vote:
 

Hi I created a custom episerver route in Global.asax

 

            RouteTable.Routes.MapContentRoute("UserProfileRoute", "user/{uid}/{languageBranch}/{node}/{partial}/{action}", new
                {
                    uid = "",
                    languageBranch = "en",
                    node = "2424",
                    partial = UrlParameter.Optional,
                    action = UrlParameter.Optional
                 });

 

the idea of this route is when i open the following link "www.mywebsite.com/user/123123" it should open the Userprofile episerver page with id "2424"

but with the above mention url it takes me to startpage instead which has a id 3.

what am i doing wrong in this scenrio??

the second problem i am having is when i change the language in the url it never change the langiage of the page e.g "www.mywebsite.com/user/123123/fr" it still stay english

#65422
Jan 29, 2013 16:31
Vote:
 

Same issue here.

#65426
Jan 29, 2013 17:46
Vote:
 

When you use MapContentRoute it will treat the parts of the url that are inside {} as segment (something that is implementing EPiServer.Web.Routing.Segments.ISegment). There are some predefined keys that are handled by default, e.g. {node} that is a content instance, {language} that handles language segment. {uid} however will not be recognized and thereby it will be handled as a ParameterSegment. 

So in your case you should use {language} instead of {languageBranch).

A parameter segment works in the way that during incoming routing the value of the segment will be placed in RequestContext.RouteData.Values with the parameter name as key, in your case "uid". During creation of outgoing links the parameter will output value if the key (e.g "uid") is part of RouteValues dictionary.

You can also have your own custom ISegment implementation (instead of ParameterSegment) that handles your segment, Then you need to use the overload of MapContentRoute that takes a ContentParameters as parameter and in property SegmentMappings add your custom segment with your url pattern as key as e.g. contentParameters.SegmentMappings.Add("uid", customSegmentInstance)

#65430
Jan 29, 2013 19:15
Vote:
 

So what would be the best way to direct the url to a specific EPiServer page? Writing a custom iSegment implementation for the {node} segment?

#65468
Jan 30, 2013 14:24
Vote:
 

I do not think any of the built in segements will do what you want so you need to create your own segment like UserIdSegment (it should be fairly simple, there is a baseclass SegmentBase that you can use). You could e.g. pass in the contentreference of the page in the constructor to your segment. And in RouteDataMatch check if the incoming segment match the a user id and if so set RoutedContentLink. Something like:

public class UserIdSegment : SegmentBase
{
private ContentReference _linkToProfilePage;
public UserIdSegment(string name, ContentReference contentLink) : base(name)
{
_linkToProfilePage = contentLink;
}

public override string GetVirtualPathSegment(System.Web.Routing.RequestContext requestContext, System.Web.Routing.RouteValueDictionary values)
{
return null;
}

public override bool RouteDataMatch(SegmentContext context)
{
var segmentPair = context.GetNextValue(context.RemainingPath);
if (IsValidUserId(segmentPair.Next))
{
context.RemainingPath = segmentPair.Remaining;
context.RoutedContentLink = _linkToProfilePage;
return true;
}

return false;
}

private bool IsValidUserId(string p)
{
//Here should logic for user id go
}
}

The you can register your route something like:

var segment = new UserIdSegment("uid", new ContentReference(2424));
var routingParameters = new MapContentRouteParameters()
{
SegmentMappings = new Dictionary<string, ISegment>()
};
routingParameters.SegmentMappings.Add("uid", segment);

routes.MapContentRoute(
name: "userprofiles",
url: "user/{uid}/{language}/{action}",
defaults: new { action = "index" },
parameters: routingParameters);

 

#65487
Jan 30, 2013 16:47
Vote:
 

Works like a charm! Thank you!

#65494
Jan 30, 2013 18:19
Vote:
 

In case someone reads this in the future I wrote an article on the topic of custom routing featuring, amongst other things a custom segment inspired by Johan's above.

#69887
Apr 09, 2013 10:18
Vote:
 

Maybe I'm missing something here, but I've set up a custom route using a custom segment, and the route parameter I'm really concerned about always is null in my controller. For example, if I use the example above, the 'uid' parameter will be null in the page controller for the profile page. I can see it fine if I pass it as a querystring, but that defeats the purpose. What am I missing?

#72000
Jun 05, 2013 0:45
Vote:
 

Chris, I got the same problem but changed the code for RouteDataMatch to this,

----------

public override bool RouteDataMatch(SegmentContext context)
{
var segmentPair = context.GetNextValue(context.RemainingPath);
var userId = segmentPair.Next;
if (IsValidUserId(userId))
{
context.RemainingPath = segmentPair.Remaining;
context.RoutedContentLink = _linkToProfilePage;
context.RouteData.Values.Add("uid", userId);
return true;
}
return false;
}

----------

e.g. adding the value to the RouteData object. Don't know if this is the correct way to do it but it works :)

 

/Viktor

#73538
Jul 26, 2013 11:14
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.