C# 如何更改Asp.NETCore中某些操作的序列化方法(类型化,无)?
我有asp.NETCore2.2Web应用程序。应用程序包含命令和查询操作,命令操作必须返回类型化json响应:C# 如何更改Asp.NETCore中某些操作的序列化方法(类型化,无)?,c#,asp.net-core,asp.net-web-api,json.net,C#,Asp.net Core,Asp.net Web Api,Json.net,我有asp.NETCore2.2Web应用程序。应用程序包含命令和查询操作,命令操作必须返回类型化json响应: { $type:"A.B.Customer, x.dll ", id: 11231, name: "Erwin .." } { id: 34234, name: "Erwin .. " } 查询操作必须返回非类型响应: { $type:"A.B.Customer, x.dll ", id: 11231, name: "Erwin .."
{
$type:"A.B.Customer, x.dll ",
id: 11231,
name: "Erwin .."
}
{
id: 34234,
name: "Erwin .. "
}
查询操作必须返回非类型响应:
{
$type:"A.B.Customer, x.dll ",
id: 11231,
name: "Erwin .."
}
{
id: 34234,
name: "Erwin .. "
}
我们可以在启动时为Json响应选择一个outputformatter
services.AddMvc().AddJsonOptions(o =>
{
SerializerSettings.TypeNameHandling=Newtonsoft.Json.TypeNameHandling.Objects
// SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.None
}
那么,如何通过操作更改相同响应类型(应用程序/json)的输出格式化程序呢?有多种方法可以做到这一点 一种方法是直接调用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
classes基函数
在ASP.NET Core 2.x中,JsonResult
接受JsonSerializerSettings
作为第二个参数。
从ASP.NET Core 3.x中,JsonResult
接受object
,并且根据所使用的序列化程序,需要不同的类型
这意味着,如果在代码中使用第二个示例,它将(首先)在迁移到ASP.NET Core 3.0时中断,因为它不再依赖于JSON.NET。通过向项目中添加Newtonsoft.JSON
包并添加
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);
有太多的操作需要更改,因此我将尝试为此需求准备ActionFilter/ResultFilter,感谢您的详细响应@Tseng@ozz:我很好奇:当您使用(键入的)命令时,为什么会有多个端点?(这是“太多行动需要改变”的唯一原因)。当您使用命令时,其基本上是RPC和命令类型本身就足以通过完整的quallified名称来区分命令。对完全限定类型的需要是您有一个基类和一个接受该基类类型的操作。如果每个操作都接受最特定的类型名,那么您将只有多个操作,但是,您不需要$type参数作为JSON反序列化器提示。没有?我想我误解了这个问题,我没有使用$type信息作为命令分派器。我为我的实体创建了通用的创建、编辑和显示页面(前端:Vue+Vuetify)。我想知道这个在服务器端创建和编辑页面的类型信息。所以我对它们使用类型化序列化反序列化。另一方面,我还为ViewModel对象创建了通用/动态显示。现在对它们没有“类型信息”要求:)如果我尝试做一个抽象,1-命令(创建/更新-我需要类型化反序列化),2-查询,2a-命令查询(新建/编辑页面-我需要类型化序列化)2b-只是查询(查看页面-现在不需要类型化序列化)谢谢帮助,现在问题已经解决:)