2017-07-27 1 views
1

Einfache ApiController Methode:Asp.Net Web-API-2-Modell nicht automatisch verbindlich

public class TestController : ApiController 
{ 
    public void TakeIt(MyObject o){ 
     Console.Write(o.ToString()); 
    } 
} 

Einfacher Datentyp:

public class MyObject{ 
    public string V1{ get; set; } 
    public string V2{ get; set; } 
} 

Einfach Beitrag:

POST http://localhost:11026/api/test/takeit HTTP/1.1 
Accept: application/json 
Content-Type: application/json 
Host: localhost:11026 

{"V1":"Something","V2": "Something else"} 

Aus irgendeinem Grunde der MyObject o wird nicht automatisch aus dem JSON-Formular post-body (auch mit [FromBody] eingefügt vor dem Parameter) binden auf der Methode.

Mache ich etwas falsch?

SOLUTION (DUH!)

Um meine eingehenden Anfragen zu debuggen, hatte ich dies in meinem global.asax setzen (weil ich versagte die Anträge zu erhalten durch Fiddler fließen), so konnte ich sie zuerst prüfen

protected void Application_BeginRequest() 
    { 
     using (Stream receiveStream = Request.InputStream) 
     { 
      using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8)) 
      { 
       var content = readStream.ReadToEnd(); 
       Console.WriteLine(content); 
      } 
     } 
    } 

Dies war etwas auf der ganzen Linie durch das Lesen der veröffentlichten Daten zu stoppen. Sobald ich das entfernte, funktionierte die automatische Modellbindung gut.

Antwort

1

Ich denke, Sie müssen entweder Ihre Methode mit [HttpPost] dekorieren oder sie zu PostTakeIt umbenennen. Die Web-API verwendet standardmäßig GET, glaube ich.

1

Zwei Dinge

public class TestController : ApiController 
{ 
    [HttpPost] 
    public void TakeIt([FromBody]MyObject o){ 
     Console.Write(o.ToString()); 
    } 
} 

Tag die Aktion mit HttpPost wie es Konvention basiertes Routing zu entsprechen, und am nächsten Tag der Parameter mit [FromBody] so das Modell Bindemittel wissen, wo für das Modell aussieht nicht wirklich ist.

Auch unter der URI api/test/takeit wird hier angenommen, dass die Routenvorlage api/{controller}/{action} ist.

Die Standardvorlage ist in der Regel api/{controller}/

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

, die nicht für die Aktion Namen nicht gerecht zu werden.

würden Sie entweder eine andere Route hinzufügen

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

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

oder Verwendung Attribut Routing

// Attribute routing. 
config.MapHttpAttributeRoutes(); 

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

Mit aktualisierten Controller

[RoutePrefix("api/test")] 
public class TestController : ApiController 
{ 
    [HttpPost] 
    [Route("takeit")] //Matches POST api/test/takeit 
    public IHttpActionResult TakeIt([FromBody]MyObject o){ 
     Console.Write(o.ToString()); 
     return Ok(); 
    } 
} 
+0

ich gesagt haben sollte ausdrücklich, dass ich die API Route geändert mapper zu "api/{controller}/{aktion}/{id}". Leider macht weder das Hinzufügen von [FromBody] zum Parameter noch von [HttpPost] zur Methode einen Unterschied für die Bindung meines Controllers. Ich habe das Gefühl, es ist eine Konfigurationseinstellung, die irgendwo fehlt. – Jimbo

+0

@ Jimbo Ich würde zustimmen müssen. Es gibt nicht genug Informationen im OP für die Verwendung zu sagen, obwohl. Stellen Sie ein [mcve] bereit, mit dem Sie Ihr Problem reproduzieren und eine Lösung finden können. – Nkosi

+0

Verdammt, ich wusste, es war etwas Einfaches ... Ich habe mehr Informationen in meinem OP erklärt, warum das nicht funktioniert.Danke für Ihr Bemühen. – Jimbo

Verwandte Themen