【问题标题】:How can I change Serialization approach (Typed,None) for some actions in Asp.Net Core?如何更改 Asp.Net Core 中某些操作的序列化方法(Typed,None)?
【发布时间】:2019-11-26 00:39:58
【问题描述】:

我有 asp.net core 2.2 web 应用程序。应用程序包含命令和查询操作,命令操作必须返回类型化的 json 响应:

{
   $type:"A.B.Customer, x.dll ",
   id: 11231,
   name: "Erwin .."
}

查询操作必须返回非类型化响应:

{
  id: 34234,
  name: "Erwin .. "
}

我们可以在启动时为 Json 响应选择一种输出格式器。

 services.AddMvc().AddJsonOptions(o =>
                {
    SerializerSettings.TypeNameHandling=Newtonsoft.Json.TypeNameHandling.Objects
   // SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.None
}

那么如何通过操作更改相同响应类型(应用程序/json)的输出格式器?

【问题讨论】:

    标签: c# asp.net-core asp.net-web-api json.net


    【解决方案1】:

    有多种方法可以做到这一点。

    一种是直接调用 JSON.NET 方法并将您的设置传递给它。

    JsonSerializerSettings settings = new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.Objects
    };
    
    return base.Content(JsonConvert.SerializeObject(query, settings), "application/json");
    

    或者,返回JsonResult

    JsonSerializerSettings settings = new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.Objects
    };
    
    return new JsonResult(query, settings);
    

    注意第二个例子。在 .NET Core 3.0 中,JSON.NET 不再硬连线到 ASP.NET Core 中,并且 ASP.NET Core 不提供 JSON.NET 并使用新的 System.Text.Json 类基跨度。

    在 ASP.NET Core 2.x 中,JsonResult 接受 JsonSerializerSettings 作为第二个参数。 从 ASP.NET Core 3.x 开始,JsonResult 接受 object,并且根据所使用的序列化程序,需要不同的类型。

    这意味着,如果您在代码中使用第二个示例,则在迁移到 ASP.NET Core 3.0 时(起初)会中断,因为它不再依赖于 JSON.NET。您可以通过将 Newtonsoft.Json 包添加到您的项目并添加来轻松地将 JSON.NET 添加回它

    servics.AddNewtonsoftJson();
    

    在您的 ConfigureServices 方法中,再次使用 JSON.NET。但是,如果将来您决定离开 JSON.NET 并使用 System.Text.Json 或任何其他 Json 序列化程序,则必须更改所有使用它的地方。

    随意将其更改为扩展方法,创建自己的动作结果类,继承自 JsonResult 等。

    public class TypelessJsonResult : JsonResult
    {
        public TypelessJsonResult(object value) : base(value)
        {
            SerializerSettings.TypeNameHandling = TypeNameHandling.None;
        }
    }
    

    并将控制器的操作代码减少到

    return new TypelessJsonResult(query);
    

    【讨论】:

    • 要更改的action太多了,所以我会尝试为这个需求准备ActionFilter/ResultFilter,感谢@Tseng的详细回复
    • @ozz:我很好奇:当您使用(键入)命令时,为什么会有多个端点? (这就是可以说“改变太多动作”的唯一原因)。当您使用命令时,它基本上是 RPC 并且仅命令类型就足以通过它们的完整限定名称来区分命令。完全限定类型的需要是您有一个基类和一个接受该基类型的操作。如果每个操作都接受最具体的类型名称,您将只有多个操作,但是,您不需要 $type 参数作为 JSON 反序列化器提示。没有?
    • 我认为我歪曲了问题,我没有使用 $type 信息作为命令调度程序。我为我的实体创建了通用的创建、编辑、显示页面(前端:Vue+Vuetify)。我想知道服务器端这个创建和编辑页面的类型信息。所以我为他们使用了类型化的序列化-反序列化。另一方面,我还为 ViewModel 对象创建了通用/动态显示。目前对它们没有“类型信息”要求:)
    • 如果我尝试进行抽象,1- 命令(创建/更新 - 我需要类型化反序列化),2- 查询,2a - 查询命令(新/编辑页面 - 我需要类型化序列化) 2b - 只是查询(查看页面 - 现在不需要输入序列化)感谢您的帮助,问题现在已经解决了 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    相关资源
    最近更新 更多