【问题标题】:How to resolve HttpPut Error 405 in ASP NET Core 3.1 MVC project?如何解决 ASP NET Core 3.1 MVC 项目中的 HttpPut 错误 405?
【发布时间】:2019-12-22 18:43:39
【问题描述】:

我有一个运动控制器和两个同名的方法

[HttpGet]
public async Task<IActionResult> Update(int exerciseId)
{
    Exercise exercise = (await this.exerciseService.GetExercises(exercise => exercise.Id == exerciseId)).FirstOrDefault();
    return View(exercise);
}

[HttpPut]
public async Task<IActionResult> Update(Exercise exercise)
{
    if (ModelState.IsValid)
    {
        await this.exerciseService.EditExercise(exercise);
        return RedirectToAction("some-view-which-doesnt-matter-in-my-case");
    }
    return View(exercise);
}

我想使用相似的名称来在各自的视图中呈现验证错误。但我目前面临的问题是 HttpPut 方法的错误 405。在我的情况下,我该如何解决?我已经阅读了一些关于编辑/添加 web.config 的文章,其中包含“remove name="WebDAVModule"”之类的内容,但是 1) 这些文章是在以前版本的 .NET core 上 2) 即使我添加了 web.config 的内容,例如

<system.webServer>
  <modules runAllManagedModulesForAllRequests="false">
    <remove name="WebDAVModule" />
  </modules>
</system.webServer>

...项目根本无法启动,并引用了 IIS Express 引发的异常。那我该怎么办?我的“更新”视图是:

@model DomainModels.Exercise
@{
    ViewData["Title"] = "Update";
}

<h1>Update @Model.Name</h1>
<div>
    <form method="put" asp-controller="Exercise" asp-action="Update">
        <div asp-validation-summary="ModelOnly">

        </div>
        <div>
            <h3>Exercise settings:</h3>
            <input hidden asp-for="Id" />
            <div>
                <label asp-for="Name"></label><br />
                <input asp-for="Name" />
                <span asp-validation-for="Name"></span>
            </div>
            <div>
                <label asp-for="FractureFixNumber"></label><br />
                <input asp-for="FractureFixNumber" />
                <span asp-validation-for="FractureFixNumber"></span>
            </div>
            <div>
                <label asp-for="DislocationFixNumber"></label><br />
                <input asp-for="DislocationFixNumber" />
                <span asp-validation-for="DislocationFixNumber"></span>
            </div>
            <div>
                <label asp-for="SprainFixNumber"></label><br />
                <input asp-for="SprainFixNumber" />
                <span asp-validation-for="SprainFixNumber"></span>
            </div>
        </div>
        <div>
            <h3>Exercise analysis range settings:</h3>
            <input hidden asp-for="ExerciseAnalysisRange.ExerciseId" />
            <div>
                <label asp-for="ExerciseAnalysisRange.MinAnalysis1"></label><br />
                <input asp-for="ExerciseAnalysisRange.MinAnalysis1" />
                <span asp-validation-for="ExerciseAnalysisRange.MinAnalysis1"></span>
            </div>
            <div>
                <label asp-for="ExerciseAnalysisRange.MaxAnalysis1"></label><br />
                <input asp-for="ExerciseAnalysisRange.MaxAnalysis1" />
                <span asp-validation-for="ExerciseAnalysisRange.MaxAnalysis1"></span>
            </div>
            <div>
                <label asp-for="ExerciseAnalysisRange.MinAnalysis2"></label><br />
                <input asp-for="ExerciseAnalysisRange.MinAnalysis2" />
                <span asp-validation-for="ExerciseAnalysisRange.MinAnalysis2"></span>
            </div>
            <div>
                <label asp-for="ExerciseAnalysisRange.MaxAnalysis2"></label><br />
                <input asp-for="ExerciseAnalysisRange.MaxAnalysis2" />
                <span asp-validation-for="ExerciseAnalysisRange.MaxAnalysis2"></span>
            </div>
            <div>
                <label asp-for="ExerciseAnalysisRange.MinHighPressure"></label><br />
                <input asp-for="ExerciseAnalysisRange.MinHighPressure" />
                <span asp-validation-for="ExerciseAnalysisRange.MinHighPressure"></span>
            </div>
            <div>
                <label asp-for="ExerciseAnalysisRange.MaxHighPressure"></label><br />
                <input asp-for="ExerciseAnalysisRange.MaxHighPressure" />
                <span asp-validation-for="ExerciseAnalysisRange.MaxHighPressure"></span>
            </div>
            <div>
                <label asp-for="ExerciseAnalysisRange.MinLowPressure"></label><br />
                <input asp-for="ExerciseAnalysisRange.MinLowPressure" />
                <span asp-validation-for="ExerciseAnalysisRange.MinLowPressure"></span>
            </div>
            <div>
                <label asp-for="ExerciseAnalysisRange.MaxLowPressure"></label><br />
                <input asp-for="ExerciseAnalysisRange.MaxLowPressure" />
                <span asp-validation-for="ExerciseAnalysisRange.MaxLowPressure"></span>
            </div>
            <div>
                <label asp-for="ExerciseAnalysisRange.MinHeartBeats"></label><br />
                <input asp-for="ExerciseAnalysisRange.MinHeartBeats" />
                <span asp-validation-for="ExerciseAnalysisRange.MinHeartBeats"></span>
            </div>
            <div>
                <label asp-for="ExerciseAnalysisRange.MaxHeartBeats"></label><br />
                <input asp-for="ExerciseAnalysisRange.MaxHeartBeats" />
                <span asp-validation-for="ExerciseAnalysisRange.MaxHeartBeats"></span>
            </div>
            <input type="submit" value="Update exercise" />
        </div>
    </form>
</div>

【问题讨论】:

标签: c# asp.net .net asp.net-core asp.net-core-mvc


【解决方案1】:

在 Asp.Net Core 的同一个控制器上不能有两个同名的方法。

您应该更改其中一种方法的名称并使用[ActionName()] 属性使两种方法的方法路径相同。

[HttpGet]
public async Task<IActionResult> Update(int exerciseId)
{
    Exercise exercise = (await this.exerciseService.GetExercises(exercise => exercise.Id == exerciseId)).FirstOrDefault();
    return View(exercise);
}

[HttpPut]
[ActionName("Update")]
public async Task<IActionResult> UpdatePut(Exercise exercise)
{
    if (ModelState.IsValid)
    {
        await this.exerciseService.EditExercise(exercise);
        return RedirectToAction("some-view-which-doesnt-matter-in-my-case");
    }
    return View(exercise);
}

【讨论】:

  • 他不是特意要了两个相同的方法名吗?
  • 在问题中他说:“我想使用相似的名称,以便在各自的视图中呈现验证错误。”。在我的回答中,我清楚地表明该方法不能具有相同的名称,但使用 ActionName 属性,它将以相同的路线响应。仅通过 http 动词不同。我相信它正确地回答了这个问题。如果您不同意,请指出问题所在,我会尽快解决。
  • 没问题。有时我误解了这个问题。有人来评论总是好的。
  • docs 根据 Microsoft 指南,您的端点不应包含 get、create、update、delete 字词,动作由 HTTP 动词指定
  • 这个完全不行,提交表单后转到[HttpGet]Update(int exerciseId)方法
【解决方案2】:

解决方案非常简单:扔掉 HttpPut,更改动作名称并手动设置重定向视图。最终代码为:

public async Task<IActionResult> UpdateExercise(Exercise exercise)
        {
            if (ModelState.IsValid)
            {
                await this.exerciseService.EditExercise(exercise);

                return RedirectToAction("UpdateIndex");
            }
            return View("Update", exercise);
        }

因此,在视图中更改 PUT 操作名称...

<form method="put" asp-controller="Exercise" asp-action="UpdateExercise">

顺便说一句,HttpDelete 方法也是如此:只需摆脱 HttpDelete

【讨论】:

    猜你喜欢
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 2021-05-25
    • 2021-06-01
    • 2017-10-30
    • 2021-03-26
    • 1970-01-01
    相关资源
    最近更新 更多