Asp.net mvc I';我没有用GET方法获取表单中的友好url

Asp.net mvc I';我没有用GET方法获取表单中的友好url,asp.net-mvc,asp.net-mvc-4,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,

我设置了这样的路线:

routes.MapRoute(
    name: "Pesquisar",
    url: "Pesquisar/{aaa}/{bbb}/{id}",
    defaults: new { controller = "Home", action = "Pesquisar",
                    aaa = UrlParameter.Optional,
                    bbb = UrlParameter.Optional,
                    id = UrlParameter.Optional
    }
);
http://localhost:00000/Pesquisar?aaa=One&bbb=Two

当我在表单中按Send按钮(使用GET方法)时,url如下所示:

routes.MapRoute(
    name: "Pesquisar",
    url: "Pesquisar/{aaa}/{bbb}/{id}",
    defaults: new { controller = "Home", action = "Pesquisar",
                    aaa = UrlParameter.Optional,
                    bbb = UrlParameter.Optional,
                    id = UrlParameter.Optional
    }
);
http://localhost:00000/Pesquisar?aaa=One&bbb=Two
但我期待着:

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

不确定是否直接从html表单获取干净的URL
get

一个建议是
将它发布到一个动作中,对数据做你需要做的事情,然后在完成后重定向到你的干净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>
}
控制器动作

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

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>
}
@model MyApplication.Models.PesquisarModel
@使用(Html.BeginForm())
{
@Html.TextBoxFor(m=>m.aaa)
@Html.TextBoxFor(m=>m.bbb)
@Html.TextBoxFor(m=>m.id)
提交
}

映射路由时,它会将其添加到列表的末尾。当路由器查找要匹配的规则时,它从列表的开头开始,并通过它进行排序。它将采用匹配的第一条规则,而不是最具体的规则。因为在末尾追加代码是很自然的,所以默认规则(几乎适用于所有情况)将在开头

尝试将代码重新排序为如下所示:

        ///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 }
        );
更多信息可在此问题中找到:

当我按表单中的“发送”按钮(使用GET方法)时,url如下所示:

routes.MapRoute(
    name: "Pesquisar",
    url: "Pesquisar/{aaa}/{bbb}/{id}",
    defaults: new { controller = "Home", action = "Pesquisar",
                    aaa = UrlParameter.Optional,
                    bbb = UrlParameter.Optional,
                    id = UrlParameter.Optional
    }
);
http://localhost:00000/Pesquisar?aaa=One&bbb=Two

但我期待着:

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

这是因为浏览器不知道您想要的奇特url,因为标准的表单
Get
方法是在querystring中附加表单值

除了重定向到您想要的url(如果它不是您想要显示的url)之外,您最可能需要做的事情是这样的


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

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

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

您可以在OnActionExecuting中编写一些代码(或者您可以使用任何处理程序)来重建RoutedData并使用适当的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);

这是预期的行为

路由系统位于服务器端。浏览器对路线一无所知,您在浏览器中执行的操作也会发生

如果要获得该路由,必须在客户端使用自定义脚本编写它,该脚本使用
的操作,并使用
值的值

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

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

您可以通过在服务器端使用带有特殊占位符的UrlHelper扩展方法创建url来避免这个问题,在客户端可以很容易地替换这些占位符。即,生成如下url:

        ///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 }
        );
http://localhost/Pesquisar/$aaa$/$bbb$/$id$

通过向UrlHelper方法提供如下路由值:
new{aaa=“$aaa$,bbb=“$bbb$,id=“$id$”}
。此url可以存储在隐藏字段的value属性中

然后,为按钮的单击事件创建一个浏览器脚本,从隐藏字段中用占位符恢复url,并用文本框的实际值替换占位符。要执行get,请运行以下命令:
document.location=theUrl

如果您想为许多不同的实例创建一个帮助器,用Url和一个javascript来创建隐藏字段,以进行替换


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

当ID有值时,同样的事情会发生吗?@Jeroenvanevel:是的。如果我在浏览器中手动输入,它会工作(
http://localhost:00000/Pesquisar/foo/bar/1
)但通过表单获取却没有。我的意思是,它是有效的,但不是友好的url。