'How to control response wrapping in ABP on a per-route basis?

I'm using ABP (aspnetboilerplate) 7.0 thru ASP.NET Zero 11 and I'm trying to get OData working. I've followed the article over at ABP and I've taken inspiration from their sample.

The response of OData routes (/odata and /odata/$metadata) should not be wrapped. ABP does provide an attribute to prevent wrapping called DontWrapResult. However, since these routes are not on controllers that I have direct access 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.

The answer to that question is to use a ResultFilter to set the attribute's value. I have, however, found that setting the value thru the attribute also sets the value that comes from the injected 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;, _configuration.DefaultWrapResultAttribute becomes false and every other request ends up not being wrapped. My front-end expects wrapped responses and thus the front-end stops working as soon as I hit an OData route once.

How can I manipulate this attribute and prevent wrapping for OData routes but leave the default + attribute-configured wrapping behavior for the other routes?

GetSingleAttributeOfMemberOrDeclaringTypeOrDefault method should work fine, except right now, since _configuration.DefaultWrapResultAttribute gets modified, a controller that doesn't explicitly set a WrapResult attribute will get the default, overridden by the last value set.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source