web-dev-qa-db-ja.com

Web APIを使用して部分的な更新を実行するために現在推奨されている方法は何ですか?

ASP.NET Web APIのRESTfulインターフェイスを使用して部分的な更新を実装する方法を知りたいですか?たとえば、次の構造のワイヤを介してオブジェクトを渡しているとします。

public class Person {
    public int Id { get; set; }
    public string Username { get; set; }
    public string Email { get; set; }
}

一度にPersonの一部、たとえばEmailプロパティの更新をどのようにサポートしますか? OData とPATCHバーブを介してこれを実装することをお勧めしますか、それとも自分でPATCHを実装する方が良いでしょうか?

22
aknuds1

Web APIの現在の最新stableリリース(2012年8月以降)ではサポートがありません。したがって、使用したいのがWeb API RTMだけの場合は、配管全体を自分で実装する必要があります。

そうは言っても、ODataプレリリースパッケージは、新しいDelta<T>オブジェクトを介して部分的な更新を非常にうまくサポートします。現在、Microsoft.AspNet.WebApi.ODataパッケージはすでにRCバージョン(0.3)であり、ここから入手できます: http://www.nuget.org/packages/Microsoft.AspNet.WebApi.OData ==

それをインストールすると、それに応じてそれを使用できます。

[AcceptVerbs("PATCH")]
public void Patch(int id, Delta<Person> person)
{
    var personFromDb = _personRepository.Get(id);
    person.Patch(personFromDb);
    _personRepository.Save();
}

そして、あなたはこのようにクライアントからそれを呼び出すでしょう:

$.ajax({
    url: 'api/person/1',
    type: 'PATCH',
    data: JSON.stringify(obj),
    dataType: 'json',
    contentType: 'application/json',
    success: function(callback) {            
       //handle errors, do stuff yada yada yada
    }
});

これの明らかな利点は、どのプロパティでも機能することであり、EmailまたはUsernameを更新するかどうかを気にする必要はありません。

非常によく似たテクニックを示しているので、この投稿も調べてみてください http://techbrij.com/http-patch-request-asp-net-webapi

EDIT(詳細):PATCHを使用するために、何も有効にする必要はありませんODataパッケージの追加を除いて、OData関連-Delta<TEntityType>オブジェクトへのアクセスを取得します。

次に、これを行うことができます。

public class ValuesController : ApiController
{
    private static List<Item> items = new List<Item> {new Item {Id = 1, Age = 1, Name = "Abc"}, new Item {Id = 2, Age = 10, Name = "Def"}, new Item {Id = 3, Age = 100, Name = "Ghj"}};

    public Item Get(int id)
    {
        return items.Find(i => i.Id == id);
    }

    [AcceptVerbs("PATCH")]
    public void Patch(int id, Delta<Item> item)
    {
        var itemDb = items.Find(i => i.Id == id);
        item.Patch(itemDb);
    }
}

あなたのアイテムがそうであるならば、言いましょう:

{
    "Id": 3,
    "Name": "hello",
    "Age": 100
}

次の方法で/api/values/3にパッチを当てることができます。

{
    "Name": "changed!"
}

これでオブジェクトが正しく更新されます。

Delta<TEntity>は変更を追跡します。これは、Typeの軽量プロキシとして機能する動的クラスであり、元のオブジェクト(つまり、DBから)とクライアントから渡されたオブジェクトの違いを理解します。

これは、APIの残りの部分にはまったく影響しません(もちろん、DLLを新しいものに置き換えてODataパッケージの依存関係を容易にすることを除いて)。

PATCH + Deltaの動作を示すサンプルプロジェクトを追加しました-ここで入手できます(it.s VS2012) https://www.dropbox.com/s/hq7wt3a2w84egbh/MvcApplication3.Zip

31
Filip W