406(NotAcceptable)来自EntitySetController中的PATCH请求的响应.网站API 2.
本文关键字:请求 响应 网站 API PATCH 中的 NotAcceptable 来自 EntitySetController | 更新日期: 2023-09-27 17:59:03
我非常困惑,希望有人能澄清。升级到Web API的最新版本后(从Microsoft.AspNet.WebApi.xx5.0.0。到Microsoft.AspNet.WebApi.xxx5.1.2)OData的EntitySetController停止处理PATCH谓词,而是返回406(不可接受)代码。
实现没有改变:
public class ODataAnnouncementController : EntitySetController<TEntity, TKey> where TEntity : class
{
(...)
protected override Announcement PatchEntity(Guid key, Delta<Announcement> patch)
{
var announcement = getEntityByKeyOrThrowException(key);
patch.Patch(announcement);
AnnouncementManager.Instance.Save(announcement, true);
return announcement;
}
}
请求也没有改变:
接受:application/json
内容类型:application/json;charset=utf-8
补丁:http://{url}/odatea/Announcement(guid'62E34FB3-A37E-413F-9843-642D95BA580A')
{"描述":"单元测试的修补描述"}
方法内部的断点没有被击中,就好像"Delta<Announce>>补丁"从未被反序列化一样。它真正到达方法内部断点的唯一条件是,请求BODY为空,导致补丁对象为空。
所有其他动词(GET、POST、PUT、DELETE)都可以正常工作。
这以前也行得通。有人知道Web API 2.1在PATCH方面有任何突破性的变化吗?否则我该如何进行故障排除?
非常感谢
票据
更新
以下是C#模型:
[Serializable]
[DataContract]
public class Announcement
{
private Guid _announcementID;
private string _description;
private bool _isPrivate;
private DateTime _createdTime;
private Nullable<Guid> _membershipID;
[DataMember]
public Guid AnnouncementID
{
get { return this._announcementID; }
set { this._announcementID = value; }
}
[DataMember]
public string Description
{
get { return this._description; }
set { this._description = value; }
}
[DataMember]
public bool IsPrivate
{
get { return this._isPrivate; }
set { this._isPrivate = value; }
}
[DataMember]
public DateTime CreatedTime
{
get { return this._createdTime; }
set { this._createdTime = value; }
}
[DataMember]
public Nullable<Guid> MembershipID
{
get { return this._membershipID; }
set { this._membershipID = value; }
}
}
我使用显式数据模型:
var routingConventions = ODataRoutingConventions.CreateDefault();
config.Routes.MapODataRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: BuildExplicitODataModel(),
pathHandler: new DefaultODataPathHandler(),
routingConventions: routingConventions
);
public static IEdmModel BuildExplicitODataModel()
{
ODataModelBuilder modelBuilder = new ODataModelBuilder();
var announcementSet = buildAnnouncementModel(modelBuilder);
return modelBuilder.GetEdmModel();
}
private static EntitySetConfiguration<Announcement> buildAnnouncementModel(ODataModelBuilder modelBuilder)
{
var announcementSet = modelBuilder.EntitySet<Announcement>("Announcement");
announcementSet.HasEditLink(
entityContext => entityContext.Url.ODataLink(
new EntitySetPathSegment(entityContext.EntitySet.Name),
new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(entityContext.EntityInstance.AnnouncementID, ODataVersion.V3))),
followsConventions: true);
announcementSet.HasIdLink(
entityContext => entityContext.Url.ODataLink(
new EntitySetPathSegment(entityContext.EntitySet.Name),
new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(entityContext.EntityInstance.AnnouncementID, ODataVersion.V3))),
followsConventions: true);
var announcement = announcementSet.EntityType;
announcement.HasKey(p => p.AnnouncementID);
announcement.Property(p => p.Description);
announcement.Property(p => p.IsPrivate);
announcement.Property(p => p.CreatedTime);
announcement.Property(p => p.MembershipID);
return announcementSet;
}
这是请求有效载荷:
补丁http://{url}/odatea/Announcement(guid'62E34FB3-A37E-413F-9843-642D95BA580A')
接受:application/json
内容类型:application/json;charset=utf-8
身体:
{"描述":"单元测试的修补描述"}
在我检查了最新的文件EntityRoutingConvention.cs之后,我发现actionName只能是Patch或PatchAnnouncement。
永远不会调用PatchEntity。
可以尝试使用Patch或PatchAnnouncement重命名该方法吗?
更新
然而,它在我的repo项目中运行良好。你能将你的参考版本WebApiConfig.cs、AnnouncementsController.cs和请求与我的进行比较吗。
我注意到了一些不同:
- 控制器名称为ODataAnnouncementController,您是否在模型生成器中使用"ODataAnnotation"作为实体集名称
- 在您的PATCH请求中,为什么要使用"公告"而不是"公告"
参考
Microsoft.AspNet.WebApi 5.1.2targetFramework="net45"
WebApiConfig.cs
using System.Web.Http;
using System.Web.Http.OData.Builder;
using ReproPatchNotWork.Models;
namespace ReproPatchNotWork
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Announcement>("Announcements");
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());
}
}
}
公告Controller.cs
using System;
using System.Web.Http.OData;
namespace ReproPatchNotWork.Models
{
public class AnnouncementsController : EntitySetController<Announcement, Guid>
{
protected override Announcement PatchEntity(Guid key, Delta<Announcement> patch)
{
Announcement announcement = new Announcement();
patch.Patch(announcement);
return announcement;
}
}
}
请求
PATCH http://{url}/odatea/Announcements(guid'62E34FB3-A37E-413F-9843-642D95BA580A')
接受:application/json
内容类型:application/json;charset=utf-8
正文:{"描述":"单元测试的补丁描述"}