访问odata / $ metadata

时间:2018-03-28 13:30:30

标签: c# asp.net-core odata aspnetboilerplate

我正在使用此软件包配置新的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文档返回的。

1 个答案:

答案 0 :(得分:2)

目标解决方案

solutionDisable 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;

之前:

后: