简体   繁体   中英

ASP NET Boilerplate > Generating C# swagger client using swagger codegen tool (nswag) not working

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?

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 is solved.

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

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

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.

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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