简体   繁体   English

单击routelink URL不会将所有数据传递给操作

[英]Clicking on routelink url not passing all the data to action

I have creating URL using RouteLink . 我已经使用RouteLink创建URL。

@Html.RouteLink("Edit", "PageWithId",
new
{
    controller = "Customers",
    action = "Edit",
    id = item.CustomerID,
    page = ViewBag.CurrentPage
}) 

I am using this routing PageWithId with route link 我正在将此路由PageWithId与路由链接一起使用

routes.MapRoute(
    name: "PageWithId",
    url: "{controller}/{action}/{page}/{id}",
    defaults: new { controller = "Customers", action = "Edit", page = UrlParameter.Optional, id = UrlParameter.Optional }
);

I have 3 routing code. 我有3个路由代码。 Here is all 这就是全部

routes.MapRoute(
    name: "PageWithSort",
    url: "{controller}/{action}/{page}/{SortColumn}/{CurrentSort}",
    defaults: new { action = "Index", page = UrlParameter.Optional, SortColumn = UrlParameter.Optional, CurrentSort = UrlParameter.Optional }
);

routes.MapRoute(
    name: "PageWithId",
    url: "{controller}/{action}/{page}/{id}",
    defaults: new { controller = "Customers", action = "Edit", page = UrlParameter.Optional, id = UrlParameter.Optional }
);

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

When I run my program the route link generate URL like http://localhost:55831/Customers/Edit/1/ALFKI 当我运行程序时,路由链接会生成类似http://localhost:55831/Customers/Edit/1/ALFKI URL

When I click on the link the Edit action is getting called but customer id is getting null where as ALFKI is there in URL as customer id. 当我单击链接时,将调用“编辑”操作,但客户ID却为null ,因为URL中有ALFKI作为客户ID。

Here is my edit action details 这是我的编辑操作详细信息

public ActionResult Edit(string id, int page)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Customer customer = db.Customers.Find(id);
    if (customer == null)
    {
        return HttpNotFound();
    }
    ViewBag.CurrentPage = page;
    return View(customer);
}

Please tell me why id is getting null when ALFKI as passing as customer id? 请告诉我,当ALFKI作为客户ID传递时,为什么id会为null?

A placeholder (such as {page} or {controller} ) acts like a variable. 占位符(例如{page}{controller} )的作用类似于变量。 It can match anything and store it in a route value with that same name. 它可以匹配任何内容并将其存储在具有相同名称的路由值中。

So, what you are actually saying with your configuration is: 因此,您实际上对配置说的是:

Try 尝试

/<anything (optional)>/<anything (optional)>/<anything (optional)>/<anything (optional)>/<anything (optional)>

If that doesn't work, try 如果这不起作用,请尝试

/<anything (optional)>/<anything (optional)>/<anything (optional)>/<anything (optional)>

If that doesn't work, try 如果这不起作用,请尝试

/<anything (optional)>/<anything (optional)>/<anything (optional)>

If that doesn't work, since {id} is optional try 如果这不起作用,则由于{id}是可选的,请尝试

/<anything (optional)>/<anything (optional)>

If that doesn't work, since {action} is optional try 如果这样不起作用,由于{action}是可选的,请尝试

/<anything (optional)> (if it matches, action will be "Index")

If that doesn't work, since {controller} is optional try 如果这不起作用,则由于{controller}是可选的,请尝试

/ (if it matches, controller will be "Home" and action will be "Index")

See the problem? 看到问题了吗? The first route can (and will) match a URL of any value and any length from 0 to 5 segments. 第一条路由可以(并且将)匹配任何值且长度在0到5段之间的URL。 Once it matches, there is no way to try another route that follows it. 一旦匹配,就无法尝试遵循它的另一条路线。

You need to constrain the routes in some way to ensure some URLs can pass through to the next route to try, namely in the cases where you don't want to match that URL. 您需要以某种方式限制路由,以确保某些URL可以传递到下一条尝试的路由,即在您不想匹配该URL的情况下。

Also, segments can be made optional , but they cannot change position . 同样,可以将段设为可选 ,但不能更改position If you pass a value that means CurrentSort , that automatically means that all of the parameters to the left of it are required . 如果传递的值表示CurrentSort ,则自动表示它左侧的所有参数都是必需的

To me it seems illogical to make {page} , {SortColumn} and {CurrentSort} optional. 在我看来,将{page}{SortColumn}{CurrentSort}设为可选是不合逻辑的。 If you don't need them then either use a different route or take them out of the path altogether and use a query string instead (routes are unaffected by query string values, they only match on the path). 如果不需要它们,则可以使用其他路由,也可以将它们完全从路径中移出,而使用查询字符串(路由不受查询字符串值的影响,它们仅在路径上匹配)。

To make the values required, remove the value = UrlParameter.Optional from the defaults. 要使值成为必需, value = UrlParameter.Optional从默认value = UrlParameter.Optional删除value = UrlParameter.Optional In fact, you can just remove all of the defaults because controller and action are already passed in the URL. 实际上,您可以删除所有默认值,因为控制器和操作已在URL中传递。

routes.MapRoute(
    name: "PageWithSort",
    url: "{controller}/{action}/{page}/{SortColumn}/{CurrentSort}"
);

routes.MapRoute(
    name: "PageWithId",
    url: "{controller}/{action}/{page}/{id}"
);

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

Although these routes can still match anything , this will constrain them to a specific length and since all 3 of them have a different number of segments they won't conflict. 尽管这些路由仍然可以匹配任何内容 ,但这会将它们限制为特定的长度,并且由于所有这三个路由都具有不同数量的细分,因此它们不会冲突。 But since they are still so broad, you should think about using another technique to constrain them such as literal segments or route constraints. 但是,由于它们仍然如此广泛,因此您应该考虑使用另一种技术来约束它们,例如文字段或路线约束。 For example: 例如:

routes.MapRoute(
    name: "CustomerEditWithId",
    url: "Customers/Edit/{page}/{id}",
    defaults: new { controller = "Customers", action = "Edit" }
);

The first route PageWithSort is applied instead of the second one. 应用第一个路由PageWithSort而不是第二个路由。

Note that the routing framework does not know which parameter name you used to generate the URL. 请注意,路由框架不知道您用于生成URL的参数名称。 It just looks at the received string Customers/Edit/1/ALFKI . 它只是查看收到的字符串Customers/Edit/1/ALFKI

For this string, the first route "PageWithSort" matches with 对于此字符串,第一个路由“ PageWithSort”与

  • controller = Customers 控制器=客户
  • action = Edit 动作=编辑
  • page = 1 页= 1
  • SortColumn = ALFKI SortColumn = ALFKI
  • CurrentSort = null (this is OK because it is optional) CurrentSort = null(这是可以的,因为它是可选的)

Because the first matching route will be used, this URL will never hit the "PageWithId" route. 因为将使用第一个匹配的路由,所以该URL将永远不会命中“ PageWithId”路由。

Maybe you can make the SortColumn and CurrentSort parameters of "PageWithSort" required? 也许可以使“ PageWithSort”的SortColumnCurrentSort参数成为必需?

Or change the order in which the routes are defined. 或更改定义路由的顺序。

Or add something unique to the "PageWithSort" route, eg 或添加“ PageWithSort”路由特有的内容,例如

routes.MapRoute(
        name: "PageWithId",
        url: "{controller}/{action}/{page}/ID/{id}",
        //                                 ^^
        defaults: new { controller = "Customers", action = "Edit", page = UrlParameter.Optional, id = UrlParameter.Optional }
    );

Adding /ID as hard coded part of the URL will make it distinguishable from the other routes (assuming there is not SortColumn calling "ID"). /ID添加为URL的硬编码部分将使其与其他路由区分开(假设没有SortColumn调用“ ID”)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM