5

System.Web.Http.OData.Deltaを使用して ASP.NET Web API サービスにPATCHメソッドを実装しようとしていますが、タイプ のプロパティに変更を適用できないようIEnumerable<T>です。Delta の最新の Git リビジョン (2012.2-rc-76-g8a73abe) を使用しています。誰もこれを機能させることができましたか?

Web API サービスへの PATCH 要求で更新できるはずのこのデータ型を検討してください。

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 メソッドは、以下を介して Person のパッチ適用を実装しますDelta<Person>

public void Patch(int id, Delta<Person> delta)
{
    var person = _persons.Single(p => p.Id == id);
    delta.Patch(person);
}

次の JSON を含む PATCH 要求をサービスに送信すると、個人のFriendsプロパティが更新されるはずですが、残念ながら更新されません。

{"Friends": [1]}

問題の要点は、Friendsこのデータでデルタを更新する方法です。CodePlex での議論も参照してください。

4

3 に答える 3

3

JArray問題は、DetaがJSONをあなたに割り当てようとすることです。Hashset<int>

JsonMEdiaTypeFormatterに対して使用していて、Deltaコードを内部化した場合(つまり、変更できる場合)、次のような操作を行う必要があります(これは大まかなことですが、機能します)。

bool TrySetPropertyValue(string name, object value)の内部、 Delta<T>ここで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; }
    }

そして、それらを正常に更新することができます。

于 2013-01-12T17:42:55.290 に答える
0

ODataMediaTypeFormatter を使用している場合、これは機能するはずです。ただし、いくつかの注意事項があります。1) コレクションは設定可能でなければなりません。2) コレクション全体が置き換えられます。個々の要素を削除/追加することはできません。

また、問題追跡項目 1 があります - 「670 -Delta should support non-settable collections」。

于 2013-01-12T18:14:48.823 に答える