我没有使用GET方法获取友好网址

时间:2013-07-11 01:33:35

标签: asp.net-mvc asp.net-mvc-4

我设置了这样的路线:

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

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

  

http://mydomain.com/Pesquisar?aaa=One&bbb=Two

但我期待:

  

http://mydomain.com/One/Two

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

您最常可能需要做的事情是Creating Canonical URLs including an id and title slug,除非重定向到您想要的网址,如果它不是您想要显示的网址。

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

答案 2 :(得分:0)

不确定您是否直接从html表单GET获得干净的网址。

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

e.g。

<强>视图模型

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>
}

答案 3 :(得分:0)

这是浏览器行为。在发出GET请求时,浏览器会将所有KeyValue对附加到querystring。

当我们使用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);

答案 4 :(得分:0)

这是预期的行为。

路由系统位于服务器端。浏览器对路由一无所知,你在浏览器中做了什么。

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

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

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

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

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

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

然后,为按钮的click事件创建一个浏览器脚本,使用隐藏字段中的占位符恢复url,并将占位符替换为文本框的实际值。要执行get run:document.location = theUrl;

如果您想为许多不同的实例添加此功能,您可以创建一个Helper来使用Url生成隐藏字段,并使用javascript进行替换。

问题是......值得努力吗?