ASP.NET MVC预览4-使用现有参数停止Url.RouteUrl()等

时间:2020-03-05 18:49:10  来源:igfitidea点击:

我有一个这样的动作:

public class News : System.Web.Mvc.Controller
{
    public ActionResult Archive(int year)
    {
       / *** /
    }
}

使用这样的路线:

routes.MapRoute(
           "News-Archive",                                              
           "News.mvc/Archive/{year}",                           
           new { controller = "News", action = "Archive" }
       );

我使用的URL是:

News.mvc/Archive/2008

我在此页面上有一个这样的表格:

<form>
    <select name="year">
        <option value="2007">2007</option>
    </select>
</form>

如果在表单中选择了" 2007",则提交表单应转到News.mvc / Archive / 2007.

这要求表单的"操作"属性为" News.mvc / Archive"。

但是,如果我声明这样的形式:

<form method="get" action="<%=Url.RouteUrl("News-Archive")%>">

它呈现为:

<form method="get" action="/News.mvc/Archive/2008">

有人可以让我知道我在想什么吗?

解决方案

回答

我认为我们有几个问题。

首先,路线没有默认的"年"值,因此URL" /News.mvc/Archive"实际上对于路由目的无效。

其次,我们希望表单值显示为路由参数,但这不是HTML的工作原理。如果我们使用带有选择和提交的纯格式,则URL最终将在其末尾带有"?year = 2007"。这就是GET方法表单设计为在HTML中工作的方式。

因此,我们需要得出关于重要内容的一些结论。

  • 如果我们希望用户能够从下拉菜单中选择某些内容并更改提交URL,那么我们将不得不使用Javascript来实现这一点(通过截取表单提交并制定正确的URL)。
  • 如果我们可以使用/News.mvc/Archive?year=2007作为URL,那么我们应该从路由中完全删除{year}标记。我们仍然可以在操作上保留" int year"参数,因为表单值还将填充操作方法参数。

回答

我想我已经弄清楚了为什么路线包含{year},所以生成的路线也总是如此。

如果有人可以确认这一点?

回答

解决方案

好的,这是解决方案,(感谢Brad带领我到达那里)。

1)在路由中需要默认值:

routes.MapRoute(
       "News-Archive",                                              
       "News.mvc/Archive/{year}",                           
       new { controller = "News", action = "Archive", year = 0 }
   );

2)添加重定向以解析GET参数,就像它们是URL段一样。

public ActionResult Archive(int year)
{
   if (!String.IsNullOrEmpty(Request["year"]))
   {
       return RedirectToAction("Archive", new { year = Request["year"] });
   }
}

3)确保在具有用于重定向"默认"年份条目的任何代码之前,具有用于请求参数的重定向代码。 IE。

public ActionResult Archive(int year)
{
   if (!String.IsNullOrEmpty(Request["year"]))
   {
       return RedirectToAction("Archive", new { year = Request["year"] });
   }
   if (year == 0)
   {
       /* ... */
   }
   /* ... */
}

3)在Url.RouteUrl()调用中明确指定year的默认值:

Url.RouteUrl("News-Archive", new { year = 0 })