尝试使用System.Web.Http.OData.Delta在ASP.NET Web API服务中实现PATCH方法,但似乎无法将更改应用于IEnumerable<T>类型的属性。我使用的是Delta的最新Git修订版(2012.2-rc-76-g8a73abe)。有没有人能做到这一点?
考虑以下数据类型,应该可以在对Web API服务的修补请求中对其进行更新:
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()
{
}
}此Web API方法通过Delta<Person>实现人员的修补
public void Patch(int id, Delta<Person> delta)
{
var person = _persons.Single(p => p.Id == id);
delta.Patch(person);
}如果我向服务发送一个带有以下JSON的补丁请求,那么这个人的Friends属性应该会被更新,但遗憾的是,这并没有发生:
{"Friends": [1]}问题的症结在于如何让达美航空用这些数据更新Friends。另请参阅discussion at CodePlex。
发布于 2013-01-13 01:42:55
问题可能是Deta会尝试将JSON的JArray分配给您的Hashset<int>
如果你对JsonMEdiaTypeFormatter使用它,并且你内化了增量代码(这意味着你可以修改它),你必须这样做(这很粗糙,但很有效):
内部,Delta<T>的bool TrySetPropertyValue(string name, object value),其中它返回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或string的集合,但希望能将您推向一个好的方向。
例如,现在您的模型可以具有:
public class Team {
public HashSet<string> PlayerIds { get; set; }
public List<int> CoachIds { get; set; }
}你就可以成功地更新它们了。
发布于 2017-03-24 18:45:50
您可以覆盖Delta类的TrySetPropertyValue方法并使用JArray类:
public sealed class DeltaWithCollectionsSupport<T> : Delta<T> where T : class
{
public override bool TrySetPropertyValue(string name, object value)
{
var propertyInfo = typeof(T).GetProperty(name);
return propertyInfo != null && value is JArray array
? base.TrySetPropertyValue(name, array.ToObject(propertyInfo.PropertyType))
: base.TrySetPropertyValue(name, value);
}
}发布于 2013-01-13 02:14:49
如果您使用的是ODataMediaTypeFormatter,这应该是可行的。不过,这里有几个需要注意的地方。1)你的集合必须是可设置的。2)替换整个集合。不能删除/添加单个元素。
此外,还有一个问题跟踪项目1- '670 -Delta should support non-settable collections.'
https://stackoverflow.com/questions/14294136
复制相似问题