MapPageRoute - can't send empty strings in the middle?

て烟熏妆下的殇ゞ 提交于 2019-12-24 19:36:01

问题


In Global.asax.cs in a project that I'm maintaining there is a method that looks like this

private static void MapRouteWithName(string name, string url, string physicalPath, bool? checkPhysicalUrlAccess = null, RouteValueDictionary defaults = null)
{
  Route route;
  if ((checkPhysicalUrlAccess != null) && (defaults != null))
  {
    route = System.Web.Routing.RouteTable.Routes.MapPageRoute(name, url, physicalPath, checkPhysicalUrlAccess.Value, defaults);
  }
  else
  {
    route = System.Web.Routing.RouteTable.Routes.MapPageRoute(name, url, physicalPath);
  }
  route.DataTokens = new RouteValueDictionary();
  route.DataTokens.Add("RouteName", name);
}

It's then used in Global.asax.cs to set up routes like this:

MapRouteWithName("Change User", "User/Change/{id}/{organizationid}/{username}/{logonaccount}/{phone}", "~/User/Change.aspx", true,
  new RouteValueDictionary { { "id", "0" }, { "organizationid", "0" }, { "username", "" }, { "logonaccount", "" }, { "phone", "" } });

And then in the code behind a page one can find things like this:

Response.RedirectToRoute("Change User", new
{
  id = userID,
  organizationid = selectedOrganizationID,
  username = userName,
  logonaccount = logonAccount,
  phone = phone
});

Now this works nicely in most cases but in this particular example I don't know if the variables userName, logonAccount and phone actually contains something or is empty. When for instance userName is empty ("") and logonAccount has a value ("abcde") an exception is thrown:

System.InvalidOperationException: No matching route found for RedirectToRoute.

It seems like the exception is thrown when there is a variable with an empty string in between variables that has values. (Did this make sense?) What can I do about this?


回答1:


The issue here is that the redirect doesn't match the route because you are declaring optional values incorrectly. The only way to make them optional would be to have a configuration like this:

routes.MapPageRoute(
    routeName: "ChangeUser1",
    routeUrl: "User/Change/{id}/{organizationid}/{username}/{logonaccount}/{phone}",
    physicalFile: "~/User/Change.aspx",
    checkPhysicalUrlAccess: true,
    defaults: new RouteValueDictionary(new {
        phone = UrlParameter.Optional,
    })
);

routes.MapPageRoute(
    routeName: "ChangeUser2",
    routeUrl: "User/Change/{id}/{organizationid}/{username}",
    physicalFile: "~/User/Change.aspx",
    checkPhysicalUrlAccess: true,
    defaults: new RouteValueDictionary(new
    {
        username = UrlParameter.Optional
    })
);

This will always work when any of the last 3 parameters are left off of the redirect. However, there's a catch - when you leave out a parameter, all of the parameters to the right will also be empty. That is the way the built-in routing works. A parameter can only be optional if there is no value to the right of it.

If you want to have all 3 parameters optional and not have to worry about what order or combination the parameters are passed, you have 2 options:

  1. Use query string parameters
  2. Use a convention to build up a series of routes as in this example

Query string parameters are the far simpler option when dealing with search forms with lots of optional parameters because they can be supplied in any order and any combination without having to do anything extra. They are a natural fit for this scenario.



来源:https://stackoverflow.com/questions/48808698/mappageroute-cant-send-empty-strings-in-the-middle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!