2013-12-16 22 views
13

costruisco la mia lista come questa:ritorno JSON da elenco generico in API Web

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

Utilizzando questo oggetto:

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

    public string Description { get; set; } 

    public string Url { get; set; } 
} 

ho iniziato ad usare l'IHttpActionResult, restituendo il bene (risultati); funzione. Credo che questo sia ciò che mi ha fatto iniziare la strada confusa. Avevo inviato con successo un ArrayList ma questo non serializzava come pensavo.

Ho provato a cambiarlo in ActionResult e ho tentato di restituire Json (risultato). Il risultato è la lista effettiva.

Vorrei continuare a utilizzare IhttpActionResult e inviare i dati serializzati con il metodo OK(). Mi sembra anche di avere un conflitto tra il serializzatore json integrato e il serializzatore json NewtonSoft.

Cosa dovrei usare. Qual è il modo più semplice di serializzare semplicemente un elenco generico e passare il risultato nel metodo IHttpActionResult OK()?

Ho provato il JavaScriptSerializer ma restituisce XML non 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(); 

    } 
} 

Ecco la Json.Net Esempio:

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

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

Ho provato il MemoryStream ... bla bla bla ... niente sembra un approccio pulito e diretto e non esiste materia per questa soluzione specifica.

Vorrei iniziare con questo ...

Come posso serializzare un elenco generico a JSON?

Come posso inviare quel risultato tramite IHttpActionResult?

* Aggiornamento *

Questo è quello che sto ottenendo per la serializzazione da Json.Net. MA c'è qualcosa che non va nel formato ... Persino Fiddler non può determinare che sia Json. Il mio Header assomiglia a questo (in Fiddler):

Accept: application/json, text/javascript, /; q = 0,01

"[{\" titolo \ ": \" Lacidofil ® \ "\ "description \": \" Lacidofil ® caratteristiche Institut Rosell ’ s Lactobacillus helveticus e Lactobacillus rhamnosus. Entrambi questi ceppi sono stati ampiamente studiati nelle sperimentazioni cliniche umane, possiedono un ... \ ", \" url \ ": \"/products/product-detail.aspx? Pid = 103 \ "}, {\" title \ ": \" MedCaps GI ™ \ ", \" description \ ": \" MedCaps GI ™ contiene ingredienti progettati per supportare nutrizionalmente l'integrità e la funzione ottimale del rivestimento gastrointestinale. Fortificato con sostanze nutritive come l-glutam ... \ ", \" url \ ": \"/products/product-detail.aspx?pid = 114 \ "}, {\" title \ ": \" OrganiX ™ PhytoFood ™ \ ", \" description \ ": \" OrganiX PhytoFood è una formulazione in polvere conveniente che fornisce i nutrienti chiave   per supportare uno stile di vita sano. Questa formula completa incorpora   una miscela innovativa di organi ... \ ", \" url \ ": \"/products/product-detail.aspx? Pid = 271 \ "}, {\" title \ ": \" Probio Defense ™ \ ", \" description \ ": \" Probio Defense ™ è una combinazione ottimale di batteri probiotici che supporta il sistema immunitario. \ R \ nIl prodotto contiene: \ r \ n \ r \ nLactobacillus helveticus Rosell-52 (3 miliardi) \ r \ nLactobacillu ... \ ", \" url \ ": \"/products/product-detail.aspx? pid = 102 \ "}, {\" title \ ": \" ProbioMax Daily DF ™ \ ", \" descrizione \ ": \" ProbioMax Daily DF ™ è un probiotico vegetariano, da latte e senza glutine, a quattro ceppi per un totale di 30 miliardi di CFU e pugnale; per capsula. Ogni capsula vegetale è sigillata in alu ... \ ", \" url \ ": \"/products/product-detail.aspx? Pid = 181 \ "}, {\" title \ ": \" ProbioMax DF ™ \ ", \" description \ ": \" ProbioMax DF ™ è un probiotico vegetariano, da latte e senza glutine, a quattro ceppi per un totale di 100 miliardi di CFU e pugnale; per capsula. Ogni capsula vegetale è sigillata in alluminio purificato con azoto ... \ ", \" url \ ": \"/products/product-detail.aspx? Pid = 184 \ "}, {\" title \ ": \" ProbioMax Plus DF ™ \ ", \" description \ ": \" La moltitudine di benefici salutari raggiunti dall'individuo   integrazione di ceppi probiotici di batteri, il lievito non patogeno  , Saccharomyces boulardii, immunoglobuline, ... \ ", \ "url \": \ "/ products/product-detail.aspx? pid = 185 \"}, {\ "title \": \ "Saccharomycin DF ™ \", \ "description \": \ "Saccharomycin DF ™ è una formula resistente, priva di lattosio, resistente allo stomaco –, stabile, in attesa di brevetto europeo contenente Saccharomyces boulardii verificato dal DNA. Questo supporto lievito probiotico ... \ "\ "URL \": \ "/ Prodotti/Product-detail.aspx pid = 197 \"}]"

+0

Hai guardato in Json.Net? –

+0

Questo fa parte del problema, sto ottenendo un conflitto tra il default e newtonoft. –

+1

Ho pensato che l'API Web già utilizzato JSON.NET per impostazione predefinita. In quello che ho scritto, restituisco sempre il mio oggetto, a meno che non voglia specificamente restituire il codice di errore HTTP. In questo modo se il tuo cliente vuole usare XML invece di JSON, non hai più lavoro da fare. –

risposta

10

Colgo l'approccio che sembra molto più semplice e non comporta la modifica il serializzatore jSON per i dati che avete .

Se si restituiscono gli oggetti come un elenco, il formattatore del tipo di supporto predefinito gestirà la serializzazione in base al tipo di contenuto specificato dal client (purché sia ​​json o xml).

Per scopi dimostrativi aggiungere i seguenti metodi che restituiscono oggetti codificati.

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

    } 

Poi nel violinista specificare il cliente accetta application/json come nella foto qui sotto e il contenuto viene restituito come json.

enter image description here

Per ulteriori informazioni sulla serializzazione vedere qui:

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

+0

L'intestazione è corretta. Gli oggetti sono popolati correttamente. Aggiornare come appare il risultato nella mia domanda. –

+0

Ho evidenziato il risultato JSON che ritorna dalla mia app dimostrativa nella schermata sopra, la scatola gialla. Non è quello che stai cercando? – hutchonoid

+0

Se lo si modifica per restituire gli oggetti così come sono senza serializzarli, dovrebbe funzionare correttamente. Come nel mio esempio sopra, l'unica differenza è che non li sto leggendo da un db. – hutchonoid

1

solito serializzare JSON utilizzare questo metodo di estensione? :

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 
    } 

non dimenticate di aggiungere il tramite e il riferimento a:

System.Runtime.Serialization.Json; 
+1

Non è necessario, a meno che non sia necessario personalizzare la formattazione JSON. L'istanza MediaTypeFormatter nella pipeline Http di Web API gestisce la serializzazione su JSON/XML e la de-serializzazione sui tipi CLR. – dotnetguy