我该如何修补与可枚举System.Web.Http.OData.Delta? [英] How do I patch enumerables with System.Web.Http.OData.Delta?
问题描述
试图使用的 System.Web.Http.OData.Delta A>实施 PATCH 一>中的ASP.NET Web API服务的方法,但似乎无法更改应用到类型的属性的IEnumerable< T>
。我使用的是三角洲(2012.2-RC-76 g8a73abe)最新的Git版本。任何人都已经能够使这项工作?
Trying to make use of System.Web.Http.OData.Delta to implement PATCH methods in ASP.NET Web API services, but it seems unable to apply changes to properties of type IEnumerable<T>
. I'm using the latest Git revision of Delta (2012.2-rc-76-g8a73abe). Has anyone been able to make this work?
考虑这个数据类型,它应该有可能在一个PATCH请求到Web API服务来更新
Consider this data type, which it should be possible to update in a PATCH request to the Web API service:
public class Person
{
HashSet<int> _friends = new HashSet<int>();
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public IEnumerable<int> Friends
{
get { return _friends; }
set
{
_friends = value != null ? new HashSet<int>(value) : new HashSet<int>();
}
}
public Person(int id, string firstName, string lastName)
{
Id = id;
FirstName = firstName;
LastName = lastName;
}
public Person()
{
}
}
本网页API方法实现了人的修补三角洲&LT;&人GT;
:
public void Patch(int id, Delta<Person> delta)
{
var person = _persons.Single(p => p.Id == id);
delta.Patch(person);
}
如果我返回以下JSON补丁请求到服务,人的朋友
属性应被更新,但可惜它不会发生:
If I send a PATCH request with the following JSON to the service, the person's Friends
property should be updated, but alas it doesn't happen:
{"Friends": [1]}
而问题的关键是如何真正使增量更新朋友
与此数据。又见讨论在codePLEX 。
推荐答案
的问题可能是,德塔会尝试分配JSON的 JArray
你的 HashSet的&LT; INT&GT;
The problem likely is that Deta will try to assign JSON's JArray
to your Hashset<int>
如果您正在使用它对抗JsonMEdiaTypeFormatter你内在三角洲code(这意味着你可以修改它),你必须做这样的事情(这是粗糙的,但工程):
If you are using it against JsonMEdiaTypeFormatter and you internalized the Delta code (meaning you can modify it), you'd have to do something like this (this is rough, but works):
里面, BOOL TrySetPropertyValue(字符串名称,对象的值)
三角洲&LT; T&GT;
,它返回false
Inside, bool TrySetPropertyValue(string name, object value)
of Delta<T>
, where it returns false:
if (value != null && !cacheHit.Property.PropertyType.IsPrimitive && !isGuid && !cacheHit.Property.PropertyType.IsAssignableFrom(value.GetType()))
{
return false;
}
更改为:
var valueType = value.GetType();
var propertyType = cacheHit.Property.PropertyType;
if (value != null && !propertyType.IsPrimitive && !propertyType.IsAssignableFrom(valueType))
{
var array = value as JArray;
if (array == null)
return false;
var underlyingType = propertyType.GetGenericArguments().FirstOrDefault() ??
propertyType.GetElementType();
if (underlyingType == typeof(string))
{
var a = array.ToObject<IEnumerable<string>>();
value = Activator.CreateInstance(propertyType, a);
}
else if (underlyingType == typeof(int))
{
var a = array.ToObject<IEnumerable<int>>();
value = Activator.CreateInstance(propertyType, a);
}
else
return false;
}
这将只与 INT
或字符串
收藏工作,但希望能轻推你进入一个很好的方向。
This will only work with collections of int
or string
but hopefully nudges you into a good direction.
例如,现在你的模型有:
For example, now your model can have:
public class Team {
public HashSet<string> PlayerIds { get; set; }
public List<int> CoachIds { get; set; }
}
和你能够成功地更新它们。
And you'd be able to successfully update them.
这篇关于我该如何修补与可枚举System.Web.Http.OData.Delta?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!