6
public class ContactsController : ApiController
{
    private static readonly List<Contact> _contacts = new List<Contact>();
    public Contact PutContacts(int id, Contact contact)
    {
        if (_contacts.Any(c => c.Id == contact.Id) == false)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        contact.LastModified = DateTime.Now;
        return contact;
    }
}

httpプットヘッダー:

PUT /api/contacts/3 HTTP/1.1
User-Agent: Fiddler
Content-Type: application/json
Host: localhost:8080

体:

{"Id":3,"Name":"mmm","Phone":"000 000 0000","Email":"mmm@gmail.com","LastModified":"2012-03-08T23:42:13.8681395+08:00"}

応答:

HTTP/1.1 400 Bad Request
"The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'SelfHost.Contact PutContacts(Int32, SelfHost.Contact)' in 'SelfHost.ContactsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."

なんで?ありがとう。

PS:

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

3 に答える 3

2

私はこれと同じ問題を抱えています。クエリパラメータ「id」はnullで、オブジェクト「contact」が入力されています。これはモデルバインディングの問題だと思います。コントローラにブレークポイントを設定する場合は、次の式を見てください。

this.ControllerContext.RouteData.Values["id"]

ルートデータに値があることがわかります。モデルに設定されていないだけです。私はActionFilterを持っていて、そこにもブレークポイントを置くと、actionContextのActionArgumentにそのキーがありますが、null値であることがわかります。

私はまだ研究しています...

于 2012-04-03T19:40:42.317 に答える
1

あなたが説明している問題を再現できません。

モデル:

public class Contact
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }
    public string Email { get; set; }
    public DateTime LastModified { get; set; }
}

コントローラ:

public class ContactsController : ApiController
{
    public Contact Put(int id, Contact contact)
    {
        return contact;
    }
}

クライアント:

class Program
{
    static void Main()
    {
        using (var client = new WebClient())
        {
            client.Headers[HttpRequestHeader.ContentType] = "application/json";
            var data = Encoding.UTF8.GetBytes(@"{""Id"":3,""Name"":""mmm"",""Phone"":""000 000 0000"",""Email"":""mmm@gmail.com"",""LastModified"":""2012-03-08T23:42:13.8681395+08:00""}");
            var result = client.UploadData("http://localhost:1405/api/contacts/4", "PUT", data);
            Console.WriteLine(Encoding.UTF8.GetString(result));
        }
    }
}

クライアントを実行すると、次のリクエストが送信されます。

PUT /api/contacts/4 HTTP/1.1
Content-Type: application/json
Host: localhost:1405
Content-Length: 119
Expect: 100-continue
Connection: Keep-Alive

{"Id":3,"Name":"mmm","Phone":"000 000 0000","Email":"mmm@gmail.com","LastModified":"2012-03-08T23:42:13.8681395+08:00"}

サーバーから正しい結果が得られます。したがって、表示されているリクエストは、サーバーに送信されている実際のリクエストではないと思います。

于 2012-03-08T16:49:29.637 に答える
0

craigtadlock、あなたの助けとマイクロソフトにバグを送ってくれてありがとう。私はPUTでも同じ問題を抱えていました。それらのどれも機能しませんでした。回避策として、PUTを処理するためにPOSTをハッキングしました。サーバーに投稿しているオブジェクトがすでにそのIDを持っている場合、POSTコードはそれをそのIDを持つPUTとして扱います。擬似コードは次のとおりです。

public HttpResponseMessage<MyClass> PostMyClass(MyClass myObject)
{
    if( myObject.ID != 0 ){
         //do PUT code
    }else{
         //do POST code
    }
}
于 2012-05-05T14:32:15.243 に答える