2014-04-17 15 views
7

Witam Chciałbym nazwać metodę Web Api z klienta C# przez moją zmienną body w kontrolerze web api jest null cały czas. Jak ustawić poprawność? strona klient:Web Api FromBody ma wartość zerową z klienta WWW

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; 
    } 
} 

Odpowiedz

19

Myślę, że ma to więcej wspólnego z faktem, że technicznie nie przekazujesz ciągu znaków. Przekazywane są ciągi reprezentowane przez JSON typu anonimowego, więc proces deserializacji w Web Api działa przeciwko Tobie. Do czasu, gdy twoje żądanie dotrze do kontrolera i tej metody, nie jest już ciągiem znaków. Spróbuj zmienić typ w metodzie SavImage, aby była dynamiczna. W ten sposób:

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

     return "-OK-" + version; 
} 

Niestety, w tym momencie nie będzie można użyć intellisense, aby uzyskać swoje właściwości. Będziesz musiał pobrać dane z dynamicznego typu za pomocą słownika.

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

Oczywiście inną opcją byłoby użycie rzeczywistego typu, który jest współdzielony między klientem a serwerem. To by ułatwiło to.

+0

dobry punkt, ale znalazłem, jeśli wysłać param jak ciąg do PostAsJsonAsync to działałoby dobrze. –

+1

Naprawdę działasz przeciwko systemowi. Wyślij dane jako ciąg i połącz jako ciąg, LUB wyślij jako JSON i połącz z tym samym obiektem danych po stronie interfejsu WebAPI. Drugi sposób to właściwa droga. W ten sposób unikasz pisania określonego kodu manipulacji jsonem w swojej metodzie akcji, framework jest tam, robisz to za ciebie. –

+0

@ YishaiGalatzer Zgadzam się w większości z tym, ale jeśli chcę serializować listę obiektów, zmusiłoby mnie to do stworzenia nowego modelu po prostu do przechowywania listy! To wydaje się szalone, prawda? – Chris

1

Wartość ciągu przekazywana w organizmie prawdopodobnie musi być poprzedzona znakiem =.

+0

Co masz na myśli? –

+1

Jeśli chcesz przekazać ciąg 'Hello World' w ciele, podaj go jako' = Hello World'. –

+0

Wygląda na to, że próbujesz przekazać obiekt JSON do metody. Lepszym sposobem byłoby mieć obiekt o silnym typie jako parametr metody "SavImage" bez atrybutu [FromBody] '(który jest naprawdę zaprojektowany do przekazywania prostych wartości). WebService powinien zająć się serializacją. –

Powiązane problemy