Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
DotNet 5.0核心MVC-与JsonPatchDocument一起使用-修补程序不工作-找不到404_Json_.net_Model View Controller_.net Core_Patch - Fatal编程技术网

DotNet 5.0核心MVC-与JsonPatchDocument一起使用-修补程序不工作-找不到404

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 5.0项目(MVC项目):

dotnet新mvc

内部.csproj文件:
net5.0

**如前所述,模板不起作用,因此我添加了一些额外的控制器操作
[HttpGet]Index()
[HttpGet]Patch()
:**并将
[HttpPatch]Patch()
方法作为教程保持不变

这将返回未找到的
404

关于路径的注释https://localhost:5001/api/VideoGame/...:

  • 导航到普通MVC[HttpGet]操作方法
    Index
    Patch
    实际上会按预期返回视图,这确认了路径可以解决
  • 从[HttpPatch]Patch()方法中删除/id参数将返回
    405 method Not Allowed
    ——这意味着我的另一个方法[HttpGet]Patch()随后执行,但由于不允许使用补丁而失败
  • 因此,修补方法不起作用,或者无法解析为路径

我错过了什么?或者我不能在同一个项目中使用“MVC操作”和“补丁API操作”吗?

我通过补丁更新解决了问题,我确实可以在同一个项目中使用它,我正在使用Dotnet MVC项目

我的问题中链接的教程不适用于当前版本的Dotnet Core 3x或新的Dotnet 5.0,但它只需要稍作更新

我的问题中几乎所有的内容都是正确的,在做了不同的测试后有一些细微的变化

必要的部分:

使用Nuget等添加这两个库:

  • Microsoft.AspNetCore.Mvc.NewtonsoftJson

  • Microsoft.AspNetCore.JsonPatch

  • .proj/solution文件

  • 您的控制器
请注意教程路线和最终有效的路线之间的差异<代码>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);
        }
}
使用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作为内容类型
错误415“不支持的媒体类型”

  • 您的内容类型未设置为JSON
patchEntity
集合为空,但响应为
200
success(似乎正在工作,但对象上未发生修补)

  • 我发现,如果未添加扩展方法
    AddNewtonsoftJson()
    extension,则集合将为空,给出了成功的请求,但没有更新
// 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);
        }
}