web-dev-qa-db-ja.com

Web APIの汎用リストからJsonを返す

次のようにリストを作成します。

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

このオブジェクトの使用:

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

    public string Description { get; set; }

    public string Url { get; set; }
}

IHttpActionResultの使用を開始し、OK(results)を返しました。関数。これが私を混乱の道に導いたと信じています。 ArrayListを正常に送信しましたが、これは思っていた方法をシリアル化しませんでした。

ActionResultに変更して、実際のリストであるJson(result)Resultを返そうとしました。

IhttpActionResultを引き続き使用し、シリアル化されたデータをOK()メソッドで送信します。また、組み込みのjsonシリアライザーとNewtonSoft jsonシリアライザーの間で競合が発生しているようです。

何を使うべきですか。汎用リストをシリアル化し、その結果をIHttpActionResult OK()メソッドに渡す最も簡単な方法は何ですか?

JavaScriptSerializerを試しましたが、JsonではなくXMLを返します...

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();

    }
}

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

MemoryStreamを試しました...何とか何とか...何もきれいで、率直​​なアプローチとは思えません。この特定のソリューションの主題はありません。

これから始めましょう...

GenericリストをJsonにシリアル化するにはどうすればよいですか?

IHttpActionResultを使用してその結果を送信するにはどうすればよいですか?

* Update*

これは、Json.Netからのシリアル化で得られるものです。しかし、フォーマットに何か問題があります... Fiddlerでさえ、Jsonであると判断することはできません。私のヘッダーは次のようになります(Fiddlerで):

承認:application/json、text/javascript、/; q = 0.01

「[{\ "title \":\ "Lacidofil®\ "、\" description\":\"Lacidofil®は、Institut RosellのLactobacillus helveticusとLactobacillus rhamnosusを特徴としています。これらの株は両方とも人間の臨床試験で広く研究されており、...\"、\" url\":\"/products/product-detail.aspx?pid = 103\"}、{\" title\":\" MedCaps GI™\ "、\" description\":\" MedCaps GI™は、胃腸の内層の完全性と最適な機能を栄養的にサポートするように設計された成分を特徴としています。 l-glutam ...\"、\" url\":\"/products/product-detail.aspx?pid = 114\"}、{\" title\":\" OrganiX™PhytoFoodなどの栄養素で強化™\ "、\" description\":\" OrganiX PhytoFoodは、健康的なライフスタイルをサポートする重要な栄養素を提供する便利な粉末製剤です。この包括的な式には、組織の革新的なブレンドが組み込まれています...\"、\" url\":\"/products/product-detail.aspx?pid = 271\"}、{\" title\":\" Probio Defense ™\ "、\" description\":\" Probio Defense™は、免疫システムをサポートするプロバイオティクス細菌の最適な組み合わせです。\ r\nこの製品には、以下が含まれています。\ r\n\r\n )\ r\nLactobacillu ...\"、\" url\":\"/products/product-detail.aspx?pid = 102\"}、{\" title\":\" ProbioMax Daily DF™\ " 、\ "説明\":\ "ProbioMax Daily DF™は、ベジタリアン、乳製品、グルテンを含まない、4系統のプロバイオティクスで、カプセルあたり合計300億CFU†です。各ベジタリアンカプセルは、窒素でパージされたALU ...\"、\" url\":\"/products/product-detail.aspx?pid = 181\"}、{\" title\":\" ProbioMaxで密封されています。 DF™\ "、\" description\":\" ProbioMax DF™は、1カプセルあたり合計1,000億CFU†のベジタリアン、乳製品、グルテンを含まない4系統のプロバイオティクスです。各ベジタリアンカプセルは窒素パージされたアルミニウムで密閉されています...\"、\" url\":\"/products/product-detail.aspx?pid = 184\"}、{\" title\":\" ProbioMax Plus DF™\ "、\" description\":\"細菌のプロバイオティクス株、非病原性酵母、Saccharomyces boulardii、免疫グロブリン、...\"、\" url\":\"/products/product-detail.aspx?pid = 185\"}、{\" title\":\" Saccharomycin DF™\ "、\" description\":\" Saccharomycin DF™は乳糖ですDNA検証済みSaccharomyces boulardiiを含む、胃酸耐性のない安定した欧州特許出願中のフォーミュラ。このプロバイオティクス酵母のサポート...\"、\" url\":\"/products/product-detail.aspx?pid = 197\"}]"

13
Brett Spencer

私はこのアプローチを採用していますが、これははるかに単純で、所有するデータのJSONシリアライザーを変更する必要はありません。

オブジェクトをリストとして返す場合、デフォルトのメディアタイプフォーマッターは、クライアントから指定されたコンテンツタイプに基づいてシリアル化を処理します(jsonまたはxmlの場合)。

デモのために、ハードコードされたオブジェクトを返す以下のメソッドを追加します。

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

    }

次に、フィドラーで、クライアントがapplication/json以下に示すように、コンテンツはjsonとして返されます。

enter image description here

シリアル化の詳細については、次を参照してください。

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

10
hutchonoid

通常、この拡張メソッドを使用してJSONにシリアル化します。

    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
    }

使用と参照を追加することを忘れないでください:

System.Runtime.Serialization.Json;
1
Alex Siepman