Base solution for your next web application
Open Closed

DontWrap Result by header info, or another way #7259


User avatar
0
enerjisauretim created

Hi there,

We now have a couple of finished AspnetZero applications, and we started using some of their api's like login and other methods. However, the same nswag problem starts occurring: nswag generated unwrapped results.

In my opinion, you can pass such a lambda function:

Configuration.Modules.AbpAspNetCore().DefaultWrapResultAttribute.WrapOnSuccessFunc = (request) => request.Headers["x-dontwrap"] != null;

So that we can configure it per httprequest?

What we do is now create an overload for unwrapped version and use [DontWrap] Attribute, which is very weird.


8 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    I think the content format returned by api should be fixed and should not be changed according to the content of the request header.

  • User Avatar
    0
    enerjisauretim created

    @maliming you are right, however, AspnetZero does inject the response type, which is wrong, either. The service should return the same structure as it promises to.

    In my opinion, instead of wrapping results, RAD tool should generate wrapped object results (such as AbpPagedResult<T> ) so that Swagger will generate related structure.

  • User Avatar
    0
    maliming created
    Support Team

    hi @enerjisauretim

    This returned wrapper object is automatically handled in zero's angular. https://github.com/aspnetboilerplate/abp-ng2-module/blob/master/src/abpHttpInterceptor.ts#L129

  • User Avatar
    0
    enerjisauretim created

    Since we are calling webapi's from our other projects via server-to-server communication, this interceptor does not work for our case.

  • User Avatar
    0
    maliming created
    Support Team

    hi

    I don't know your code, maybe you can write an interceptor similar to angular in the backend application. This is the best.

    If you want to dynamically control the return content based on the request header, you can refer to the code of the AbpResultFilter and then replace the filter (note that the order of the filters cannot be changed). Determine the request header in the filter to decide whether to wrap the returned content.

    https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.AspNetCore/AspNetCore/Mvc/Results/AbpResultFilter.cs#L10

    services.PostConfigure<MvcOptions>(options =>
    {
    	ReplaceYourFilter(options.Filters);
    });
    
  • User Avatar
    0
    enerjisauretim created

    Can you provide an example for this scenario?

    I've tried many ways to either remove AbpResultFilter and add my extended Filter class, or make this filter class working conditionally.

    In startup.cs file, services.Configure<MvcOptions> and PostConfigure methods not working, so that i was not be able to modify filters accordingly.

  • User Avatar
    0
    enerjisauretim created

    Configuration.Modules.AbpAspNetCore().DefaultWrapResultAttribute is also get-only property, so that I am unable to override the existing filter. Configuration.Modules.AbpAspNetCore().DefaultWrapResultAttribute.WrapOnError is not a function, in which I can resolve a HttpContext and decide to return a wrapped result or not.

  • User Avatar
    0
    maliming created
    Support Team

    You can replace the built-in filter with a code like the one below (the filter order is important)

    services.PostConfigure<MvcOptions>(options =>
    {
    	ReplaceExceptionFilter(options);
    });
    
    
    private static void ReplaceExceptionFilter(MvcOptions options)
    {
    	for (var index = options.Filters.Count - 1; index >= 0; --index)
    	{
    		if (options.Filters[index] is ServiceFilterAttribute &&
    			((ServiceFilterAttribute) options.Filters[index]).ServiceType != typeof(AbpExceptionFilter))
    		{
    			continue;
    		}
    
    		options.Filters.Insert(index, new ServiceFilterAttribute(typeof(MyWebSiteExceptionFilter))
    		{
    			Order = 0
    		});
    
    		options.Filters.RemoveAt(index + 1);
    
    		break;
    	}
    }