我非常困惑,希望有人能说清楚。升级到最新版本的Web API(从Microsoft.AspNet.WebApi.xxx 5.0.0。到Microsoft.AspNet.WebApi.xxx 5.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
Content-Type:application / json;字符集= UTF-8
PATCH:http:// {url} / odata / Announcement(guid'62E34FB3-A37E-413F-9843-642D95BA580A')
{“描述”:“单元测试中的修补描述”}
方法中的断点未被击中,好像“Delta&lt; Announcement&gt;&gt; patch”从未反序列化。它实际上确实触及方法内部断点的唯一条件是当请求BODY为空时导致补丁对象当然为空。
所有其他动词(GET,POST,PUT,DELETE)都可以正常工作。
之前曾经工作过。有人知道有关PATCH的Web API 2.1有任何重大变化吗?我怎么能排除故障呢?
非常感谢
比尔
更新
这是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;
}
这是请求有效负载:
PATCH http:// {url} / odata / Announcement(guid'62E34FB3-A37E-413F-9843-642D95BA580A')
接受:application / json
Content-Type:application / json;字符集= UTF-8
BODY:
{“描述”:“单元测试中的修补描述”}
答案 0 :(得分:0)
检查完最新文件EntityRoutingConvention.cs后, 我发现actionName只能是Patch或PatchAnnouncement。
永远不会调用PatchEntity。
您可以尝试使用Patch或PatchAnnouncement重命名方法吗?
<强>更新强>
然而,它在我的repro项目中工作正常。 你能比较你的参考版本,WebApiConfig.cs,AnnouncementsController.cs和我的请求。
我注意到一些不同之处:
<强>参考强>
Microsoft.AspNet.WebApi 5.1.2 targetFramework =&#34; net45&#34;
<强> 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());
}
}
}
<强> AnnouncementsController.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} / odata / Announcements(guid&#39; 62E34FB3-A37E-413F-9843-642D95BA580A&#39;)
接受:application / json
Content-Type:application / json;字符集= UTF-8
正文:{&#34;描述&#34;:&#34;来自单元测试和#34的补丁描述;}