web-dev-qa-db-fra.com

Renvoyer Json de la liste générique dans l'API Web

Je construis ma liste comme ceci:

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

Utilisation de cet objet:

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

    public string Description { get; set; }

    public string Url { get; set; }
}

J'ai commencé à utiliser IHttpActionResult, en renvoyant OK (résultats); une fonction. Je crois que c'est ce qui m'a lancé sur la route confuse. J'avais envoyé avec succès une liste de tableaux mais cela n'a pas sérialisé comme je le pensais.

J'ai essayé de le changer en ActionResult et j'ai essayé de renvoyer le résultat Json (résultat) étant la liste réelle.

Je souhaite continuer à utiliser IhttpActionResult et envoyer les données sérialisées avec la méthode OK (). Il semble également que j'aie un conflit entre le sérialiseur json intégré et le sérialiseur json NewtonSoft.

Que dois-je utiliser. Quelle est la manière la plus simple de sérialiser une liste générique et de passer le résultat à la méthode IHttpActionResult OK ()?

J'ai essayé le JavaScriptSerializer mais il retourne XML pas 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();

    }
}

Voici l'exemple Json.Net:

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

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

J'ai essayé le MemoryStream ... bla bla bla ... rien ne semble être une approche claire et simple et il n'y a pas de sujet pour cette solution spécifique.

Permettez-moi de commencer par ceci ...

Comment sérialiser une liste générique vers Json?

Comment puis-je envoyer ce résultat via IHttpActionResult?

* ( Mise à jour *

C'est ce que j'obtiens pour la sérialisation de Json.Net. MAIS quelque chose ne va pas avec le format ... Même Fiddler ne peut pas déterminer que c'est Json. Mon en-tête ressemble à ceci (dans Fiddler):

Accepter: application/json, texte/javascript, /; q = 0,01

"[{\" title\": \" Lacidofil®\ ", \" description\": \" Lacidofil® présente Lactobacillus helveticus et Lactobacillus rhamnosus de l'Institut Rosell. Ces deux souches ont été largement étudiées dans des essais cliniques humains, possèdent un ...\", \" url\": \"/products/product-detail.aspx? Pid = 103\"}, {\" title\": \" MedCaps GI ™\", \" description\": \" MedCaps GI ™ contient des ingrédients conçus pour soutenir nutritionnellement l'intégrité et la fonction optimale de la muqueuse gastro-intestinale. Enrichi en nutriments tels que le l-glutam ...\", \" url\": \"/products/product-detail.aspx? Pid = 114\"}, {\" title\": \" OrganiX ™ PhytoFood ™\", \" description\": \" OrganiX PhytoFood est une formulation en poudre pratique fournissant des nutriments essentiels pour soutenir un mode de vie sain. Cette formule complète incorpore un mélange innovant d'organi ...\", \" url\": \"/products/product-detail.aspx? Pid = 271\"}, {\" title\": \" Probio Defense ™\", \" description\": \" Probio Defense ™ est une combinaison optimale de bactéries probiotiques qui soutient le système immunitaire.\R\nCe produit contient:\r\n\r\nLactobacillus helveticus Rosell-52 (3 milliards )\r\nLactobacillu ...\", \" url\": \"/products/product-detail.aspx? pid = 102\"}, {\" title\": \" ProbioMax Daily DF ™\" ,\"description \":\"ProbioMax Daily DF ™ est un probiotique à quatre souches végétarien, sans produits laitiers et sans gluten totalisant 30 milliards d'UFC † par capsule. Chaque capsule végétarienne est scellée dans de l'ALU purgé à l'azote ...\", \" url\": \"/products/product-detail.aspx? Pid = 181\"}, {\" title\": \" ProbioMax DF ™\", \" description\": \" ProbioMax DF ™ est un probiotique à quatre souches végétarien, sans produits laitiers et sans gluten totalisant 100 milliards d'UFC † par capsule. Chaque capsule végétarienne est scellée dans de l'aluminium purgé à l'azote ...\", \" url\": \"/products/product-detail.aspx? Pid = 184\"}, {\" title\": \" ProbioMax Plus DF ™\", \" description\": \" La multitude d'avantages pour la santé obtenus par la supplémentation individuelle de souches probiotiques de bactéries, la levure non pathogène, Saccharomyces boulardii, les immunoglobulines, ...\", \" url\": \"/products/product-detail.aspx? pid = 185\"}, {\" title\": \" Saccharomycin DF ™\", \" description\": \" Saccharomycin DF ™ est un lactose sans gluten, résistant aux acides gastriques, stable, formule en instance de brevet européen contenant du Saccharomyces boulardii vérifié par l'ADN. Cette levure probiotique supporte ...\", \" url\": \"/products/product-detail.aspx? Pid = 197\"}]"

13
Brett Spencer

Je prends cette approche qui semble beaucoup plus simple et n'implique pas de changer le sérialiseur json pour les données que vous avez.

Si vous renvoyez les objets sous forme de liste, le formateur de type de support par défaut gérera la sérialisation en fonction du type de contenu spécifié par le client (à condition qu'il soit json ou xml).

À des fins de démonstration, ajoutez les méthodes ci-dessous qui renvoient des objets codés en dur.

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

    }

Ensuite, dans fiddler, spécifiez que le client accepte application/json comme illustré ci-dessous et le contenu est renvoyé sous la forme json.

enter image description here

Pour plus d'informations sur la sérialisation, voir ici:

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

10
hutchonoid

Je sérialise généralement en JSON en utilisant cette méthode d'extension:

    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
    }

N'oubliez pas d'ajouter l'utilisation et la référence à:

System.Runtime.Serialization.Json;
1
Alex Siepman