Asp.net mvc 什么';这条MVC路线有什么问题

Asp.net mvc 什么';这条MVC路线有什么问题,asp.net-mvc,asp.net-mvc-3,asp.net-mvc-routing,Asp.net Mvc,Asp.net Mvc 3,Asp.net Mvc Routing,有这个 routes.MapRoute( "ShowPage", "default.aspx/{page}/{pagetype}", new { controller = "Info", action = "PageASPX", page = "emptypage", pagetype = "emptypagetype" } ); 要捕获default.aspx?page=order (我需要生成一

有这个

routes.MapRoute(
    "ShowPage",
    "default.aspx/{page}/{pagetype}",
    new {
        controller = "Info",
        action = "PageASPX",
        page = "emptypage",
        pagetype = "emptypagetype"
    }
);
要捕获
default.aspx?page=order
(我需要生成一个从旧站点到新MVC站点的永久重定向)

正如我在route debugger中看到的那样,路由是匹配的,但是我在路由中没有得到任何值

Key          Value
page         emptypage 
pagetype     emptypagetype 
controller   Info 
action       PageASPX 

怎么了???

MVC路由定义有URL段。您的路线如下所示:

default.aspx/{page}/{pagetype}
default.aspx/somepage
default.aspx/somepage/sometype
这意味着像
default.aspx/order
这样的请求应该在路由解析期间填充
page
值,因为它是作为URL段提供的。这并不意味着当模型绑定发生并且您的控制器操作被调用时,
页面
将不会被填充

如果您的控制器操作签名与此类似:

public ActionResult PageASPX(string page, string pagetype)
{
    ...
}
即使您将这两个参数作为查询变量而不是URL段提供,它们仍可能被填充。唯一的要求是,布线不为缺少的段值提供默认值(或者将其设置为可选值)。然后,默认MVC模型绑定器将使用实际查询变量值填充
页面
操作参数

所以最重要的是你应该改变你的路由定义(见我答案的最后一部分)

应该有效的请求 为了使路由能够识别
页面
页面类型
URL段变量,您的请求应如下所示:

default.aspx/{page}/{pagetype}
default.aspx/somepage
default.aspx/somepage/sometype
如果您的路由没有为
页面
页面类型
定义默认值,那么当您的请求看起来如下时,控制器操作将获得
页面
页面类型
参数,并填充正确的值:

default.aspx/somepage
default.aspx/somepage/sometype
default.aspx?page=somepage
default.aspx?pagetype=sometype
default.aspx?page=somepage&pagetype=sometype
混合路由值和查询字符串变量 正如我的测试所显示的那样,Asp.net MVC在有值时(在URL中作为段或路由默认值提供)不会提供路由值覆盖。在您的情况下,如果您请求此URL:

default.aspx/routepage?page=querypage
您的操作方法将看到
页面
参数以具有routepage的值始终

更重要的一点是,当您在路由定义本身中提供默认值时,您将无法将其设置为查询字符串,即使您从URL中省略了它。要避免此问题,您有两种选择:

  • page
    pagetype
    设置为
    UrlParameter。可选的
    ,当URL没有查询字符串变量时,允许您用查询字符串变量覆盖它们的值-这意味着您始终只能使用URL段或查询字符串,但不能同时使用两者,因为URL段占主导地位

  • URL段变量和查询字符串变量具有不同的名称-缺点是您需要使用双参数执行操作,这是不需要的:

    public ActionResult PageASPX(string routePage, string routeType, string queryPage, string queryType)
    {
        string page = routePage ?? queryPage ?? string.Empty;
        string type = routeType ?? queryType ?? string.Emtpy;
        ...
    }
    
  • 最佳解决方案 更改路由,以便为作为URL段提供的变量提供单独的路由定义,并为作为查询字符串变量提供的变量提供另一个路由定义。然后将这些路由连接到相同的控制器操作,只要所有变量(在段和查询字符串中)共享相同的名称:

    route.MapRoute(
        "InSegmentsBoth",
        "default.aspx/{page}/{pagetype}",
        new { controller = "Info", action = "PageASPX" }
    );
    route.MapRoute(
        "InSegmentsPage",
        "default.aspx/{page}",
        new { controller = Info"", action = "PageASPX" }
    );
    route.MapRoute(
        "InQueryString",
        "default.aspx",
        new { controller = "Info", action = "PageASPX" }
    );
    
    如果您的请求同时提供了两个值(段和查询变量),如


    然后段值具有优先级,因此动作参数
    page
    将具有此请求的段页值。

    MVC路由定义具有URL段。您的路线如下所示:

    default.aspx/{page}/{pagetype}
    
    default.aspx/somepage
    default.aspx/somepage/sometype
    
    这意味着像
    default.aspx/order
    这样的请求应该在路由解析期间填充
    page
    值,因为它是作为URL段提供的。这并不意味着当模型绑定发生并且您的控制器操作被调用时,
    页面
    将不会被填充

    如果您的控制器操作签名与此类似:

    public ActionResult PageASPX(string page, string pagetype)
    {
        ...
    }
    
    即使您将这两个参数作为查询变量而不是URL段提供,它们仍可能被填充。唯一的要求是,布线不为缺少的段值提供默认值(或者将其设置为可选值)。然后,默认MVC模型绑定器将使用实际查询变量值填充
    页面
    操作参数

    所以最重要的是你应该改变你的路由定义(见我答案的最后一部分)

    应该有效的请求 为了使路由能够识别
    页面
    页面类型
    URL段变量,您的请求应如下所示:

    default.aspx/{page}/{pagetype}
    
    default.aspx/somepage
    default.aspx/somepage/sometype
    
    如果您的路由没有为
    页面
    页面类型
    定义默认值,那么当您的请求看起来如下时,控制器操作将获得
    页面
    页面类型
    参数,并填充正确的值:

    default.aspx/somepage
    default.aspx/somepage/sometype
    default.aspx?page=somepage
    default.aspx?pagetype=sometype
    default.aspx?page=somepage&pagetype=sometype
    
    混合路由值和查询字符串变量 正如我的测试所显示的那样,Asp.net MVC在有值时(在URL中作为段或路由默认值提供)不会提供路由值覆盖。在您的情况下,如果您请求此URL:

    default.aspx/routepage?page=querypage
    
    您的操作方法将看到
    页面
    参数以具有routepage的值始终

    更重要的一点是,当您在路由定义本身中提供默认值时,您将无法将其设置为查询字符串,即使您从URL中省略了它。要避免此问题,您有两种选择:

  • page
    pagetype
    设置为
    UrlParameter。可选的
    ,当URL没有查询字符串变量时,允许您用查询字符串变量覆盖它们的值-这意味着您始终只能使用URL段或查询字符串,但不能同时使用两者,因为URL段占主导地位

  • URL段变量和查询字符串变量具有不同的名称-缺点是您需要使用双参数执行操作,这是不需要的:

    public ActionResult PageASPX(string routePage, string routeType, string queryPage, string queryType)
    {
        string page = routePage ?? queryPage ?? string.Empty;
        string type = routeType ?? queryType ?? string.Emtpy;
        ...
    }
    
  • 最佳解决方案 更改路由,以便为作为URL段提供的变量提供单独的路由定义,并为作为查询stri提供的变量提供另一个路由定义