2014-04-17 24 views
7

Ciao Mi piacerebbe chiamare il metodo Web Api dal client C# dalla variabile del mio corpo nel controller web api è sempre nullo. Come impostarlo correttamente? lato client:Web Api FromBody è nullo dal client Web

IFileService imgService = new ImageServiceBll(); 
var image = System.Drawing.Image.FromFile(serverFile); 
var dataImage = imgService.ImageToBase64(image, System.Drawing.Imaging.ImageFormat.Png); 

using (var client = new HttpClient()) 
{ 
    client.BaseAddress = new Uri("http://site.local/"); 
    client.DefaultRequestHeaders.Accept.Clear(); 
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

    // HTTP POST 
    var data = new 
    { 
     imageData = dataImage, 
     version = version 
    }; 

    HttpResponseMessage response = await client.PostAsJsonAsync("api/contenttool/SaveImage", data); 
    if (response.IsSuccessStatusCode) 
    { 
     Uri gizmoUrl = response.Headers.Location; 
    } 
} 

Server Side:

public class ContentToolController : ApiController 
{ 
    public IFileService FileService { get; set; } 
    // POST api/contenttool 
    public string SaveImage([FromBody]string data) 
    { 
     JObject jObject = JObject.Parse(data); 
     JObject version = (JObject)jObject["version"]; 

     return "-OK-" + version; 
    } 
} 

risposta

19

Penso che abbia più a che fare con il fatto che tecnicamente non stai passando una stringa. Stai trasmettendo una rappresentazione stringa serializzata JSON di un tipo anonimo, quindi il processo di deserializzazione in Web Api sta funzionando contro di te. Nel momento in cui la richiesta arriva al controller e a quel metodo, non è più una stringa. Prova a cambiare il tuo tipo sul metodo SavImage per essere dinamico. In questo modo:

public string SavImage([FromBody]dynamic data) 
{ 
     JObject jObject = JObject.Parse(data); 
     JObject version = (JObject)jObject["version"]; 

     return "-OK-" + version; 
} 

Sfortunatamente a quel punto non sarà possibile utilizzare intellisense per ottenere le proprietà. Dovrai ottenere i dati dal tipo dinamico tramite un dizionario.

Dictionary<string, object> obj = JsonConvert.DeserializeObject<Dictionary<string, object>>(Convert.ToString(data)); 

Naturalmente l'altra opzione sarebbe quella di utilizzare un tipo effettivo condiviso tra il client e il server. Ciò renderebbe questo un po 'più facile.

+0

buon punto, ma ho trovato se inviare param come una stringa a PostAsJsonAsync funzionerebbe bene. –

+1

Si sta davvero lavorando contro il sistema. Inviare i dati come stringa e associare come stringa, O inviare come JSON e associare allo stesso oggetto dati sul lato WebAPI. Il secondo modo è il modo giusto per farlo. Così eviti di scrivere codice di manipolazione json specifico nel tuo metodo di azione, il framework è lì per te. –

+0

@YishaiGalatzer Sono d'accordo per la maggior parte con questo, ma se voglio serializzare una lista di oggetti, mi costringerebbe a creare un nuovo modello semplicemente per contenere una lista! Questo sembra pazzesco, vero? – Chris

1

Il valore della stringa passata nel corpo probabilmente ha bisogno di essere preceduto con il segno =.

+0

Cosa intendi? –

+1

Se si desidera passare una stringa 'Hello World' nel corpo, passarla come' = Hello World'. –

+0

Sembra che tu stia cercando di passare un oggetto JSON nel metodo. Un modo migliore sarebbe quello di avere un oggetto fortemente tipizzato come parametro del metodo 'SavImage' senza l'attributo' [FromBody] '(che è progettato per passare valori semplici). Le API Web dovrebbero occuparsi della serializzazione. –

Problemi correlati