1

I am having difficulties with a generated Swagger Angular client from an Asp.Net Core 3.1.

I created an ASP.NET Core application and added the following to the TestController.cs

[HttpGet]
[Route("TList")]
[Produces("application/json")]
public ActionResult<TestDto> TList()
{
  TestDto result = new TestDto();
  result.Title = "Title";
  result.DataList = new List<TestItem>();
  result.DataList.Add(new TestItem() { Title = "Test" });
  return Ok(result);
}

The DTO was defined as:

  public class TestDto
  {
    public string Title { get; set; }
    public List<TestItem> DataList { get; set; }
  }
  public class TestItem
  {
    public string Title { get; set; }
  }

I generate the swagger file from:

gulp.task('swagger-json', function (cb) {
 exec('node_modules\\nswag\\bin\\binaries\\NetCore30\\dotnet-nswag webapi2swagger /assembly:..\\bin\\Debug\\netcoreapp3.1\\WebApplication1.dll /output:WebApplication1.swagger.json', function (err, stdout, stderr) {
  console.log(stdout);
  console.log(stderr);
  cb(err);
 });
});

gulp.task('swagger-angular', function (cb) {
 exec('node_modules\\nswag\\bin\\binaries\\win\\nswag swagger2tsclient /input:WebApplication1.swagger.json /output:src/generated/Backend.ts /template:Angular /injectionTokenType:InjectionToken /httpClass:HttpClient /rxJsVersion:6.0', function (err, stdout, stderr) {
  console.log(stdout);
  console.log(stderr);
  cb(err);
 });
});

I invoke the Rest interface with

 public getDataWithSwagger() {
  this.testClient.tList().subscribe((data) => {
   this.myData = data;
   this.title = data.title;
  },
   () => { console.warn("Could not call REST") }
  );
 }
}

But the variable data is not populated, the Title is undefined and dataList does not appear at all

But the following code works, Title and dataList are populated

public getData() {
  this.http.get('https://localhost:44383/api/test/TList').subscribe((data: TestDto) => {
   this.myData = data;
   this.title = data.title;
  });
 }

What additional parameters do I need to give in the dotnet-nswag or nswag commands?

Below is part of the generated code from nswag

tList(): Observable<TestDto | null> {
    let url_ = this.baseUrl + "/api/Test/TList";
    url_ = url_.replace(/[?&]$/, "");

let options_ : any = {
    observe: "response",
    responseType: "blob",           
    headers: new HttpHeaders({
        "Accept": "application/json"
    })
};

return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => {
    return this.processTList(response_);
})).pipe(_observableCatch((response_: any) => {
    if (response_ instanceof HttpResponseBase) {
        try {
            return this.processTList(<any>response_);
        } catch (e) {
            return <Observable<TestDto | null>><any>_observableThrow(e);
        }
    } else
        return <Observable<TestDto | null>><any>_observableThrow(response_);
}));
}

protected processTList(response: HttpResponseBase): Observable<TestDto | null> {
    const status = response.status;

const responseBlob = 
    response instanceof HttpResponse ? response.body : 
    (<any>response).error instanceof Blob ? (<any>response).error : undefined;

let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }};
if (status === 200) {
    return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
    let result200: any = null;
    let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
    result200 = resultData200 ? TestDto.fromJS(resultData200) : <any>null;
    return _observableOf(result200);
    }));
} else if (status !== 200 && status !== 204) {
    return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
    return throwException("An unexpected server error occurred.", status, _responseText, _headers);
    }));
}
    return _observableOf<TestDto | null>(<any>null);
}
10
  • question is not clear. From where the first part of code comes from? Commented Dec 26, 2019 at 4:15
  • I created a TestController from the template including read and write operations. The first part of the code was placed in the TestController class. Commented Dec 26, 2019 at 5:13
  • How does this.testClient.tList() function look like? Could you please add it to the post? Commented Dec 27, 2019 at 18:47
  • @tenkmilan I have added the generated code to the bottom of the question Commented Dec 28, 2019 at 16:14
  • Did you observe your request in the network tab? what is the request url? and i don't know why swagger generates blob request for json result. Commented Dec 29, 2019 at 15:22

1 Answer 1

1

The problem was caused because the Swagger generated backend was expecting Pascal Cased Json properties but ASP.NET Core by default delivers camelCase. To fix this:

        services.AddControllersWithViews()
            .AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.PropertyNamingPolicy=null;
            });

If you prefer camel Case there may be a way to change this in NSwagStudio.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.