我需要创建一个序列化器来支持以下所有任务:
删除空属性
删除空列表
我注意到ODataMediaTypeFormatter
的语法已更改。
而且我在将我的Serialzation提供程序添加到管道时遇到了麻烦。
这是我尝试过的:
在WebApiConfig.cs上:
var odataFormatters = ODataMediaTypeFormatters.Create();
odataFormatters.Add(new MyDataMediaTypeFormatter());
config.Formatters.InsertRange(0, odataFormatters);
另外,我创建了以下Odatameditatypeformatter
:
public class MyODataMediaTypeFormatter : ODataMediaTypeFormatter
{
static IEnumerable<ODataPayloadKind> payloadKinds = new List<ODataPayloadKind>
{
ODataPayloadKind.Asynchronous,
ODataPayloadKind.Batch,
ODataPayloadKind.BinaryValue,
ODataPayloadKind.Collection,
ODataPayloadKind.EntityReferenceLink,
ODataPayloadKind.EntityReferenceLinks,
ODataPayloadKind.Error,
ODataPayloadKind.Delta,
ODataPayloadKind.IndividualProperty,
ODataPayloadKind.MetadataDocument,
ODataPayloadKind.Parameter,
ODataPayloadKind.Resource,
ODataPayloadKind.ServiceDocument,
ODataPayloadKind.Unsupported,
ODataPayloadKind.Value
};
public MyODataMediaTypeFormatter() : base(payloadKinds)
{
}
}
当前,我检查了所有基本方法,在向我的OData控制器创建Get / Post请求时,似乎没有一个碰到断点。
谁能在新版本的Microsoft.Aspnet.OData 7.0.1上做到这一点?
参考方案
我找到了解决方案。
在新版本上,仅通过依赖注入才能启用所有序列化和反序列化定制。
首先,我们需要重写序列化提供程序:
/// <summary>
/// Provider that selects the IgnoreNullEntityPropertiesSerializer that omits null properties on resources from the response
/// </summary>
public class MySerializerProvider : DefaultODataSerializerProvider
{
private readonly IgnoreNullsSerializer _propertiesSerializer;
private readonly IgnoreEmptyListsResourceSetSerializer _ignoreEmptyListsSerializer;
private readonly IgnoreEmptyListsCollectionSerializer _ignoreEmptyListsCollectionSerializer;
/// <summary>
/// constructor
/// </summary>
/// <param name="rootContainer"></param>
public MySerializerProvider(IServiceProvider rootContainer)
: base(rootContainer)
{
_ignoreEmptyListsSerializer = new IgnoreEmptyListsResourceSetSerializer(this);
_propertiesSerializer = new IgnoreNullsSerializer(this);
_ignoreEmptyListsCollectionSerializer = new IgnoreEmptyListsCollectionSerializer(this);
}
/// <summary>
/// Mark edmtype to apply the serialization on
/// </summary>
/// <param name="edmType"></param>
/// <returns></returns>
public override ODataEdmTypeSerializer GetEdmTypeSerializer(Microsoft.OData.Edm.IEdmTypeReference edmType)
{
// Support for Entity types AND Complex types
if (edmType.Definition.TypeKind == EdmTypeKind.Entity || edmType.Definition.TypeKind == EdmTypeKind.Complex)
{
return _propertiesSerializer;
}
if (edmType.Definition.TypeKind == EdmTypeKind.Collection)
{
if(edmType.Definition.AsElementType().IsDecimal() || edmType.Definition.AsElementType().IsString())
return _ignoreEmptyListsCollectionSerializer;
return _ignoreEmptyListsSerializer;
}
var result = base.GetEdmTypeSerializer(edmType);
return result;
}
}
您可能需要根据要覆盖其行为的EdmType覆盖不同的序列化程序。
我要添加一个序列化程序的示例,该示例将忽略请求中基于“ HideEmptyLists”标头的实体中的空列表...
/// <inheritdoc />
/// <summary>
/// OData Entity Serializer that omits empty listss properties from the response
/// </summary>
public class IgnoreEmptyListsResourceSetSerializer : ODataResourceSetSerializer
{
/// <summary>
/// constructor
/// </summary>
/// <param name="provider"></param>
public IgnoreEmptyListsResourceSetSerializer(ODataSerializerProvider provider) : base(provider) { }
/// <inheritdoc />
public override void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer,
ODataSerializerContext writeContext)
{
var shouldHideEmptyLists = writeContext.Request.GetHeader("HideEmptyLists");
if (shouldHideEmptyLists != null)
{
IEnumerable enumerable = graph as IEnumerable; // Data to serialize
if (enumerable.IsNullOrEmpty())
{
return;
//ignore
}
}
base.WriteObjectInline(graph, expectedType, writer, writeContext);
}
}
还有一个忽略集合的空列表...
/// <inheritdoc />
/// <summary>
/// OData Entity Serilizer that omits null properties from the response
/// </summary>
public class IgnoreEmptyListsCollectionSerializer : ODataCollectionSerializer
{
/// <summary>
/// constructor
/// </summary>
/// <param name="provider"></param>
public IgnoreEmptyListsCollectionSerializer(ODataSerializerProvider provider)
: base(provider) { }
/// <summary>
/// Creates an <see cref="ODataCollectionValue"/> for the enumerable represented by <paramref name="enumerable"/>.
/// </summary>
/// <param name="enumerable">The value of the collection to be created.</param>
/// <param name="elementType">The element EDM type of the collection.</param>
/// <param name="writeContext">The serializer context to be used while creating the collection.</param>
/// <returns>The created <see cref="ODataCollectionValue"/>.</returns>
public override ODataCollectionValue CreateODataCollectionValue(IEnumerable enumerable, IEdmTypeReference elementType,
ODataSerializerContext writeContext)
{
var shouldHideEmptyLists = writeContext.Request.GetHeader("HideEmptyLists");
if (shouldHideEmptyLists != null)
{
if (enumerable.IsNullOrEmpty())
{
return null;
//ignore
}
}
var result = base.CreateODataCollectionValue(enumerable, elementType, writeContext);
return result;
}
}
最后,我将展示如何将序列化提供程序注入我们的OData管道:
config.MapODataServiceRoute(odata, odata, builder => builder
.AddService<ODataSerializerProvider>(ServiceLifetime.Scoped, sp => new MySerializerProvider(sp)));
那应该把它包起来。
干杯。
我被困写数据库不要把我丢错写命令不起作用控制器:[HttpPost] public async Task<ActionResult>PartialTabelaEcp(string userDate) { var numerMiesiaca = 1; var numerRoku = 1; var dbExists = _ecpContext.Kar…
ASP.NET Core 2.0中的多个身份 - c#我正在将ASP.NET Core 1.0应用程序迁移到ASP.NET Core 2.0。在我的启动中,我正在配置两个身份:services.AddIdentity<IdentityUser, IdentityRole>(configureIdentity) .AddDefaultTokenProviders() .AddUserStore<…
Visual Studio,ASP.Net(.Net Framework),并在项目中包含NuGet安装的软件包 - javascript我在Visual Studio 2017中有一个主要由JavaScript组成的ASP.Net(.Net Framework)MVC Web应用程序。我已经使用NuGet安装了一个软件包(特别是marker-animate-unobtrusive软件包。)文档继续说我应该在我的HTML页面中包含JavaScript,但是在仔细检查了NuGet的内容后,我不确…
.Net LINQ-使用其他字典过滤字典 - c#我有两个相同类型的字典,A和B。Dictionary<string, IEnumerable<object>> 我使用对象来表示具有属性“ Id”的复杂类型。我正在寻找A中具有B中存在的对象(使用Id)但在另一个键下的所有项目。基本上是要判断对象是否已移动键。 A是新字典,B是旧字典。有没有使用LINQ完成此操作的合理方法?我希望结果…
在视图模型中,asp.net mvc核心2选择值始终为0 - c#我在视图中有一个选择,该选择始终向我的视图模型返回0,但我不知道为什么:查看模型:// CreateLifeInsuranceViewModel.cs using InsuranceListManager.Models.EntityFrameworkModels; using System.Collections.Generic; using System.…