Delta can't patch enumerables

Topics: ASP.NET Web API, General
Jan 12, 2013 at 2:02 PM

Hi guys

I'm trying to use System.Web.Http.OData.Delta (Git revision 2012.2-rc-76-g8a73abe) against Web API to patch a type containing an enumerable (IEnumerable<int>), but it is impossible to patch this enumerable property. I've confirmed that Delta can patch scalar properties no problem, but it won't assign an incoming change to the enumerable property.

The following code contains an example of a type, Person, that should be patched by Delta. The property 'Friends' is an enumerable of integers. The data type is followed by an example implementation of a Web API PATCH method that is to apply incoming changes to a Person. If I send JSON containing an array 'Friends', e.g. {"Friends": [1]} to this server, Delta does not apply the change.

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()
    {
    }
}

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

Any ideas?

 

Jan 12, 2013 at 6:16 PM

I have answered this on SO. copying the answer here too.

If you are using the ODataMediaTypeFormatter, this should be working. There are a couple of caveats to mention though. 1) your collections have to be settable. 2) the entire collection is replaced. you cannot remove/add individual elements.

Also, there is an issue tracking item 1 - '670 -Delta should support non-settable collections.'

Jan 12, 2013 at 6:31 PM

What would switching to ODataMediaTypeFormatter entail for my service? Does it change the exposed API?