我正在使用最新发布的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/...:
- 导航到正常MVC[HttpGet]操作方法
Index
和Patch
实际上按预期返回了视图,这证实了路径可以被解析 - 从[HttpPatch]Patch((方法中删除/id参数将返回
405 Method Not Allowed
,这意味着我的另一个方法[HttpGet]Patch(随后执行,但由于不允许Patch而失败 - 因此,PATCH方法不起作用,或者无法解析为路径
我缺少什么?或者我不能在同一个项目中使用"MVC操作"one_answers"Patch 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>
- Startup.cs
不要为api添加新的
.MapControllerRoute()
路由路径,这似乎与JsonPatch无法正常工作确保引用了
Microsoft.Extensions.DependencyInjection
,静态类NewtonsoftJsonMvcBuilderExtensions
将
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
错误405不允许使用方法。
- 请确保您的路由与Controller中的此处完全相同,Startup.cs中的路由似乎不适用于JsonPatch
- 还要确保将JSON作为内容类型
错误415";不支持的媒体类型";
- 您的内容类型未设置为JSON
patchEntity
集合为空,但响应为200
成功(似乎正在工作,但对象上没有发生补丁。
- 我发现,如果不添加
AddNewtonsoftJson()
扩展方法,集合将为空,从而发出成功的请求,但没有更新