我正在使用此软件包配置新的OData项目。我已根据文档https://aspnetboilerplate.com/Pages/Documents/OData-AspNetCore-Integration
配置了项目当我访问路径 / odata / $ metadata 时,我收到以下异常:
Newtonsoft.Json.JsonSerializationException:'自我引用循环 检测到属性'声明类型'与类型 ' Microsoft.OData.Edm.EdmEntityType&#39 ;.路径 ' result.schemaElements [0] .declaredKey [0]''
调用AbpUnitOfWorkMiddleware
时,await _next(httpContext);
类会抛出此内容。
我可以通过将.AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
添加到Startup
类来绕过此问题,但之后只会继续呈现 $ metadata ,直到浏览器死亡。
这可能是ABP框架如何处理这条特定路线的问题吗?如果我在没有ABP框架的情况下使用Microsoft.AspNetCore.OData
,那么 $ metadata 路线会很好;它实际上是作为XML文档返回的。
答案 0 :(得分:2)
solution与Disable Wrapping of Controller Results的答案相同。
您可以实施
IResultFilter
并将WrapOnSuccess
设置为false:public class ResultFilter : IResultFilter, ITransientDependency { private readonly IAbpAspNetCoreConfiguration _configuration; public ResultFilter(IAbpAspNetCoreConfiguration configuration) { _configuration = configuration; } public void OnResultExecuting(ResultExecutingContext context) { if (context.HttpContext.Request.Path.Value.Contains("odata")) { var methodInfo = context.ActionDescriptor.GetMethodInfo(); var wrapResultAttribute = GetSingleAttributeOfMemberOrDeclaringTypeOrDefault( methodInfo, _configuration.DefaultWrapResultAttribute ); wrapResultAttribute.WrapOnSuccess = false; } } public void OnResultExecuted(ResultExecutedContext context) { // No action } private TAttribute GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<TAttribute>(MemberInfo memberInfo, TAttribute defaultValue = default(TAttribute), bool inherit = true) where TAttribute : class { return memberInfo.GetCustomAttributes(true).OfType<TAttribute>().FirstOrDefault() ?? memberInfo.DeclaringType?.GetTypeInfo().GetCustomAttributes(true).OfType<TAttribute>().FirstOrDefault() ?? defaultValue; } }
然后,在Startup
类中,使用ConfigureServices
方法添加过滤器:
services.AddMvc(options =>
{
// ...
options.Filters.Add<ResultFilter>();
});
或者,您可以在模块的PreInitialize
方法中默认禁用换行:
Configuration.Modules.AbpAspNetCore().DefaultWrapResultAttribute.WrapOnSuccess = false;
之前:
后: