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

如何让MVC的JsonResult动作方法使用自定义序列化器?

解决MVC JsonResult与Newtonsoft DateTime序列化不一致的问题

我来帮你搞定这个DateTime序列化的问题——你猜的完全没错:MVC默认的JsonResult使用的是.NET内置的JavaScriptSerializer,而你手动用的是Newtonsoft的Json.NET,这两个序列化器对DateTime的处理逻辑不一样,才导致了格式差异。下面给你两种可行的解决方案,优先推荐第一种,能从根源上统一前后端的序列化逻辑:

方案一:让MVC全局使用Newtonsoft.Json作为默认序列化器

这是最优解,能让所有JsonResult的序列化逻辑和你之前手动调用JsonConvert.SerializeObject保持一致,不用改前端代码。

步骤:

  1. 确保安装Newtonsoft.Json NuGet包:如果你的项目还没装,打开NuGet包管理器,搜索Newtonsoft.Json并安装(你之前手动用过的话应该已经装好了)。
  2. 配置MVC使用Json.NET:
    • 如果你用的是传统ASP.NET MVC(非Core):
      在Global.asax.cs的Application_Start方法里添加以下配置:
      protected void Application_Start()
      {
          // 保留你原有的其他配置(如RouteConfig等)
          GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings
          {
              DateFormatString = "MM/dd/yyyy", // 设置你需要的日期格式
              Formatting = Newtonsoft.Json.Formatting.Indented // 可选,美化JSON输出
          };
      }
      
    • 如果你用的是ASP.NET Core:
      在Startup.cs的ConfigureServices方法里修改MVC服务配置:
      public void ConfigureServices(IServiceCollection services)
      {
          services.AddControllersWithViews()
              .AddNewtonsoftJson(options =>
              {
                  options.SerializerSettings.DateFormatString = "MM/dd/yyyy";
              });
          // 其他服务配置...
      }
      

配置完成后,你原来的JsonResult代码完全不用改,返回的DateTime格式就会和之前手动序列化的一致了。

方案二:在Angular中解析MVC默认的DateTime格式

如果暂时不想修改后端配置,可以在前端处理JsonResult返回的特殊DateTime格式(通常是/Date(1234567890)/这种格式)。

方法1:自定义Angular过滤器

创建一个全局过滤器来统一解析日期:

// 假设你的Angular模块叫myApp
var app = angular.module('myApp', []);

app.filter('parseMVCDate', function() {
    return function(dateString) {
        if (!dateString) return null;
        // 匹配/Date(ticks)/格式的字符串
        var matchResult = dateString.match(/\/Date\((\d+)\)\//);
        if (matchResult && matchResult.length > 1) {
            var timestamp = parseInt(matchResult[1]);
            return new Date(timestamp);
        }
        // 如果是其他合法日期格式,直接转换
        return new Date(dateString);
    };
});

然后在视图中使用这个过滤器配合Angular的date过滤器展示:

<!-- 假设你的日期字段叫CreateTime -->
<span>{{ item.CreateTime | parseMVCDate | date:'MM/dd/yyyy' }}</span>

方法2:在数据加载时批量转换日期

在$http的成功回调里遍历数据,手动转换日期字段:

$scope.LoadData = function() {
    $http({ 
        method: "GET", 
        url: 'Home/REIDataRefresh', 
        params:{'_': +new Date() } 
    }).then(function success(response) {
        // 遍历返回的数据,转换所有日期字段
        $scope.data = response.data.map(function(item) {
            // 替换成你实际的日期字段名,比如CreateTime、UpdateTime等
            if (item.CreateTime) {
                var ticks = parseInt(item.CreateTime.match(/\/Date\((\d+)\)\//)[1]);
                item.CreateTime = new Date(ticks);
            }
            if (item.UpdateTime) {
                var ticks = parseInt(item.UpdateTime.match(/\/Date\((\d+)\)\//)[1]);
                item.UpdateTime = new Date(ticks);
            }
            return item;
        });
    }, function error(errResponse) {
        alert("data " + errResponse.data + " status " + errResponse.status + " headers " + errResponse.headers + "config " + errResponse.config + " statusText " + errResponse + " xhrStat " + errResponse.xhrStatus);
    });
};

总结

优先选择方案一,因为它能统一前后端的序列化逻辑,避免以后出现其他类型的序列化不一致问题;方案二适合临时快速解决问题,但需要维护前端的解析逻辑,如果后续日期字段增加,还要同步修改前端代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:49:23