2013-12-16 19 views
13

buduję moją listę tak:Powrót Json z Generic listy w Web API

public static List<SearchFormula> SearchData(string searchString) 
{ 
    var searchResults = new List<SearchFormula>(); 

    SqlDataReader drResults = FormulaUtility.SearchFormulas(searchString); 

    if ((drResults != null) && (drResults.HasRows)) 
    {     
     while (drResults.Read()) 
     { 
      searchResults.Add(new SearchFormula() 
      { 
       // id use the GetValue function 
       Title = drResults.GetString(1), 
       Description = drResults.GetString(2), 
       Url = drResults.GetString(3) 
       // total use the GetValue Function 
       }); 
      } 
     } 
    return searchResults; 
} 

Korzystanie obiektu:

public class SearchFormula 
{ 
    public string Title { get; set; } 

    public string Description { get; set; } 

    public string Url { get; set; } 
} 

I zaczął używać IHttpActionResult, zwracając OK (wyników); funkcjonować. Wierzę, że właśnie to doprowadziło mnie do mylącej drogi. Udało mi się wysłać ArrayList, ale to nie serializuje tak, jak myślałem.

Próbowałem zmienić to na ActionResult i próbowałem zwrócić Json (wynik) Wynik będący rzeczywistą listą.

Chciałbym nadal używać IhttpActionResult i wysyłać zserializowane dane za pomocą metody OK(). Wydaje mi się również, że mam konflikt między wbudowanym serializatorem json a seriserem json NewtonSoft.

Co powinienem użyć. Jaki jest najprostszy sposób serializowania ogólnej listy i przekazania wyniku do metody IHttpActionResult OK()?

Próbowałem JavaScriptSerializer ale zwraca XML nie JSON ...

public class SearchController : ApiController 
{ 
    public IHttpActionResult Get(string searchTerm) 
    {    
     var jsonSerialiser = new JavaScriptSerializer(); 
     var jsonResult = jsonSerialiser.Serialize(SearchUtility.SearchData(searchTerm)); 

     if (jsonResult != null) 
     { 
      return Ok(jsonResult); 
     } 
     return NotFound(); 

    } 
} 

Oto Json.NET Przykład:

public class SearchController : ApiController 
{ 
    public IHttpActionResult Get(string searchTerm) 
    { 
     var jsonResult = JsonConvert.SerializeObject(SearchUtility.SearchData(searchTerm)); 

     if (jsonResult != null) 
     { 
      return Ok(jsonResult); 
     } 
     return NotFound();   
    } 
} 

Próbowałem MemoryStream ... bla bla bla ... nic nie wydaje się być czystym, prostym podejściem i nie ma żadnego przedmiotu dla tego konkretnego rozwiązania.

Zacznę od tego ...

Jak mogę serializacji Generic listy do formatu JSON?

Jak wysłać ten wynik przez IHttpActionResult?

* Aktualizacja *

To co ja dostaję do serializacji z Json.NET. ALE coś jest nie tak z formatem ... Nawet Fiddler nie może stwierdzić, że to Json. Mój nagłówek wygląda tak (w Fiddler):

Zaakceptuj: aplikacja/json, tekst/javascript, /; q = 0,01

"[{\" tytułowy \ ": \" Lacidofil ® \ "\ "opis \": \" Lacidofil ® wyposażony Instytut Rosell ’ s Lactobacillus helveticus i Lactobacillus rhamnosus. Oba te szczepy zostały szeroko przebadane w badaniach klinicznych u ludzi, posiadają ... \ ", \" url \ ": \"/products/product-detail.aspx? Pid = 103 \ "}, {\" tytuł \ ": \" MedCaps GI ™ \ ", \" opis \ ": \" MedCaps GI ™ zawiera składniki, które zostały zaprojektowane, aby odżywczo wspierać integralność i optymalne funkcjonowanie wyściółki żołądkowo-jelitowej. Wzbogacony o składniki odżywcze, takie jak l-glutam ... \ ", \" url \ ": \"/products/product-detail.aspx?pid = 114 \ "}, {\" title \ ": \" OrganiX ™ PhytoFood ™ \ ", \" opis \ ": \" OrganiX PhytoFood to wygodny sproszkowany preparat dostarczający kluczowych składników odżywczych dla utrzymania zdrowego stylu życia. Ta kompleksowa formuła zawiera   innowacyjną mieszankę organi ... \ ", \" url \ ": \"/products/product-detail.aspx? Pid = 271 \ "}, {\" title \ ": \" Probio Defense ™ \ ", \" description \ ": \" Probio Defence ™ to optymalna kombinacja bakterii probiotycznych, które wspierają układ odpornościowy. \ R \ nTen produkt zawiera: \ r \ n \ r \ nLactobacillus helveticus Rosell-52 (3 miliardów) \ r \ nLeactobacilllu ... \ ", \" url \ ": \"/products/product-detail.aspx? pid = 102 \ "}, {\" title \ ": \" ProbioMax Daily DF ™ \ ", \" description \ ": \" ProbioMax Daily DF ™ jest wegetariańskim probiotycznym probiotykiem o czterech i trzech grupach, pozbawionym mleka i glutenu, o łącznej wartości 30 miliardów CFU i sztyletu; na kapsułkę. Każda wegetariańska kapsuła jest zamknięta w azotowym przedmuchiwanym ... \ ", \" url \ ": \"/products/product-detail.aspx? Pid = 181 \ "}, {\" title \ ": \" ProbioMax DF ™ \ ", \" description \ ": \" ProbioMax DF ™ to wegetariański probiotyk probiotyczny o objętości czterech miliardów bakterii, bez mleczarstwa i glutenu o łącznej wartości 100 miliardów CFU i sztylet; na kapsułkę. Każda wegetariańska kapsuła jest zamknięta w azotowanym aluminium ... \ ", \" url \ ": \"/products/product-detail.aspx? Pid = 184 \ "}, {\" title \ ": \" ProbioMax Plus DF ™ \ ", \" description \ ": \" Mnogość korzyści zdrowotnych osiąganych dzięki indywidualnej suplementacji bakterii probiotycznych  , niepatogennych drożdży  , Saccharomyces boulardii, immunoglobulin, ... \ ", \ "url \": \ "/ products/product-detail.aspx? pid = 185 \"}, {\ "title \": \ "Saccharomycin DF ™ \", \ "description \": \ "Saccharomycin DF ™ jest niezawierający laktozy, odporny na kwas żołądkowy, odporny, stabilny, europejski zgłoszony do opatentowania preparat zawierający Saccharomyces boulardii zweryfikowany przez DNA. Ten probiotyk wsparcie drożdże ... \ "\ "url \": \ "/ produkty/product-detail.aspx pid = 197 \"}]"

+0

Pan spojrzał na Json.NET? –

+0

To jest część problemu, pojawia się konflikt między domyślnym a newtonsoft. –

+1

Myślałem, że Web API już domyślnie korzysta z JSON.NET. W tym, co napisałem, zawsze zwracam obiekt, chyba że specjalnie chcę zwrócić kod błędu HTTP. W ten sposób, jeśli twój klient chce używać XML zamiast JSON, nie musisz już wykonywać żadnej pracy. –

Odpowiedz

10

biorę to podejście, które wydaje się o wiele prostsza i nie wiązać zmiana serializatora json dla danych, które trzeba .

Jeśli obiekty zostaną zwrócone jako lista, domyślny format formatowania będzie obsługiwał serializację w oparciu o typ zawartości określony przez klienta (pod warunkiem, że jest to json lub xml).

Dla celów demonstracyjnych dodaj poniższe metody, które zwracają zakodowane obiekty.

// GET api/search 
    public List<SearchFormula> Get(string searchTerm) 
    { 
     var searchItems = SearchData(searchTerm); 
     return searchItems; 
    } 

    public static List<SearchFormula> SearchData(string searchString) 
    { 
     var searchResults = new List<SearchFormula>(); 

     searchResults.Add(new SearchFormula { Description = "desc1", Title = "title1", Url = "http://url.com" }); 
     searchResults.Add(new SearchFormula { Description = "desc2", Title = "title2", Url = "http://url.com" }); 

     return searchResults; 

    } 

Następnie w Fiddler określić klient akceptuje application/json jak na zdjęciu poniżej, a zawartość jest zwracany jako json.

enter image description here

W celu uzyskania dalszych informacji na temat serializacji zobaczyć tutaj:

http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization

+0

Nagłówek jest poprawny. Obiekty są wypełnione poprawnie. Aktualizuję wynik w moim pytaniu. –

+0

Podkreśliłem wynik json, który powraca z mojej aplikacji demo w powyższym grabu ekranu skrzypka, żółtym polu. Czy to nie json, którego szukasz? – hutchonoid

+0

Jeśli zmienisz go tak, aby po prostu zwracał obiekty bez numeru seryjnego, powinien działać poprawnie. Jak w moim przykładzie powyżej, jedyną różnicą jest to, że nie czytam ich z db. – hutchonoid

1

zwykle serializacji do JSON przy użyciu tej metody rozszerzenie? :

public static class Extensions 
{ 
    public static string SerializeToJson<T>(this T obj, DateTimeSerializationFormat format = DateTimeSerializationFormat.DotNet) where T : class 
    { 
     string result; 
     var serializer = new DataContractJsonSerializer(typeof(T)); 
     using (var stream = new MemoryStream()) 
     { 
      serializer.WriteObject(stream, obj); 
      result = Encoding.UTF8.GetString(stream.ToArray()); 
     } 

     if (formaat != DateTimeSerializationFormat.DotNet) 
     { 
      const string dotNetDateTimePattern = @"""\\/Date\((-?\d+)([\+-]\d{4})?\)\\/"""; 

      if (format ==DateTimeSerializationFormat.Iso8601 || format ==DateTimeSerializationFormat.Ruby)) 
      { 
       var matchEvaluator = new MatchEvaluator(ConvertJsonDateToIso8601DateString); 
       var regex = new Regex(dotNetDateTimePattern); 
       resultaat = regex.Replace(resultaat, matchEvaluator); 
       if (format == DateTimeSerializationFormat.Ruby && resultaat.Length > 10) // Ruby time 
       { 
        result = Regex.Replace(result, @"([\+-]\d{1,2}\:\d{2})", " $0"); // Add an space before the timeZone, for example bv "+01:00" becomes " +01:00" 
       } 
      } 

     } 
     return result; 
    } 

    public enum DateTimeSerializationFormat 
    { 
     /// <summary> 
     /// Example: "\/Date(1198908717056)\/" (aantal miliseconden na 1-1-1970) 
     /// </summary> 
     DotNet, 
     /// <summary> 
     /// Example: "1997-07-16T19:20:30.45+01:00" 
     /// </summary> 
     Iso8601, 
     /// <summary> 
     /// Example: "1997-07-16T19:20:30.45 +01:00" 
     /// </summary> 
     Ruby, 
     ///// <summary> 
     ///// Example: new Date(1198908717056) or other formats like new (date (1997,7,16) 
     ///// </summary> 
     //JavascriptDateObject 
    } 

nie zapomnij dodać używania i odniesienie do:

System.Runtime.Serialization.Json; 
+1

Nie potrzebujesz tego, chyba że chcesz dostosować formatowanie JSON. Instancja MediaTypeFormatter w potoku HTTP narzędzia Web API obsługuje serializację do JSON/XML i dekretyzację z powrotem do typów CLR. – dotnetguy