asp.net 为POST操作生成的URL无效

c0vxltue  于 2023-03-24  发布在  .NET
关注(0)|答案(2)|浏览(159)

我认为URL生成有问题。
假设我们有以下控制器:

[Route("[action]")]
public class Home : Controller
{
    [Route("/")]
    public IActionResult Index()
    {
        return View();
    }

    [HttpGet]
    [Route("{number}")]
    public IActionResult Edit(int number)
    {
        
        return View();
    }
    
    [HttpPost]
    public IActionResult Edit()
    {
        return View();
    }
}

索引视图生成了指向“编辑”操作的正确链接:

<a asp-action="Edit" asp-all-route-data='new Dictionary<string, string>{{"number", "11"}}'>GO TO EDIT</a>

也就是/Edit/11
但是在编辑视图中,我试图创建一个表单,它应该发布到相同的action,但是没有路由参数。所以,URL应该只是/Edit。相反,我得到了/Edit/11,它没有到达控制器上的适当action。我用两种方式生成表单,结果是一样的:

<div>
    <form asp-action="Edit" method="post">
        <button type="submit">submit</button>
    </form>
    
    @using (Html.BeginForm("Edit", "Home", FormMethod.Post))
    {
        <button type="submit">submit</button>
    }
</div>

此外,将POST路由模板更改为:

[HttpPost]
    [Route("something")]
    public IActionResult Edit()
    {
        return View();
    }

导致为GET生成的链接为http://localhost:5253/Edit/something?number=11,这是错误的。
对我来说,它看起来像一个bug,但我可能忽略了一些东西。你能帮助我理解这种行为吗?所有端点都正确注册了。是否涉及路由优先级?如果是,那么如何因为那些动作方法对单独的动词做出React...我很困惑。
请在此链接下找到项目:https://blindsend.io#5m4QCCyXKdchLEos4M1ang;GnFBHbs2xAap6QzxJadwFw==

bfrts1fy

bfrts1fy1#

我对你的示例代码进行了测试,在我注解了[Route("{number}")]之后,一切都运行得很好。
当我们在Get action方法之前有[Route("{number}")]时,对Controller的请求将是https://localhost:7131/Edit/11,如果我们注解此属性,则请求将是https://localhost:7131/Edit?number=11
错误发生在表单提交操作中,对于POST操作public IActionResult Edit(),正确的请求URL应该是POST https://localhost:7131/Edit,但当浏览器中的URL是https://localhost:7131/Edit/11并进行表单提交时,提交请求将如下所示,问题发生了。

关于错误405,这意味着URL是正确的,但方法是不允许的,在这个问题中,“不允许”指向Url Routing,为了修复问题,我们可以注解[Route("{number}")]或将[Route("{number}")]添加到POST操作中。
让我们回到正常的行为,在这里看到official sample。默认的路由Map定义为pattern: "{controller=Home}/{action=Index}/{id?}");,当Edit Get请求变成Movies/Edit/5时,我们需要让Movie Controller具有Get操作public async Task<IActionResult> Edit(int? id)id是参数而不是路由属性。这就是为什么我说我在开头注解了[Route("{number}")]

xtupzzrd

xtupzzrd2#

顺便说一句,你可以在GitHub上的这个问题中找到aspnet团队的答案:https://github.com/dotnet/aspnetcore/issues/47375#issuecomment-1481063287

相关问题