【问题标题】:Return JavaScript object literal, not JSON string, from ASP.NET MVC endpoint从 ASP.NET MVC 端点返回 JavaScript 对象文字,而不是 JSON 字符串
【发布时间】:2016-09-20 23:27:50
【问题描述】:

由于各种原因,我已从 ASP.NET MVC 的内置 JSON 序列化程序(返回 System.Web.Mvc.JsonResult 对象的那个 (参见下面的编辑))切换到牛顿软件。直到我开始测试前我才意识到前者返回一个 JavaScript 对象字面量,而 Newtonsoft 返回一个 JSON 格式的 string。

我喜欢不必在客户端解析 JSON 字符串 — 将其作为对象文字非常方便 — 但出于其他技术原因,我想坚持使用 Newtonsoft。

例如,而不是在我的客户端上看到此结果...

"{"Errors":["Please enter a valid email address."],"HasErrors":true}"

...我想看看这个结果:

{"Errors":["Please enter a valid email address."],"HasErrors":true} // no quotes

有没有办法让 Newtonsoft 返回 JS 对象字面量而不是字符串?

编辑

我提出问题的方式并不是最好的。 JsonResult 类型没有任何问题。事实上,解决方案仍然使用它。唯一的问题是默认的 Controller.Json 方法,可以覆盖它以使用 Newtonsoft (Json.NET) 而不是内置的序列化程序。

【问题讨论】:

  • 我对 .NET 世界不太熟悉 - Newtonsoft 在服务器上吗?因为如果是这样,您将永远无法从服务器返回 JS 文字。无论如何,不​​在网络请求中。还是在渲染时嵌入在页面中的某个地方?
  • 你不能用 JSON.Parse(response) 编辑你的 JS 文件吗?
  • 您如何使用 Json.Net 创建 JSON 响应并从 MVC 返回它们?
  • @vlaz 是的,Newtonsoft 是一个用于处理所有“JSON”的 .NET 小型框架。看起来它们确实是作为 JS 文字出现的——它们甚至具有application/json 的 MIME 类型。但是它目前使用 Newtonsoft 的方式是,它们以 JSON 字符串的形式出现,MIME 类型为text/html。
  • 你能分享你用来插入Json.NET的代码吗?是否类似于Using JSON.NET to return ActionResult 或Using JSON.NET as the default JSON serializer in ASP.NET MVC 3 - is it possible?? Json.NET 不会通过用引号括住对象来序列化对象,因此插入 Json.NET 的方式很可能出现问题。

标签: javascript json asp.net-mvc json.net


【解决方案1】:

只需编写一个使用 Newtonsoft 序列化程序的自定义 JsonResult:

类似的东西:

public abstract class BaseController : Controller
{
    protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding)
    {
        return new JsonNetResult
        {
            ContentType = contentType,
            ContentEncoding = contentEncoding,
            Data = data
        };
    }

    protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
    {
        return new JsonNetResult
                    {
                        ContentType = contentType,
                        ContentEncoding = contentEncoding,
                        Data = data,
                        JsonRequestBehavior = behavior
                    };
    }
}

JsonNetResult.cs:

using System;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;

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

    public JsonNetResult()
    {
        Formatting = Formatting.None;
        SerializerSettings = new JsonSerializerSettings();
        JsonRequestBehavior = JsonRequestBehavior.DenyGet;
    }

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

        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet
            && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
        }

        HttpResponseBase response = context.HttpContext.Response;

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

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

        if (Data != null)
        {
            var writer = new JsonTextWriter(response.Output) { Formatting = Formatting };

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

            writer.Flush();
        }
    }
}

信用:https://gist.github.com/jpoehls/1424538

【讨论】:

  • 这太完美了!我最终通过使用response.Write(JsonConvert.SerializeObject(this.Data)) 而不是JsonTextWriter 和JsonSerializer 实现了一个更简单的版本。我永远不需要使用任何特殊的JsonSerializerSettings 或Formatting,与作家合作总是让我觉得过于复杂。
【解决方案2】:

答案在这里:How to force ASP.NET Web API to always return JSON?

摘录:

清除所有格式化程序并重新添加 Json 格式化程序。

GlobalConfiguration.Configuration.Formatters.Clear(); GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter()); 编辑

我在 Application_Start() 中将它添加到 Global.asax。

【讨论】:

  • 我没有使用 Web API。我的控制器上的端点还包括 ViewResults、Json 字符串和文件结果,所以我认为这对我不起作用。
猜你喜欢
  • 2012-11-26
  • 2019-11-01
  • 2010-12-04
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-17
相关资源
最近更新 更多