将JSON.NET格式化程序用于普通控制器

时间:2012-07-24 10:53:18

标签: asp.net-mvc asp.net-mvc-4

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

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

3 个答案:

答案 0 :(得分: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(对象viewModel)类型的方法。

E.g。

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

答案 1 :(得分:2)

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

就我个人而言,我使用自己的JsonDotNetResult(以及我的BaseController上的快捷方法)来执行所有json操作。您不仅可以通过多种方式更改其设置,而且使用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,它们将会花得很好。

答案 2 :(得分:0)

根据asp.net MVC 3 来源(我手边的第四个版本没有,但是那里的内容很可能没有改变)你不能这样做。< / p>

Controller.Json使用new JsonResultJsonResult.ExecuteResult直接使用new JavaScriptSerializer

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