简体   繁体   中英

get a method to return json in C# and asp.net MVC 2 or 3

i use JSon to return allot of results when building a website, but find myself writing aa lot of code like this:

 return Json((
                    from s in searchResults
                    select new { 
                      orderID = s.OrderID,
                      OrderRealID = s.OrderRealID,
                      OrderStatus = s.OrderStatus,
                      OrderDate = s.OrderDate,
                      OrderVenue = s.VenueName + " - " + s.VenueLocation + " (" + s.VenueNumber + ")",
                      OrderStatusText = s.StatusOrderValue
                    }
                ), JsonRequestBehavior.DenyGet);

what i would like to do is something like this:

 public string ResultsToJson<T>(hashtable fields){
                    from s in T
                    select new { 
                      // loop through hash table
                    } }

and then simply call this function with whatever IEnumerable results i have my question is would i be on the right lines here, what would be the best possible way to do this as it makes no sense to be writing in MVC and OOP but to keep rewriting code to just FROM ? IN ? all the time.

many thanks

Have you had a look at System.Web.Script.Serialization.JavaScriptSerializer . The class will serialize data for you into a JSON string

You could then use jQuery.parseJson(...) if you wish to consume in on the client.

What types does your hashtable ( Dictionary<T,T> since 2.0) hold? If it's a plain Dictionary<string,string> then you could write the JSON yourself fairly trivially.

If it has a set of types that have more types inside, all the way down to the leaf nodes then it will be worth looking at the JSON.NET library instead, as it has far more advanced JSON capabilities than the standard .NET JSON serializer.

You could use Reflection to iterate through all properties. But use cache with it as it is painfully slow.

Here is a snippet from one of my test (educational) projects:

public class OneTwoThree
{
    public string One { get; set; }
    public string Two { get; set; }
    public string Three { get; set; }
}

/// <summary>
/// Should serialize the anonymous object
/// and deserialize it into a strong type.
/// </summary>
/// <remarks>
///     An MVC JSON result on the server can use anonymous objects that are serialized
///     into strong types on a rich client.
///
///     “Making use of your JSON data in Silverlight”
///     [http://timheuer.com/blog/archive/2008/05/06/use-json-data-in-silverlight.aspx]
///
///     “ASP.NET MVC: Using dynamic type to test controller actions returning JsonResult”
///     [http://weblogs.asp.net/gunnarpeipman/archive/2010/07/24/asp-net-mvc-using-dynamic-type-to-test-controller-actions-returning-jsonresult.aspx]
///
///     “ASP.NET MVC – Unit Testing JsonResult Returning Anonymous Types”
///     [http://www.heartysoft.com/post/2010/05/25/ASPNET-MVC-Unit-Testing-JsonResult-Returning-Anonymous-Types.aspx]
///
///     “.NET 3.5: JSON Serialization using the DataContractJsonSerializer”
///     [http://pietschsoft.com/post/2008/02/NET-35-JSON-Serialization-using-the-DataContractJsonSerializer.aspx]
/// </remarks>
[TestMethod]
public void ShouldSerializeAnonymousObject()
{
    var data = new
    {
        One = "uno",
        Two = "dos",
        Three = "tres"
    };

    var result = new JsonResult
    {
        Data = data,
        ContentEncoding = Encoding.Unicode
    };

    var serializer = new JavaScriptSerializer();

    var actual = serializer.Serialize(result.Data);
    var expected = @"{""One"":""uno"",""Two"":""dos"",""Three"":""tres""}";
    Assert.AreEqual(expected, actual);

    var clientSerializer = new DataContractJsonSerializer(typeof(OneTwoThree));

    using(var stream = new MemoryStream(Encoding.Unicode.GetBytes(actual)))
    {
        var clientObject = clientSerializer.ReadObject(stream) as OneTwoThree;
        Assert.IsNotNull(clientObject);
    }
}

/// <summary>
/// Should serialize the generic dictionary
/// and deserialize it.
/// </summary>
[TestMethod]
public void ShouldSerializeGenericDictionary()
{
    var dictionary = new Dictionary<string, string>();
    dictionary.Add("One", "uno");
    dictionary.Add("Two", "dos");
    dictionary.Add("Three", "tres");

    var result = new JsonResult
    {
        Data = dictionary,
        ContentEncoding = Encoding.Unicode
    };

    var serializer = new JavaScriptSerializer();

    var actual = serializer.Serialize(result.Data);
    var expected = @"{""One"":""uno"",""Two"":""dos"",""Three"":""tres""}";
    Assert.AreEqual(expected, actual);

    var clientSerializer = new DataContractJsonSerializer(typeof(Dictionary<string, string>));

    using(var stream = new MemoryStream(Encoding.Unicode.GetBytes(actual)))
    {
        var clientObject = clientSerializer.ReadObject(stream) as Dictionary<string, string>;
        Assert.IsNotNull(clientObject);
    }
}

I'm curious, why not do this?

return Json(searchResults, JsonRequestBehavior.DenyGet);

That uses JavaScriptSerializer under the hood, which handles a fairly large range of types. As long as you don't have any circular references, a simple collection of flat objects (per your example) shouldn't be a problem for the built-in serializer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM