1

ASP.NET Web API とコントローラー クラスを使用して、クライアントからの JSON データを処理しています。1 つのコントローラーに複数の Put メソッドが必要な状況に遭遇しました。

例:

私が持つことができた私のクライアント

var box = {size:2,color:'red',height:45,width:12}

ボックスオブジェクト全体を更新したい場合は、

public void Put(Box box)
 {
 }

わかりました、私はこれだけ得ました。

しかし、次のようにボックスの単一の値を更新できる必要があります。

    public void Put(int id, width value)
    {

    }
    public void Put(int id, height value)
    {

    }
    public void Put(int id, color value)
    {

    }

追加の Put 動詞を .net c# コントローラー内からマップするにはどうすればよいですか?


作成した賞金用のコードをさらに追加します。私が提供しているコードを機能させる方法を教えてくれる人が必要です。複数のメソッドを1つにマッピングする必要がありますhttpVERB PUT。サーバー上のアイテムをマイクロ更新する必要があるためです。name と同様に、ネットワークを介して大きなオブジェクトを送信して 1 つのフィールドを更新したくありません。これは、私のプログラムがモバイル デバイスにも接続されるためです。

---このコードは機能せず、 を返すだけPutNamePutBrand. 私はあなたが想像できるほぼすべての方法で署名を切り替えました。

    [AcceptVerbs("PUT")]
    [ActionName("PutBrand")]
    public HttpResponseMessage PutBrand(int id, int val)
    {
        return Request.CreateResponse(HttpStatusCode.Created, "Brand");
    }
    [AcceptVerbs("PUT")]
    [ActionName("PutName")]
    public HttpResponseMessage PutName(IDString idString)
    {
        return Request.CreateResponse(HttpStatusCode.Created, "Name");
    }
public class IDString
{
    public IDString() { }
    public int ID { get; set; }
    public string Value { get; set; }
}

- - クライアント

   $.ajax(
                         {
                             url: "/api/project",
                             type: "PUT",
                             data: JSON.stringify({ id: 45, val:'xxx' }),
                             contentType: "application/json",
                             success: function (result) {

                             }
                         });

---ルート設定

 public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

提案された解決策

              $.ajax(
                 {
                     url: "/api/project?a=name",
                     type: "PUT",

              $.ajax(
                 {
                     url: "/api/project?a=brand",
                     type: "PUT",

              $.ajax(
                 {
                     url: "/api/project?a=size",
                     type: "PUT",

もちろん、a=myJavaScriptVariable の代わりに変数を使用します。

     public HttpResponseMessage Put(Project project)
        {



  string update = HttpContext.Current.Request.QueryString["a"];
        switch (update)
        {
            case "name":
                break;
            case "brand":
                break;
            case "size":
                break;

            default:
                break;
        }
        return Request.CreateResponse(HttpStatusCode.Accepted);
    }
4

3 に答える 3

5

HTTP動詞はアクションの名前ではなく、注釈です。

このように、コントローラーは次のようになります。

[VERB]
public ActionResult SomeMeaningfulName(ARGUMENTS)
{
//...
}

VERBは、、、またはのいずれかHttpDeleteですHttpPostHttpPutHttpGet

お役に立てれば。

よろしく


更新:上記の答えは、ASP.NETMVCアプリにも当てはまります。ただし、WebAPIアプリについて話している場合は、アクションの動詞を設定する別のオプションがあります。WebAPIは、有効なHTTP動詞である限り、アクション名動詞として理解する規則を使用します。アクションには意味のある名前が付いている場合もありますが、動詞で始まる必要があります。この投稿でより多くの情報。

これを指摘してくれた@Anandに感謝します(そして私に理解させるための努力=))。

于 2012-07-19T23:20:11.587 に答える
2

ActionName属性を使用して、この属性を持つすべてのアクションを同じ名前で呼び出すことができます。

[ActionName("Put")]
 public void PutWidth(int id, width value)
    {

    }
[ActionName("Put")]
    public void PutHeight(int id, height value)
    {

    }
[ActionName("Put")]
    public void PutColor(int id, color value)
    {

    }
于 2012-07-19T23:24:52.187 に答える
0

正直に言うと、ソリューションは、RESTスタイルのコーディングではなく、RPCスタイルのコーディングに移行します。

CRUD機能を実行するには、まずURLについて考えてください。

"/ box / {id}"

これは、すべてのCRUD機能を実行するのに十分なはずです。さらに、Web APIのマッチングセマンティクスは、以下のルールに従います。

  1. アクションの名前と動詞が一致します
  2. メソッドシグニチャに一致します(したがって、2つのget、1つのパラメータなし、およびその他のパラメータ付き)

同じ動詞と同じ署名を持つメソッドがある場合、せいぜい、最初に定義されたメソッドが呼び出されます。

ボックスの単一のプロパティを一度に更新する必要があるため、putの複数のメソッドを作成する理由を理解できました。それは次のように少しのトリックで達成することができます。クライアントからは、更新された値のみを送信します。たとえば、高さのみが変更されたとします。したがって、次のBoxオブジェクトをサーバーに送信します

//send only Id and height
var data = {size:null,color:null,height:45,width:null,id: 91}
 $.ajax(
                         {
                             url: "/api/project",
                             type: "PUT",
                             data: JSON.stringify(data),
                             contentType: "application/json",
                             success: function (result) {

                           }
                     });

また、サーバー上で、更新する前にどのフィールドがnullであるかを確認してください。私のコードは、Entity Frameの作業を使用していることを前提としていますが、どのDBでも同じように記述されています。

public void Put(Box box)
{
   //fetch the item from DB
   var item = _db.Box.First(i => i.id = box.id);
   if(item == null)
     // If you can't find the box to update
    throw new HttpResponseException(HttpStatusCode.NotFound);

   //check for properties if not null
   if(box.height != null)
      item.height= box.height;
   if(box.width!= null)
      item.width= box.width;
   if(box.color!= null)
      item.color= box.color;
   if(box.size!= null)
      item.size= box.size;  
   //update the item in database
  _db.SaveChanges();
  return new HttpResponseMessage<Box>(HttpStatusCode.Accepted);
}
于 2012-07-23T06:10:38.887 に答える