DotNet 5.0核心MVC-与JsonPatchDocument一起使用-修补程序不工作-找不到404
我正在使用最新发布的Dotnet 5.0项目(MVC项目):DotNet 5.0核心MVC-与JsonPatchDocument一起使用-修补程序不工作-找不到404,json,.net,model-view-controller,.net-core,patch,Json,.net,Model View Controller,.net Core,Patch,我正在使用最新发布的Dotnet 5.0项目(MVC项目): dotnet新mvc 内部.csproj文件:net5.0 **如前所述,模板不起作用,因此我添加了一些额外的控制器操作[HttpGet]Index()和[HttpGet]Patch():**并将[HttpPatch]Patch()方法作为教程保持不变 这将返回未找到的404 关于路径的注释https://localhost:5001/api/VideoGame/...: 导航到普通MVC[HttpGet]操作方法Index和Pat
dotnet新mvc
内部.csproj文件:net5.0
**如前所述,模板不起作用,因此我添加了一些额外的控制器操作[HttpGet]Index()
和[HttpGet]Patch()
:**并将[HttpPatch]Patch()
方法作为教程保持不变
这将返回未找到的404
关于路径的注释https://localhost:5001/api/VideoGame/...:
- 导航到普通MVC[HttpGet]操作方法
和Index
实际上会按预期返回视图,这确认了路径可以解决Patch
- 从[HttpPatch]Patch()方法中删除/id参数将返回
——这意味着我的另一个方法[HttpGet]Patch()随后执行,但由于不允许使用补丁而失败405 method Not Allowed
- 因此,修补方法不起作用,或者无法解析为路径
我错过了什么?或者我不能在同一个项目中使用“MVC操作”和“补丁API操作”吗?我通过补丁更新解决了问题,我确实可以在同一个项目中使用它,我正在使用Dotnet MVC项目 我的问题中链接的教程不适用于当前版本的Dotnet Core 3x或新的Dotnet 5.0,但它只需要稍作更新 我的问题中几乎所有的内容都是正确的,在做了不同的测试后有一些细微的变化 必要的部分: 使用Nuget等添加这两个库:
Microsoft.AspNetCore.Mvc.NewtonsoftJson
Microsoft.AspNetCore.JsonPatch
- .proj/solution文件
- 您的控制器:
using Microsoft.AspNetCore.JsonPatch;
namespace X{
[ApiController]
[Route("api/[controller]/[action]")]
public class VideoGameController : Controller
[HttpPatch("{id:int}")]
public IActionResult Patch(int id, [FromBody] JsonPatchDocument<VideoGame> patchEntity)
{
var entity = VideoGames.FirstOrDefault(videoGame => videoGame.Id == id);
if (entity == null)
{
return NotFound();
}
patchEntity.ApplyTo(entity, ModelState); // Must have Microsoft.AspNetCore.Mvc.NewtonsoftJson installed
return Ok(entity);
}
}
使用Microsoft.AspNetCore.JsonPatch;
名称空间X{
[ApiController]
[路由(“api/[controller]/[action]”)
公共类视频游戏控制器:控制器
[HttpPatch(“{id:int}”)]
公共IActionResult修补程序(int-id,[FromBody]JsonPatchDocument patchEntity)
{
var entity=VideoGames.FirstOrDefault(videoGame=>videoGame.Id==Id);
if(实体==null)
{
返回NotFound();
}
patchEntity.ApplyTo(实体,模型状态);//必须安装Microsoft.AspNetCore.Mvc.NewtonsoftJson
返回Ok(实体);
}
}
故障排除
首先:不要为api添加新的.mapcontrolleroute()
路由路径,这在JsonPatch中似乎无法正常工作
错误405方法不允许
- 确保您的路由与控制器中的路由完全相同,Startup.cs中的路由似乎不适用于JsonPatch
- 还要确保将JSON作为内容类型
- 您的内容类型未设置为JSON
patchEntity
集合为空,但响应为200
success(似乎正在工作,但对象上未发生修补)
- 我发现,如果未添加扩展方法
extension,则集合将为空,给出了成功的请求,但没有更新AddNewtonsoftJson()
// Startup.cs
// Added .AddNewtonsoftJson() extension method from NewtonsoftJsonMvcBuilderExtensions
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddNewtonsoftJson();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){
// .... truncated ....
// Add custom route for /api
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "api",
pattern: "api/{controller=VideoGame}/{action=Index}/{id?}");
});
}
// VideoGame.cs
public partial class VideoGame
{
public virtual int Id { get; set; }
public virtual string Title { get; set; }
public virtual string Publisher { get; set; }
public virtual DateTime? ReleaseDate { get; set; }
public VideoGame(int id, string title, string publisher, DateTime? releaseDate)
{
Id = id;
Title = title;
Publisher = publisher;
ReleaseDate = releaseDate;
}
}
// VideoGameController.cs
using Test_JSON_Patch.Classes;
using System.Linq;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.JsonPatch;
// Removed this route - because it didn't work at all (even without adding a custom route)
// [Route("api/video-game")]
// So current resolves to https://localhost/api/VideoGame/Index
public class VideoGameController : Controller
{
IList<VideoGame> VideoGames { get; set; }
public VideoGameController()
{
VideoGames = new List<VideoGame>();
VideoGames.Add(new VideoGame(1, "Call of Duty: Warzone", "Activision", new System.DateTime(2020, 3, 10)));
VideoGames.Add(new VideoGame(2, "Friday the 13th: The Game", "Gun Media", new System.DateTime(2017, 5, 26)));
VideoGames.Add(new VideoGame(3, "DOOM Eternal", "Bethesda", new System.DateTime(2020, 3, 20)));
}
[HttpGet]
public IActionResult Index(){
return View();
}
[HttpGet]
public IActionResult Patch(){
// Just using View from home page to confirm Patch GET
ViewBag.DataTest = "Patch Home Page";
return View("Index");
}
[HttpPatch("{id:int}")]
public IActionResult Patch(int id, [FromBody] JsonPatchDocument<VideoGame> patchEntity)
{
var entity = VideoGames.FirstOrDefault(videoGame => videoGame.Id == id);
if (entity == null)
{
return NotFound();
}
patchEntity.ApplyTo(entity, ModelState); // Must have Microsoft.AspNetCore.Mvc.NewtonsoftJson installed
return Ok(entity);
}
}
// PATCH method using POSTMAN and raw body: - tried |BOTH| array and single object syntax
https://localhost:5001/api/VideoGame/Patch/id/2
[
{
"value": "Friday the 13th",
"path": "/title",
"op": "replace"
}
]
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.0"/>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.0"/>
</ItemGroup>
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddNewtonsoftJson();
}
using Microsoft.AspNetCore.JsonPatch;
namespace X{
[ApiController]
[Route("api/[controller]/[action]")]
public class VideoGameController : Controller
[HttpPatch("{id:int}")]
public IActionResult Patch(int id, [FromBody] JsonPatchDocument<VideoGame> patchEntity)
{
var entity = VideoGames.FirstOrDefault(videoGame => videoGame.Id == id);
if (entity == null)
{
return NotFound();
}
patchEntity.ApplyTo(entity, ModelState); // Must have Microsoft.AspNetCore.Mvc.NewtonsoftJson installed
return Ok(entity);
}
}