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

时间:2022-07-13 01:49:26

I have an action like this:

我有这样的动作:

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

With a route like this:

有这样的路线:

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

The URL that I am on is:

我所在的网址是:

News.mvc/Archive/2008

I have a form on this page like this:

我在这个页面上有一个表格,如下所示:

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

Submitting the form should go to News.mvc/Archive/2007 if '2007' is selected in the form.

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

This requires the form 'action' attribute to be "News.mvc/Archive".

这要求“action”属性为“News.mvc / Archive”。

However, if I declare a form like this:

但是,如果我声明一个这样的表单:

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

it renders as:

它呈现为:

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

Can someone please let me know what I'm missing?

有人可以让我知道我错过了什么吗?

3 个解决方案

#1


2  

You have a couple problems, I think.

我想你有几个问题。

First, your route doesn't have a default value for "year", so the URL "/News.mvc/Archive" is actually not valid for routing purposes.

首先,您的路线没有“年”的默认值,因此URL“/News.mvc/Archive”实际上无法用于路由目的。

Second, you're expect form values to show up as route parameters, but that's not how HTML works. If you use a plain form with a select and a submit, your URLs will end up having "?year=2007" on the end of them. This is just how GET-method forms are designed to work in HTML.

其次,您希望表单值显示为路由参数,但这不是HTML的工作方式。如果您使用带有选择和提交的简单表单,您的网址最终会在其末尾显示“?year = 2007”。这就是GET方法表单设计为在HTML中工作的方式。

So you need to come to some conclusion about what's important.

所以你需要得出一些关于什么是重要的结论。

  • If you want the user to be able to select something from the dropdown and that changes the submission URL, then you're going to have to use Javascript to achieve this (by intercepting the form submit and formulating the correct URL).
  • 如果您希望用户能够从下拉列表中选择某些内容并更改提交URL,那么您将不得不使用Javascript来实现此目的(通过拦截表单提交并制定正确的URL)。

  • If you're okay with /News.mvc/Archive?year=2007 as your URL, then you should remove the {year} designator from the route entirely. You can still leave the "int year" parameter on your action, since form values will also populate action method parameters.
  • 如果您使用/News.mvc/Archive?year=2007作为您的URL,那么您应该完全从路线中删除{year}指示符。您仍然可以在操作中保留“int year”参数,因为表单值也会填充操作方法参数。

#2


0  

I think I've worked out why - the route includes {year} so the generated routes always will too..

我想我已经解决了原因 - 路线包括{year}所以生成的路线也总是如此...

If anyone can confirm this?

如果有人能证实这一点?

#3


0  

Solution

Okay here is the solution, (thanks to Brad for leading me there).

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

1) Require default value in route:

1)在路线中要求默认值:

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

2) Add a redirect to parse GET parameters as though they are URL segments.

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

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

3) Make sure you have your redirect code for Request params before any code for redirecting "default" year entries. i.e.

3)在重定向“默认”年份条目的任何代码之前,请确保您具有Request params的重定向代码。即

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

3) Explicitly specify the default value for year in the Url.RouteUrl() call:

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

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

#1


2  

You have a couple problems, I think.

我想你有几个问题。

First, your route doesn't have a default value for "year", so the URL "/News.mvc/Archive" is actually not valid for routing purposes.

首先,您的路线没有“年”的默认值,因此URL“/News.mvc/Archive”实际上无法用于路由目的。

Second, you're expect form values to show up as route parameters, but that's not how HTML works. If you use a plain form with a select and a submit, your URLs will end up having "?year=2007" on the end of them. This is just how GET-method forms are designed to work in HTML.

其次,您希望表单值显示为路由参数,但这不是HTML的工作方式。如果您使用带有选择和提交的简单表单,您的网址最终会在其末尾显示“?year = 2007”。这就是GET方法表单设计为在HTML中工作的方式。

So you need to come to some conclusion about what's important.

所以你需要得出一些关于什么是重要的结论。

  • If you want the user to be able to select something from the dropdown and that changes the submission URL, then you're going to have to use Javascript to achieve this (by intercepting the form submit and formulating the correct URL).
  • 如果您希望用户能够从下拉列表中选择某些内容并更改提交URL,那么您将不得不使用Javascript来实现此目的(通过拦截表单提交并制定正确的URL)。

  • If you're okay with /News.mvc/Archive?year=2007 as your URL, then you should remove the {year} designator from the route entirely. You can still leave the "int year" parameter on your action, since form values will also populate action method parameters.
  • 如果您使用/News.mvc/Archive?year=2007作为您的URL,那么您应该完全从路线中删除{year}指示符。您仍然可以在操作中保留“int year”参数,因为表单值也会填充操作方法参数。

#2


0  

I think I've worked out why - the route includes {year} so the generated routes always will too..

我想我已经解决了原因 - 路线包括{year}所以生成的路线也总是如此...

If anyone can confirm this?

如果有人能证实这一点?

#3


0  

Solution

Okay here is the solution, (thanks to Brad for leading me there).

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

1) Require default value in route:

1)在路线中要求默认值:

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

2) Add a redirect to parse GET parameters as though they are URL segments.

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

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

3) Make sure you have your redirect code for Request params before any code for redirecting "default" year entries. i.e.

3)在重定向“默认”年份条目的任何代码之前,请确保您具有Request params的重定向代码。即

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

3) Explicitly specify the default value for year in the Url.RouteUrl() call:

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

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