12

Ich versuche, JSON-Daten an eine Web-API-Methode zu senden, aber die JSON-Daten sind nicht an das Modell gebunden.ASP.Net Web Api nicht bindendes Modell auf POST

Hier ist mein Modell:

[DataContract] 
public class RegisterDataModel 
{ 
    [DataMember(IsRequired = true)] 
    public String SiteKey { get; set; } 

    [DataMember(IsRequired = true)] 
    public String UserId { get; set; } 

    [DataMember(IsRequired = true)] 
    public String UserName { get; set; } 
} 

Hier ist meine Web-Api Aktion:

public class RegisterController : ApiController 
    { 
    public Guid Post([ModelBinder] RegisterDataModel registerDataModel) 
    { 
     if (!ModelState.IsValid) 
     { 
      throw new ModelStateApiException(ModelState); 
     } 
     var userProfileDataContract = userProfileBusinessLibrary.GetNewOne(); 
     userProfileDataContract.UserId = registerDataModel.UserId; 
     userProfileDataContract.UserName = registerDataModel.UserName; 

     var userKey = userProfileBusinessLibrary.Register(registerDataModel.SiteKey, userProfileDataContract); 

     return userKey; 
    } 
    } 

Bevor ich hinzugefügt [Modelbinder], registerDataModel war null. Nach dem Hinzufügen von [ModelBinder] ist registerDataModel eine RegisterDataModel-Instanz, aber alle Eigenschaftswerte sind null.

Hier ist meine Anfrage über Fiddler:

http://local.testwebsite.com/api/register 

Request Headers: 
User-Agent: Fiddler 
Host: local.testwebsite.com 
Content-Length: 89 
Content-Type: application/json; charset=utf-8: 

Request Body: 
{ 
"SiteKey":"qwerty", 
"UserId": "12345qwerty", 
"UserName":"john q" 
}  

Was bin ich dabei meine Post-Daten binden an die RegisterDataModel Eigenschaften zu machen? Danke für Ihre Hilfe.

+0

Möglicherweise benötigen Sie nur das '[Post]' - Attribut auf Ihrer Controller-Aktion. – McGarnagle

+1

Danke für die Antwort, aber das Hinzufügen von [HttpPost] hat nicht geholfen. Es ist mein Verständnis mit WebApi, dass Sie die HTTP-Verb-Attribute nicht benötigen, da ASP.net MVC eine Konvention verwendet, das Verb mit der Controller-Aktion abzugleichen. –

Antwort

10

Wie erstellen Sie die JSON-Anfrage? Durch Fiddler Request Builder? Versuchen Sie Folgendes in dem Anfragetext.

{ 
"SiteKey":"qwerty", 
"UserId": "12345qwerty", 
"UserName":"john q" 
} 

Ich rate 'Request Body:' ist auch Teil Ihrer Anfrage Körper. Entferne das und überprüfe es.

+0

Ich verwende Fiddlers Composer, um die JSON-Daten an meine Web-API zu übermitteln. Hier ist ein Screenshot: http://screencast.com/t/x2IH6hp01rGQ –

+0

Wenn ich nur den [ModelBinder] entferne, funktioniert es perfekt für mich. Ich kopiere einfach deinen Code und teste es. Ein Unterschied, den ich hier sehe, ist, dass deine Inhaltslänge 89 ist. Meine ist 64 für genau die gleiche Nutzlast. Deshalb schätze ich, dass Sie etwas wie "Anfragetext" senden: – Badri

+4

Oh, übrigens, es gibt einen zusätzlichen Doppelpunkt oder ein Semikolon neben utf-8 Content-Type: application/json; charset = utf-8: Entfernen Sie das und versuchen Sie es bitte – Badri

11

nicht auf das Problem des OP verwendet, aber der Titel der Frage führte mich hier, als ich (öffentlich) verwenden Felder statt Eigenschaften in der Modellklasse (das heißt keine {get; set;}). Es stellte sich heraus, dass dies auch dazu führt, dass die Bindung fehlschlägt.

Vielleicht hilft jemand.

+1

Ich hatte genau das selbe Problem und fügte ein get hinzu und löste dies. –

+1

Das hat mir auch geholfen. Freut mich zu sehen, dass es nicht gelöscht wurde, es gehört definitiv zu diesem Fragetitel, auch wenn OP schon Eigenschaften hatte. –

+0

Das hat mir geholfen. Danke vielmals! – pwaivers

0

In meinem Fall werden App-Anfragen über eine Middleware namens "API Manager" zur Authentifizierung/Autorisierung weitergeleitet, bevor sie an meine .NET Web API weitergeleitet werden. Der POST-Parameter ist nicht gebunden, weil ich aus irgendeinem Grund nicht weiß, warum die "Content-Length" von den Headern ausgegeben wird. Der Grund dafür ist, dass der standardmäßige JsonMediaTypeFormatter die Inhaltslänge der Anfragen immer vor der Modellbindung prüft. und wenn die Inhaltslänge nicht dargestellt wird, wird der Parameter auf NULL gesetzt.