自定义 Json 序列化


  Asp.Net MVC 使用 JavaScriptSerializer 来序列化 Json,众所周知它有很多局限性,好多类型都不支持,好在 Asp.Net Core MVC(3.1 以后使用的是 System.Text.Json)使用 Newtonsoft.Json,但同时也面临一个问题。当你没有定义 DTO 而是直接使用 Entity 进行传输时,避免不了会引发因延迟加载属性所造成的循环引用问题。所以,Fireasy 可以使用自己的 JsonSerializer 来解决这个问题。如果你的应用程序使用了 DTO 则不必要替换 Json 序列化机制。

  和前一章一样,替换掉 ControllerActionInvoker 后,就默认使用 Fireasy 的 JsonSerializer 类进行序列化。

  在 Asp.Net Core MVC 中你需要在 Startup.ConfigureServices 方法里使用 ConfigureFireasyMvc 方法,由 UseTypicalJsonSerializer 来切换启用或禁用:

namespace demo
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddFireasy(Configuration).AddIoc();
#if NETCOREAPP3_1
            services.AddControllersWithViews()
                .ConfigureFireasyMvc(options =>
                {
                    options.UseTypicalJsonSerializer = true; //默认是开启的
                });
#else
            services.AddMvc()
                .ConfigureFireasyMvc(options =>
                {
                    options.UseTypicalJsonSerializer = true; //默认是开启的
                });
#endif
        }
    }
}

  在 Asp.Net MVC 中,你可以在 action 方法中使用 ActionContext 来设置局部的 Json 转换器。如下所示:

public class UserController : Controller
{
    public IService Service { get; set; }

    [HttpGet]
    public ActionResult GetUsers()
    {
        ActionContext.Current.Converts.Add(new FullDateTimeJsonConverter());

        var list = Service.GetUsers();
        return Json(list);
    }
}

  而在 Asp.Net Core MVC 中,你只能通过方法注入 JsonSerializeOptionHosting 对象来设置局部的 Json 转换器。如下所示:

public class UserController : Controller
{
    private readonly IService _service;
    
    public UserController(IService service)
    {
        _service = service;
    }

    [HttpGet]
    public ActionResult GetUsers([FromServices] JsonSerializeOptionHosting hosting)
    {
        hosting.Option.Converts.Add(new FullDateTimeJsonConverter());

        var list = _service.GetUsers();
        return Json(list);
    }
}