ASP.NET Core 8 MVC:操作不能具有除 id 之外的命名路由值

问题描述 投票:0回答:1

背景

我对 .NET Core 和 MVC Core 还很陌生,之前已经习惯过 .NET 4.x 和 MVC 5,所以如果我问一些显而易见的问题,请耐心等待;我通过任何方式搜索都找不到答案。

使用的东西:

  • .NET 8
  • MVC 核心
  • jQuery

所以我有一个具有如下操作的控制器:

[Area("SomeArea")]
public class SomeNameController : Controller
{
    public SomeNameController(..injected stuff...) { }

    [HttpGet]
    public PartialViewResult AddDialog() {
      ...
    }

    [HttpPost]
    public async Task<IActionResult> AddDialog(MyDialogModel dialogModel) {
      ...
    }

    [HttpDelete]
    [Route("DoSomeDeletion/{uniqueIdentifier}")]
    public async Task<JsonResult> DoSomeDeletion(int uniqueIdentifier)
    {
       ...
       return Json(result);
    }
}

在 Startup.cs 中,除了我拥有的其他东西之外,还配置了一些东西:

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapBlazorHub();

    endpoints.MapControllerRoute(
        name: "areas",
        pattern: "{area:exists}/{controller=index}/{action=Index}/{id?}");

    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=index}/{action=Index}/{id?}");

    endpoints.MapFallbackToPage("/_Host");

});

我的页面中有以下 JS 来添加点击处理程序并执行 AJAX 删除:

$("#MyGrid").on('click', '.js-delete-btn', function (e) {
    e.preventDefault();
    var url = this.href,
        data = $("#GridForm").serializeObject();
    $.ajax({
        method: "DELETE",
        url: url,
        data: data
    })
        .done(function (jqXHR, textStatus) {
            toastr.success("Yay! Deleted successfully", null, {
                timeout: 5000,
                onHidden: function () { window.location.reload(); }
            });
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
            toastr.error("Uh-oh something went wrong", null, { timeout: 5000 });
        });
});

在上面用于 AJAX 请求的 href 类似于 /SomeArea/SomeName/DoSomeDeletion/356

序列化的表单包含我使用 [HttpPost] 尝试 MVC 操作时的防伪令牌

问题

如果我在 DoSomeDeletion 操作中设置断点,它将永远不会被命中。但是,如果我去掉它的 Route 属性,那么它就会受到攻击。

我尝试过的事情

  • 我尝试使用[HttpPost]而不是[HttpDelete]
  • 对于 HttpDelete 和 HttpPost,我使用了重载,让您可以指定与 Route 属性相同的路由模板
  • 如果我更改 URL 以使 Id 成为查询字符串,例如?uniqueIdentifier=365,那么就会命中action,并且值会绑定到actions参数上。

观察结果

  • 删除路由属性,以便操作被命中,我看到 Request.RouteValues 有一个 {id} 值,该值设置为我执行 DELETE AJAX 调用的 URL 中的值。

问题

我之前没有使用过路由属性,所以也许我遗漏了一些东西,但在 .NET 4.8 中的 MVC 5 中我从未遇到过此类问题,我可以有 1 个或多个来自 URL 的路由值并被称为任何名称我想要。

发生什么事了?为什么我不能使用我想要使用的路由值名称?

c# asp.net asp.net-mvc asp.net-core-mvc
1个回答
0
投票
endpoints.MapControllerRoute(
        name: "areas",
        pattern: "{area:exists}/{controller=index}/{action=Index}/{id?}");

    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=index}/{action=Index}/{id?}");

在asp.net core中被称为常规路由

[Route("DoSomeDeletion/{uniqueIdentifier}")]
被称为属性路由有自己的模式
"DoSomeDeletion/{uniqueIdentifier}"

定义属性路由的动作无法通过常规路由到达,并且属性路由模式不会与像asp.net mvc app这样的常规路由模式结合

您现在只能使用 uri

DoSomeDeletion/356
访问 DoSomeDeletion 方法

将您的路线属性修改为

[Route("[Area]/[Controller]/[Action]/{uniqueIdentifier}")]
,以便您可以通过
/SomeArea/SomeName/DoSomeDeletion/356

到达终点
© www.soinside.com 2019 - 2024. All rights reserved.