DotNet 5.0 Core MVC - 与 JsonPatchDocument 一起使用 - PATCH 不工作 - 404 未找到
DotNet 5.0 Core MVC - using with JsonPatchDocument - PATCH not working - 404 not found
我使用的是新发布的Dotnet 5.0项目(MVC项目):
dotnet new mvc
.csproj 文件内部:<TargetFramework>net5.0</TargetFramework>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.0"/>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.0"/>
</ItemGroup>
我尝试使用教程进行测试,但没有用。
ASP Net Core API - Partial Update using HTTP Patch
// 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;
}
}
** 如前所述,模板不起作用,因此我添加了一些额外的控制器操作 [HttpGet] Index()
和 [HttpGet] Patch()
:** 和 离开 [HttpPatch] Patch()
方法不变,与教程相同
// 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);
}
}
使用以下 JSON 示例进行测试:(使用 POSTMAN 中的 PATCH 方法)
// 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"
}
]
这个returns 404 Not Found
....
关于路径的注释 https://localhost:5001/api/VideoGame/...:
- 导航到正常的 MVC [HttpGet] 操作方法
Index
和 Patch
实际上 return 是预期的视图,这证实了路径可以解析。
- 从 [HttpPatch] Patch() 方法中删除 /id 参数将 return
405 Method Not Allowed
- 这意味着我的另一个方法 [HttpGet] Patch( ) 然后执行,但由于不允许 PATCH 而失败。
- 所以,PATCH方法不起作用,或者无法解析到路径。
我错过了什么?或者我不能在同一个项目中使用 'MVC actions' 和 'Patch API actions' 吗?
我设法使用 PATCH 更新解决了问题,我确实可以在同一个项目中使用它,我正在使用 Dotnet MVC 项目。
我的问题中链接的教程不适用于当前版本的 Dotnet Core 3x 或新的 Dotnet 5.0,但它只需要稍作更新。
我的问题几乎所有内容都是正确的,经过不同的测试后有一些细微的变化。
所需件数:
使用 Nuget 等添加这两个库:
Microsoft.AspNetCore.Mvc.NewtonsoftJson
Microsoft.AspNetCore.JsonPatch
.proj/解决方案文件
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.0"/>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.0"/>
</ItemGroup>
- Startup.cs
不要为api添加新的.MapControllerRoute()
路由路径,这似乎不起作用正确使用 JsonPatch
确保Microsoft.Extensions.DependencyInjection
被引用,静态classNewtonsoftJsonMvcBuilderExtensions
添加AddNewtonsoftJson()
到服务:(IMvcBuilder
扩展)
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddNewtonsoftJson();
}
- 你的控制器:
注意教程路线和最终成功的路线之间的区别。 ApiController
属性是可选的。
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);
}
}
疑难解答
首先:不要为 api 添加新的 .MapControllerRoute()
路由路径,这似乎无法与 JsonPatch 一起正常工作
Error 405 Method Not allowed.
- 确保您的路由与控制器中的路由完全一致,Startup.cs 中的路由似乎不适用于 JsonPatch。
- 还要确保您将JSON作为内容类型
Error 415 "Unsupported Media Type"
- 您的内容类型未设置为 JSON。
The patchEntity
collection is empty, but the response is 200
success (appears that is working, but no patch happened on object.
- 我发现如果不添加
AddNewtonsoftJson()
扩展方法,集合会为空,请求成功但没有更新。
我使用的是新发布的Dotnet 5.0项目(MVC项目):
dotnet new mvc
.csproj 文件内部:<TargetFramework>net5.0</TargetFramework>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.0"/>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.0"/>
</ItemGroup>
我尝试使用教程进行测试,但没有用。 ASP Net Core API - Partial Update using HTTP Patch
// 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;
}
}
** 如前所述,模板不起作用,因此我添加了一些额外的控制器操作 [HttpGet] Index()
和 [HttpGet] Patch()
:** 和 离开 [HttpPatch] Patch()
方法不变,与教程相同
// 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);
}
}
使用以下 JSON 示例进行测试:(使用 POSTMAN 中的 PATCH 方法)
// 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"
}
]
这个returns 404 Not Found
....
关于路径的注释 https://localhost:5001/api/VideoGame/...:
- 导航到正常的 MVC [HttpGet] 操作方法
Index
和Patch
实际上 return 是预期的视图,这证实了路径可以解析。 - 从 [HttpPatch] Patch() 方法中删除 /id 参数将 return
405 Method Not Allowed
- 这意味着我的另一个方法 [HttpGet] Patch( ) 然后执行,但由于不允许 PATCH 而失败。 - 所以,PATCH方法不起作用,或者无法解析到路径。
我错过了什么?或者我不能在同一个项目中使用 'MVC actions' 和 'Patch API actions' 吗?
我设法使用 PATCH 更新解决了问题,我确实可以在同一个项目中使用它,我正在使用 Dotnet MVC 项目。
我的问题中链接的教程不适用于当前版本的 Dotnet Core 3x 或新的 Dotnet 5.0,但它只需要稍作更新。
我的问题几乎所有内容都是正确的,经过不同的测试后有一些细微的变化。
所需件数:
使用 Nuget 等添加这两个库:
Microsoft.AspNetCore.Mvc.NewtonsoftJson
Microsoft.AspNetCore.JsonPatch
.proj/解决方案文件
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.0"/>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.0"/>
</ItemGroup>
- Startup.cs
不要为api添加新的
.MapControllerRoute()
路由路径,这似乎不起作用正确使用 JsonPatch确保
Microsoft.Extensions.DependencyInjection
被引用,静态classNewtonsoftJsonMvcBuilderExtensions
添加
AddNewtonsoftJson()
到服务:(IMvcBuilder
扩展)
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddNewtonsoftJson();
}
- 你的控制器:
注意教程路线和最终成功的路线之间的区别。 ApiController
属性是可选的。
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);
}
}
疑难解答
首先:不要为 api 添加新的 .MapControllerRoute()
路由路径,这似乎无法与 JsonPatch 一起正常工作
Error 405 Method Not allowed.
- 确保您的路由与控制器中的路由完全一致,Startup.cs 中的路由似乎不适用于 JsonPatch。
- 还要确保您将JSON作为内容类型
Error 415 "Unsupported Media Type"
- 您的内容类型未设置为 JSON。
The
patchEntity
collection is empty, but the response is200
success (appears that is working, but no patch happened on object.
- 我发现如果不添加
AddNewtonsoftJson()
扩展方法,集合会为空,请求成功但没有更新。