![](/img/trans.png)
[英].NET Core Patch JsonPatchDocument works locally but not on server
[英]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 - 使用 HTTP 补丁进行部分更新
// 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"
}
]
这将返回404 Not Found
....
关于路径https://localhost:5001/api/VideoGame/... 的说明:
Index
和Patch
实际上会按预期返回视图,这确认了路径可以解析。405 Method Not Allowed
- 这意味着我的另一个方法 [HttpGet] Patch() 然后执行,并且由于不允许 PATCH 而失败。我错过了什么? 或者我不能在同一个项目中使用“MVC 操作”和“补丁 API 操作”?
我设法使用 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>
不要为 api 添加新的.MapControllerRoute()
路由路径,这似乎不能与 JsonPatch 一起正常工作
确保引用了Microsoft.Extensions.DependencyInjection
,静态类NewtonsoftJsonMvcBuilderExtensions
将AddNewtonsoftJson()
添加到服务中:( IMvcBuilder
扩展)
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddNewtonsoftJson();
}
请注意教程 Route 和最终有效的 Route 之间的区别。 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 不能正常工作
错误 405 方法 不允许。
错误 415“不支持的媒体类型”
patchEntity
集合为空,但响应为200
成功(似乎可以正常工作,但patchEntity
没有发生任何补丁。
AddNewtonsoftJson()
扩展方法,集合将为空,给出成功的请求但没有更新。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.