You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Framework MVC中JsonResult序列化long为字符串失效如何解决

问题根源

你配置的所有Newtonsoft.Json相关序列化规则(包括属性[JsonConverter]注解、WebApiConfig中的全局转换器注册)仅对ASP.NET Web API接口生效。你的TestController继承的是System.Web.Mvc.Controller,返回的是MVC原生JsonResult,该类型默认使用.NET内置的JavaScriptSerializer做序列化,完全不会调用你配置的Newtonsoft.Json规则,所以所有转换器配置都不生效。

解决方案

可根据你的项目需求任选以下一种方案:

方案1:手动调用Newtonsoft序列化返回(快速验证,无需全局修改)

直接将接口返回值改为ContentResult,手动用JsonConvert序列化对象,会自动触发你定义的Int64JsonConverter,属性上的[JsonConverter]注解也会生效:

[HttpGet,Route("Test2")]
public ContentResult Test2()
{
    var customer = new Customer
    {
        Id = long.MaxValue,
        Name = "test15"
    };
    string json = JsonConvert.SerializeObject(customer);
    return Content(json, "application/json");
}

方案2:自定义Newtonsoft专用JsonResult,全局统一MVC序列化规则

如果希望所有MVC控制器的Json返回都默认使用Newtonsoft.Json,统一序列化规则,可按如下步骤修改:

  1. 自定义JsonNetResult类替换原生JsonResult
public class JsonNetResult : JsonResult
{
    public JsonSerializerSettings SerializerSettings { get; set; }

    public JsonNetResult()
    {
        SerializerSettings = new JsonSerializerSettings
        {
            // 全局注册long转字符串转换器,注册后属性上不需要再加注解
            Converters = new List<JsonConverter> { new Int64JsonConverter() }
        };
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException(nameof(context));
        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
            string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("不允许GET请求获取JSON数据");
        }

        HttpResponseBase response = context.HttpContext.Response;
        response.ContentType = string.IsNullOrEmpty(ContentType) ? "application/json" : ContentType;

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

        if (Data != null)
        {
            var writer = new JsonTextWriter(response.Output) { Formatting = Formatting.None };
            JsonSerializer.Create(SerializerSettings).Serialize(writer, Data);
            writer.Flush();
        }
    }
}
  1. 给控制器添加扩展方法简化调用
public static class ControllerExtensions
{
    public static JsonNetResult JsonNet(this Controller controller, object data, JsonRequestBehavior behavior = JsonRequestBehavior.AllowGet)
    {
        return new JsonNetResult
        {
            Data = data,
            JsonRequestBehavior = behavior
        };
    }
}
  1. 接口直接返回自定义JsonNetResult即可
[HttpGet,Route("Test2")]
public JsonNetResult Test2()
{
    var customer = new Customer
    {
        Id = long.MaxValue,
        Name = "test15"
    };
    return this.JsonNet(customer);
}

方案3:将控制器改为Web API控制器

如果该接口仅做数据返回,没有视图渲染需求,直接将TestController的父类从Controller改为ApiController,你之前在WebApiConfig中配置的全局转换器就会自动生效,不需要修改接口返回值写法。

内容的提问来源于stack exchange,提问作者dimmits

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 22:57:03