首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用System.Web.Http.OData.Delta修补可枚举项?

如何使用System.Web.Http.OData.Delta修补可枚举项?
EN

Stack Overflow用户
提问于 2013-01-12 22:13:54
回答 3查看 2.4K关注 0票数 5

尝试使用System.Web.Http.OData.Delta在ASP.NET Web API服务中实现PATCH方法,但似乎无法将更改应用于IEnumerable<T>类型的属性。我使用的是Delta的最新Git修订版(2012.2-rc-76-g8a73abe)。有没有人能做到这一点?

考虑以下数据类型,应该可以在对Web API服务的修补请求中对其进行更新:

代码语言:javascript
运行
复制
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>实现人员的修补

代码语言:javascript
运行
复制
public void Patch(int id, Delta<Person> delta)
{
    var person = _persons.Single(p => p.Id == id);
    delta.Patch(person);
}

如果我向服务发送一个带有以下JSON的补丁请求,那么这个人的Friends属性应该会被更新,但遗憾的是,这并没有发生:

代码语言:javascript
运行
复制
{"Friends": [1]}

问题的症结在于如何让达美航空用这些数据更新Friends。另请参阅discussion at CodePlex

EN

Stack Overflow用户

回答已采纳

发布于 2013-01-13 01:42:55

问题可能是Deta会尝试将JSON的JArray分配给您的Hashset<int>

如果你对JsonMEdiaTypeFormatter使用它,并且你内化了增量代码(这意味着你可以修改它),你必须这样做(这很粗糙,但很有效):

内部,Delta<T>bool TrySetPropertyValue(string name, object value),其中它返回false:

代码语言:javascript
运行
复制
        if (value != null && !cacheHit.Property.PropertyType.IsPrimitive && !isGuid && !cacheHit.Property.PropertyType.IsAssignableFrom(value.GetType()))
        {
           return false;
        }

更改为:

代码语言:javascript
运行
复制
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;
}

这只适用于intstring的集合,但希望能将您推向一个好的方向。

例如,现在您的模型可以具有:

代码语言:javascript
运行
复制
public class Team {
        public HashSet<string> PlayerIds { get; set; }
        public List<int> CoachIds { get; set; }
    }

你就可以成功地更新它们了。

票数 3
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14294136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档