5

从控制器(MVC 4 RC)返回 Json 时,我想修改 Json 以对属性使用驼峰式大小写,为此我尝试设置 GlobalConfiguration.Formatters.JsonFormatter (不确定这是否正确......不要'前面没有代码),但这似乎不会影响Controller.Json方法输出的Json。

环顾四周后,这种方法似乎只会影响 Web API 控制器等。这是真的吗?此外,是否可以更改 Controller.Json() 方法来实现这一点?

4

3 回答 3

7

就像@rouen 建议的那样,创建了自己的 JsonDotNetResult。

这是我的项目中的一个:

public class JsonNetResult : ActionResult
{
    public Encoding ContentEncoding { get; set; }
    public string ContentType { get; set; }
    public object Data { get; set; }
    public int StatusCode { get; set; }

    public JsonSerializerSettings SerializerSettings { get; set; }

    public JsonNetResult()
    {
        SerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    }

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

        var response = context.HttpContext.Response;

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

        if ((StatusCode >= 400) && (StatusCode <= 599))
            response.TrySkipIisCustomErrors = true;

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

        if (Data == null)
            return;

        var formatting = Formatting.None;

#if DEBUG
        formatting = Formatting.Indented;
#endif

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

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

        writer.Flush();
    }
}

然后我有自己的 baseController 继承自给我 JsonDotNet(object viewModel) 类型的方法。

例如

protected JsonNetResult JsonNet(object data = null, int statusCode = (int)HttpStatusCode.OK, string contentType = null)
{
    return new JsonNetResult
               {
                   Data = data,
                   StatusCode = statusCode,
                   ContentType = contentType
               };
}

protected JsonNetResult JsonNetForbidden()
{
    return JsonNet(statusCode: (int)HttpStatusCode.Forbidden);
}

protected JsonNetResult JsonNetNotFound()
{
    return JsonNet(statusCode: (int)HttpStatusCode.NotFound);
}

protected JsonNetResult JsonNetNoContent()
{
    return JsonNet(statusCode: (int)HttpStatusCode.NoContent);
}

protected JsonNetResult JsonNetCreated(object data)
{
    return JsonNet(data, (int)HttpStatusCode.Created);
}

protected JsonNetResult JsonNetReload()
{
    return JsonNet(new { reload = true });
}

protected JsonNetResult JsonNetRedirect(string url = null, string contentType = null)
{
    return JsonNet(new { redirectUrl = url }, contentType: contentType);
}

protected JsonNetResult JsonNetClientError(ErrorDictionary errors)
{
    return JsonNet(new { Errors = errors }, (int)HttpStatusCode.BadRequest);
}

protected JsonNetResult JsonNetUnauthorized()
{
    return JsonNet(null, (int)HttpStatusCode.Unauthorized);
}

protected JsonNetResult JsonNetFlashMessage(string message)
{
    return JsonNet(new { flashMessage = message });
}
于 2012-07-24T18:14:27.460 回答
2

无法更改默认 JavaScriptSerializer afaik 的行为。

就个人而言,我对所有 json 操作都使用自己的 JsonDotNetResult(以及 BaseController 上的快捷方法)。您不仅可以通过多种方式更改其设置,而且 JSON.NET 的性能要好得多 - 看这里http://james.newtonking.com/archive/2008/10/27/json-net-3-5- beta-1-big-performance-improvements-compact-framework-support-and-more.aspx

此外,还有许多不错的好处,例如循环依赖的自动解决(总是在更大的项目中遇到它)等。

将您的 5 分钟投入到自己的 JsonDotNetResult 中,它们将非常有用。

于 2012-07-24T14:33:02.837 回答
0

根据 asp.net MVC 3来源(我手头没有第四个版本的,但那里不太可能发生改变)你不能这样做。

Controller.Json使用new JsonResult直接JsonResult.ExecuteResult使用。new JavaScriptSerializer

前段时间我们正在寻找一些方法来影响这种行为,但没有找到。

于 2012-07-24T14:21:27.667 回答