Url.Action 生成查询而不是参数 URL

Rob*_*Rob 5 asp.net-mvc attributerouting

这是控制器类。我只显示方法签名。

[Authorize]
[RoutePrefix("specification")]
[Route("{action=index}")]
public class SpecificationController : BaseController
{
    [HttpGet]
    [Route("~/specifications/{subcategoryID?}")]
    public ActionResult Index(int? subcategoryID);

    [HttpPost]
    [Route("get/{subcategoryID?}")]
    public JsonResult Get(int? subcategoryID);

    [HttpGet]
    [Route("~/specifications/reorder/{subcategoryID}")]
    public ActionResult Reorder(int subcategoryID);

    [HttpGet]
    [Route("new/{id?}")]
    public ActionResult New(int? id);

    [HttpGet]
    [Route("edit/{id?}")]
    public ActionResult Edit(int id);

    [HttpPost]
    [ValidateAntiForgeryToken]
    [Route("edit")]
    public JsonResult Edit(SpecificationJson specification);

    [HttpPost]
    [Route("moveup")]
    public JsonResult MoveUp(int specificationID);

    [HttpPost]
    [Route("movedown")]
    public JsonResult MoveDown(int specificationID);

    [HttpDelete]
    [Route]
    public ActionResult Delete(int id);
}
Run Code Online (Sandbox Code Playgroud)

问题是调用

@Url.Action("index", "specifications", new RouteValueDictionary() { { "subcategoryID", @subcategory.SubcategoryID } })

返回

/规格?子类别ID = 15

代替

/规格/15

为什么会这样?除了这个,我在这条路线上没有任何类似的方法!

Nig*_*888 3

您生成 URL 的调用不正确。为了匹配控制器名称,它应该是“规格”而不是“规格”。

@Url.Action("index", "specification", new { subcategoryID=subcategory.SubcategoryID })
Run Code Online (Sandbox Code Playgroud)

请记住,[Route]属性中指定的 URL 只是装饰性的。您的路由值必须与控制器名称和操作方法名称匹配,才能利用该路由生成 URL。

为了让代码维护人员更清楚(并且速度更快),最好将参数值设置为 Pascal 大小写,就像控制器和操作名称一样。

@Url.Action("Index", "Specification", new { subcategoryID=subcategory.SubcategoryID })
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况?

-------------------------------------------------------------
| Route Key          | Route Value   | Your Action Request  |
|--------------------|---------------|----------------------|
| Controller         | Specification | Specifications       | No Match
| Action             | Index         | Index                | Match
| subcategoryID      | ?             | XXX                  | Match (Always)
-------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

要获得路由匹配, 的所有参数都@Url.Action必须与路由值字典匹配。问题是Controller=Specifications路由值字典中没有定义,因为您的实际控制器的名称SpecificationController。因此,路由值名称Specification与您在[Route]属性中放置的内容无关。URL~/specifications/{subcategoryID?}与传出(URL 生成)匹配完全无关 - 它仅匹配传入 URL 并确定生成 URL 时的外观。

如果您想使用Specifications而不是用于Specification路由值,则需要将操作方法​​移动到名为 的新控制器SpecificationsController。也就是说,我看不出它有什么区别,因为最终用户无论如何都不会看到路由值名称。