5

I tried generating c# code for and API I created with ASP Net Boilerplate, but the response is not deserializing correctly.

Upon investigation, it seems the json response is wrapped using a class called "AjaxResponse"; however, the swagger.json doesn't include this type in the method response.

Does anyone know how to build a C# Swagger Client that accounts for the wrapped result?

Don Thomas Boyle
  • 3,055
  • 3
  • 32
  • 54
Matt
  • 53
  • 3

3 Answers3

7

Aspnet Boilerplate wraps real result within AjaxResponse. The class AjaxResponse is a generic type class. Swaggergen Tool fails to produce the right proxy classes because wrapping the result occurs in runtime. So the signature of the api, grabbed by Swagger is the raw result (not wrapped).

So the only solution is disabling automatic wrapper for solution-wide. Add the 2 lines to the PreInitialize() method in your Web.Core project. And your problem will be solved.

Configuration.Modules.AbpAspNetCore().DefaultWrapResultAttribute.WrapOnError = false;

Configuration.Modules.AbpAspNetCore().DefaultWrapResultAttribute.WrapOnSuccess = false;
Alper Ebicoglu
  • 8,884
  • 1
  • 49
  • 55
1

You can also use the [DontWrapResult]/[WrapResult] attributes for individual application methods.

[WrapResult(LogError =false, WrapOnSuccess = true, WrapOnError = true)]
SomeApplicationServiceMethod()

[DontWrapResult(LogError =false, WrapOnError=false ,WrapOnSuccess=false)]
SomeApplicationServiceMethod()

If you can't do this, then you may make same changes in client side:

Add next class:

 public class RequestResultAJAX<T>
    {
        public bool success { get; set; }
        public T result { get; set; }
        public string error { get; set; }
        public string targetUrl { get; set; }
        public string unAuthorizedRequest { get; set; }
        public string __abp { get; set; }
    }

Replace all Deserialization points in generated client method:

result_ = Newtonsoft.Json.JsonConvert.DeserializeObject<Dto>(responseData_, _settings.Value);

by

result_ = Newtonsoft.Json.JsonConvert.DeserializeObject<RequestResultAJAX<Dto>>(responseData_, _settings.Value).result;

And add success/error cheks before return result.

1

I solved this by creating a custom JsonConverter (and telling nswag to use it when generating my client).

The converter looks something like this:

public class AjaxWrapperConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanWrite => false;

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // Read about this problem here:
        // https://stackoverflow.com/questions/45777820/asp-net-boilerplate-generating-c-sharp-swagger-client-using-swagger-codegen-to

        var token = JToken.Load(reader);
        var tokenResult = token.First.First;
        var result = tokenResult.ToObject(objectType);

        return result;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(TypeIWantToUnwrap) || objectType == typeof(TypeIWantToUnwrap2);
    }
}