6

我设置了这样的路线:

routes.MapRoute(
    name: "Pesquisar",
    url: "Pesquisar/{aaa}/{bbb}/{id}",
    defaults: new { controller = "Home", action = "Pesquisar",
                    aaa = UrlParameter.Optional,
                    bbb = UrlParameter.Optional,
                    id = UrlParameter.Optional
    }
);

当我在表单中按下发送按钮(使用 GET 方法)时,网址是这样的:

http://localhost:00000/Pesquisar?aaa=One&bbb=Two

但我期待:

http://localhost:00000/Pesquisar/One/Two
4

5 回答 5

1

当您映射路线时,它会将路线添加到列表的末尾。当路由器查找要匹配的规则时,它从列表的开头开始并遍历它。它将采用第一个匹配的规则,而不是最具体的规则。因为将代码附加到末尾是很自然的,所以默认规则(几乎适用于所有内容)将位于开头。

尝试重新排序您的代码,使其看起来像这样:

        ///The specific rout which you want to use
        routes.MapRoute(
        name: "Pesquisar",
        url: "{action}/{aaa}/{bbb}/{id}",
        defaults: new { controller = "Home", action = "Pesquisar",
                        aaa = UrlParameter.Optional,
                        bbb = UrlParameter.Optional,
                        id = UrlParameter.Optional
        }
        );

        ///The generic catch all router
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

更多信息可以在这个问题中找到:
Setting up ASP.Net MVC 4 Routing with custom segment variables

于 2013-07-11T06:20:55.820 回答
1

当我在表单中按下发送按钮(使用 GET 方法)时,网址是这样的:

http://mydomain.com/Pesquisar?aaa=一个&bbb=两个

但我期待:

http://mydomain.com/一/二

这是因为浏览器不知道您想要的花哨的 url,因为标准的表单Get方法是在查询字符串中附加表单值

您最可能需要做的是创建包含 id 和标题 slug 的规范 URL,除非重定向到您想要的 url,如果它不是您想要显示的 url。

或者您可以使用 jQuery 在提交时手动创建您想要的 url,但需要更多的客户端工作。

于 2013-07-11T06:39:02.877 回答
0

不确定您是否直接从 html 表单中获得干净的 URL GET

一个建议是POST对它执行一项操作,对数据执行您需要执行的操作,然后在完成后重定向到您的干净 URL。

例如

视图模型

public sealed class PesquisarModel
{
    public string aaa { get; set; }
    public string bbb { get; set; }
    public string id { get; set; }
}

控制器动作

[HttpGet]
public ActionResult Pesquisar(PesquisarModel m)
{
    return View();
}

[HttpPost]
[ActionName("Pesquisar")]
public ActionResult PesquisarPost(PesquisarModel m)
{
    //do stuff
    return RedirectPermanent("/pesquisar/" + m.aaa + "/" + m.bbb + "/" + m.id);
}

查看

@model MyApplication.Models.PesquisarModel

@using (Html.BeginForm())
{
    @Html.TextBoxFor(m => m.aaa)
    @Html.TextBoxFor(m => m.bbb)
    @Html.TextBoxFor(m => m.id)
    <button type="submit">Submit</button>
}
于 2013-07-11T02:48:17.480 回答
0

这是浏览器的行为。发出 GET 请求时,浏览器会将所有 KeyValue 对附加到查询字符串。

当我们使用 Html.ActionLink 或 Html.RouteUrl 等时,上述路由格式将可用。

您可能可以在 OnActionExecuting 中编写一些代码(或者您可以使用任何处理程序)来重建 RouteData 并使用适当的 url 重定向。以下代码未经测试

var queries = this.Request.QueryString;

foreach(var query in queries)
{
 // Add/Update to RequestContext.RouteData

}

var redirectUrl = Url.RouteUrl("Pesquisar",this.RequestContext.RouteData);

Response.Redirect(redirectUrl);
于 2013-07-11T06:43:33.047 回答
0

这是预期的行为。

路由系统在服务器端。浏览器对路由一无所知,而您正在做的事情发生在浏览器中。

如果您想获得该路线,您必须在客户端使用自定义脚本编写它,该脚本使用<form>' 的操作,以及值的<input type="text">值。

您无法在服务器端生成 Url(可以使用一些 UrlHelper 扩展方法来完成),因为文本框上的更改不会更新。

这是不可取的,因为如果您对路由进行更改,您可能会忘记在浏览器脚本中更新它们,从而破坏您的应用程序。

您可以通过使用带有特殊占位符的 UrlHelper 扩展方法在服务器端创建 url 来避免此问题,这些占位符可以在客户端轻松替换。即生成这样的网址:

http://localhost/Pesquisar/$aaa$/$bbb$/$id$

new {aaa="$aaa$, bbb="$bbb$, id="$id$"}通过向UrlHelper 方法提供这样的 RouteValues:此 url 可以存储在隐藏字段的 value 属性中。

然后,为按钮的单击事件制作浏览器脚本,从隐藏字段中恢复带有占位符的 url,并将占位符替换为文本框的实际值。要执行 get 运行:document.location = theUrl;

如果您想为许多不同的实例执行此操作,您可以创建一个 Helper 以使用 Url 生成隐藏字段,以及一个进行替换的 javascript。

问题是……值得付出努力吗?

于 2013-07-11T15:05:57.823 回答