繁体   English   中英

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 - 使用 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]操作方法IndexPatch实际上会按预期返回视图,这确认了路径可以解析。
  • [HttpPatch] Patch()方法中删除 /id 参数将返回405 Method Not Allowed - 这意味着我的另一个方法 [HttpGet] Patch() 然后执行,并且由于不允许 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 方法 不允许。

  • 确保您的路由与控制器中的此处完全相同,Startup.cs 中的路由似乎不适用于 JsonPatch。
  • 还要确保您将 JSON 作为内容类型

错误 415“不支持的媒体类型”

  • 您的内容类型未设置为 JSON。

patchEntity集合为空,但响应为200成功(似乎可以正常工作,但patchEntity没有发生任何补丁。

  • 我发现如果不添加AddNewtonsoftJson()扩展方法,集合将为空,给出成功的请求但没有更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM