简体   繁体   English

如何根据请求控制响应包装在 Aspnetboilerplate (ABP) 中

[英]How to control response Wraping in Aspnetboilerplate (ABP) on a request-basis

I'm using ABP (aspnetboilerplate) 7.0 thru Aspnet Zero 11 and I'm trying to get OData working.我正在通过 Aspnet Zero 11 使用 ABP (aspnetboilerplate) 7.0,我正在尝试让 OData 正常工作。 I've followed the article over at ABP and I've taken inspiration from their sample.我在 ABP 上关注了这篇文章,并从他们的样本中获得了灵感。

OData routes ( /odata and /odata/$metadata ) answers should not be wraped.不应包装 OData 路由( /odata/odata/$metadata )答案。 ABP does provide an attribute to prevent wraping called DontWrap . ABP 确实提供了一个名为DontWrap的防止包装的属性。 However, since theses routes are not on controllers that I have direct acces to, I can't set the attribute.但是,由于这些路由不在我可以直接访问的控制器上,因此我无法设置该属性。

The same question has been asked here Disable Wrapping of Controller Results however, they wanted to disable wrapping altogether, which is not what I want to do.此处提出了同样的问题Disable Wrapping of Controller Results但是,他们想完全禁用包装,这不是我想要做的。

The answer to that question, is to use a ResultFilter to set the attribute's value.该问题的答案是使用ResultFilter来设置属性的值。 I have however found that setting the value thru the attribute also sets the value that comes from the injected IAbpAspNetCoreConfiguration然而,我发现通过属性设置值也会设置来自注入的IAbpAspNetCoreConfiguration的值

For example:例如:

    public class ODataResultFilter : IResultFilter, ITransientDependency
    {
        private readonly IAbpAspNetCoreConfiguration _configuration;

        public ODataResultFilter(IAbpAspNetCoreConfiguration configuration)
        {
            _configuration = configuration;
        }

        public void OnResultExecuting(ResultExecutingContext context)
        {
            var methodInfo = context.ActionDescriptor.GetMethodInfo();

            var wrapResultAttribute =
                GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(
                    methodInfo,
                    _configuration.DefaultWrapResultAttribute,
                    false
                );

            if (context.HttpContext.Request.Path.Value.Equals("/odata/$metadata") ||
                context.HttpContext.Request.Path.Value.Equals("/odata"))
            {
                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;
        }
    }

As soon as I hit wrapResultAttribute.WrapOnSuccess = false;一旦我点击wrapResultAttribute.WrapOnSuccess = false; , _configuration.DefaultWrapResultAttribute becomes false and every other request ends up not being wrapped. , _configuration.DefaultWrapResultAttribute变为 false 并且所有其他请求最终都没有被包装。 My front-end expects wrapped responses and thus the front-end stops working as soon as I hit an odata route once.我的前端期望包装响应,因此一旦我点击 odata 路由,前端就会停止工作。

How can I manipulate this attribute and prevent wrapping for OData routes but leave the default + attribute-configured wrapping behavior for the other routes?如何操作此属性并防止包装 OData 路由,但保留其他路由的默认 + 属性配置包装行为?

GetSingleAttributeOfMemberOrDeclaringTypeOrDefault method should work fine, except right now, since _configuration.DefaultWrapResultAttribute gets modified, a controller that doesn't explicitly sets a WrapResult attribute will get the default, overriden by the last value set... GetSingleAttributeOfMemberOrDeclaringTypeOrDefault方法应该可以正常工作,除了现在,因为_configuration.DefaultWrapResultAttribute被修改,没有明确设置WrapResult属性的 controller 将获得默认值,被最后一个值设置覆盖......

Implement IWrapResultFilter , which was introduced in ABP v6.5:实现 ABP v6.5 中引入的IWrapResultFilter

using Abp.Web.Results.Filters;
using System;

namespace AbpODataDemo.Web.Host.ResultWrapping
{
    public class ODataWrapResultFilter : IWrapResultFilter
    {
        public bool HasFilterForWrapOnError(string url, out bool wrapOnError)
        {
            wrapOnError = false;
            return new Uri(url).AbsolutePath.StartsWith("/odata", StringComparison.InvariantCultureIgnoreCase);
        }

        public bool HasFilterForWrapOnSuccess(string url, out bool wrapOnSuccess)
        {
            wrapOnSuccess = false;
            return new Uri(url).AbsolutePath.StartsWith("/odata", StringComparison.InvariantCultureIgnoreCase);
        }
    }
}

Add it to WrapResultFilters in the module's PreInitialize method:在模块的PreInitialize方法中将其添加到WrapResultFilters

public override void PreInitialize()
{
    Configuration.Modules.AbpWebCommon().WrapResultFilters.Add(new ODataWrapResultFilter());
}

Reference:参考:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM