4

我尝试为我使用 ASP Net Boilerplate 创建的 API 生成 c# 代码,但响应没有正确反序列化。

经调查,似乎 json 响应是使用名为“AjaxResponse”的类包装的;但是,swagger.json 在方法响应中不包含这种类型。

有谁知道如何构建一个解释包装结果的 C# Swagger 客户端?

4

3 回答 3

7

Aspnet Boilerplate 将实际结果包装在 AjaxResponse 中。AjaxResponse类是一个泛型类型类。Swaggergen 工具无法生成正确的代理类,因为包装结果发生在运行时。因此,被 Swagger 抓取的 api 签名是原始结果(未包装)。

因此,唯一的解决方案是禁用整个解决方案的自动包装器。将 2 行添加到 Web.Core 项目中的 PreInitialize() 方法。你的问题将得到解决。

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

Configuration.Modules.AbpAspNetCore().DefaultWrapResultAttribute.WrapOnSuccess = false;
于 2017-08-21T08:22:25.250 回答
1

您还可以将 [DontWrapResult]/[WrapResult] 属性用于各个应用程序方法。

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

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

如果您不能这样做,那么您可以在客户端进行相同的更改:

添加下一个类:

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

替换生成的客户端方法中的所有反序列化点:

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

经过

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

并在返回结果之前添加成功/错误检查。

于 2018-05-31T09:02:27.893 回答
1

我通过创建自定义 JsonConverter 解决了这个问题(并告诉 nswag 在生成我的客户端时使用它)。

转换器看起来像这样:

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);
    }
}
于 2019-04-21T08:23:00.893 回答