简体   繁体   中英

JsonResult - how to return an empty JSON result?

I have an ajax call that makes a GET request to one of my controllers action methods.

The ajax call is supposed to get a JSON response and use that to populate a datagrid. The callback function is supposed to fire and construct the grid and hide the loading indicator.

$.getJSON('@Url.Action("Data", "PortfolioManager")' + '?gridName=revenueMyBacklogGrid&loginName=@Model.currentUser.Login', function (data) {

                        ConstructrevenueMyBacklogGrid(data);
                        $('#revenueMyBacklogLoadingIndicator').hide();

                    });

The problem is when the object I am converting to a JsonResult object has no data - it's just an empty collection.

returnJsonResult = Json(portfolioManagerPortalData.salesData.myYTDSalesClients, JsonRequestBehavior.AllowGet);

In this example it is the collection myYTDSalesClients that returns empty (which is ok and valid - sometimes there won't be any data).

The JSON object then returns an empty response (blank, nadda) and since it's not valid JSON, the callback function won't fire. Thus the loading indicator still shows and it looks like it's just loading forever.

So, how do I return an empty JSON result {} instead of a blank?

从 asp.net mvc 5 开始,您可以简单地编写:

Json(new EmptyResult(), JsonRequestBehavior.AllowGet)
if (portfolioManagerPortalData.salesData.myYTDSalesClients == null) {
    returnJsonResult = Json(new object[] { new object() }, JsonRequestBehavior.AllowGet);
}
else {
    returnJsonResult = Json(portfolioManagerPortalData.salesData.myYTDSalesClients, JsonRequestBehavior.AllowGet);
}

在 .Net Core 3.0 中,对于 ControllerBase 类型的控制器,您可以执行以下操作:

return new JsonResult(new object());

Use JSON.NET as a default Serializer for serializing JSON instead of default Javascript Serializer:

This will handle the scenario of sending data if its NULL.

For eg

Instead of this in your action method:

return Json(portfolioManagerPortalData.salesData.myYTDSalesClients, JsonRequestBehavior.AllowGet)

You need to write this in your action method:

return Json(portfolioManagerPortalData.salesData.myYTDSalesClients, null, null);

Note: 2nd and 3rd parameter null in above function is to facilitate overloads of Json method in Controller class.

Also you do not need to check for null in all of your action methods like above:

        if (portfolioManagerPortalData.salesData.myYTDSalesClients == null)
        {
            returnJsonResult = Json(new object[] { new object() }, JsonRequestBehavior.AllowGet);
        }
        else
        {
            returnJsonResult = Json(portfolioManagerPortalData.salesData.myYTDSalesClients, JsonRequestBehavior.AllowGet);
        }

Below is the code for JsonNetResult class.

public class JsonNetResult : JsonResult
{
    public JsonSerializerSettings SerializerSettings { get; set; }
    public Formatting Formatting { get; set; }

    public JsonNetResult()
    {
        SerializerSettings = new JsonSerializerSettings();
        JsonRequestBehavior = JsonRequestBehavior.AllowGet;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        HttpResponseBase response = context.HttpContext.Response;

        response.ContentType = !string.IsNullOrEmpty(ContentType)
          ? ContentType
          : "application/json";

        if (ContentEncoding != null)
            response.ContentEncoding = ContentEncoding;

        JsonTextWriter writer = new JsonTextWriter(response.Output) { Formatting = Formatting.Indented };

        JsonSerializer serializer = JsonSerializer.Create(SerializerSettings);
        serializer.Serialize(writer, Data);

        writer.Flush();
    }
}

Also You need to add below code in BaseController if any in your project:

    /// <summary>
    /// Creates a NewtonSoft.Json.JsonNetResult object that serializes the specified object to JavaScript Object Notation(JSON).
    /// </summary>
    /// <param name="data"></param>
    /// <param name="contentType"></param>
    /// <param name="contentEncoding"></param>
    /// <returns>The JSON result object that serializes the specified object to JSON format. The result object that is prepared by this method is written to the response by the ASP.NET MVC framework when the object is executed.</returns>
    protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding)
    {
        return new JsonNetResult
        {
            Data = data,
            ContentType = contentType,
            ContentEncoding = contentEncoding
        };
    }

Return Empty JSON {} in ASP.NET Core WebAPI

Many types of response server status codes do not return content. Even a few of the 200 series Successful Response codes do not allow content to be returned. You also must return the 'application/json' content-type in your response for the browser to recognize the JSON, or the browser might interpret empty JSON as null or an empty string. Those two issues might be why you never got your empty JSON object.

So for this to work, you need to:

  1. Return the Http Header Status Code of 200 Successful
  2. Return the Http Header Content-type of "application/json"
  3. Return the empty JSON object {}

The good news is ASP.NET Core 7 comes with several "ActionResult" subtypes of Response Objects that do all three steps above for you, though the documentation does not clearly state that:

[HttpGet]
public IActionResult GetJSON(string? text = "")
{
  return new ObjectResult(new{});
}

// Returns: {}

ObjectResult is a generic wrapper around an ActionResult that includes the ability to return any object converted to JSON, the JSON content-type, and deliver the Status Code 200 Successful.

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