I will show you how to easily bind parameters to your action methods without using the querystring.
I have a page, MyPage
, with a action method that looks like this:
public async Task<ActionResult> Index(MyPage currentPage, int myId)
{
var response = await this.thirdPartyApi.Get(myId);
// Do something with the response and return a view
var model = MyModel.Create(response);
return View(model);
}
I've also created the page in editmode, I named it MyExamplePage so I can access it like this: https://example.com/MyExamplePage
So, in order to populate the myId
parameter I can call my page like this:
https://example.com/MyExamplePage?myId=1337
Asp.net will automatically populate the myId
parameter from the querystring and everything works just fine, great. But, the URL looks kinda ugly, don't you think?
I want it to look like this instead: https://example.com/MyExamplePage/1337
This doesn't work right out the box, we will need to write some code. I got some great help from Johan Björnfot in this thread over at Episerver World.
It's actually really easy to make this work, here's what you will need to do:
- Create a class that inherits from
IPartialRouter<MyPage, MyPage>
- Implement
GetPartialVirtualPath
andRoutePartial
. In my case I was only interested in theRoutePartial
method so I just returned null inGetPartialVirtualPath
- Extract and parse/validate the values in the
RoutePartial
method. - Return the content.
- Register the partialrouter in Global.asax(or wherever you configure your routes).
routes.RegisterPartialRouter(new ParameterPartialRouter());
- Done!
Here's the full code of my PartialRouter.
public class ParameterPartialRouter : IPartialRouter<MyPage, MyPage>
{
public PartialRouteData GetPartialVirtualPath(
MyPage content,
string language,
RouteValueDictionary routeValues,
RequestContext requestContext)
{
return null;
}
public object RoutePartial(
MyPage content,
SegmentContext segmentContext)
{
var nextValue = segmentContext.GetNextValue(segmentContext.RemainingPath);
int myId;
if (Int32.TryParse(nextValue.Next, out myId))
{
segmentContext.RouteData.Values["myId"] = myId;
segmentContext.RemainingPath = nextValue.Remaining;
}
return content;
}
}