Angular 从 ASP.NET Core 3.1 应用程序生成的 TypeScript 客户端无法正常工作
Angular TypeScript client generated from an ASP.NET Core 3.1 application is not working
我在使用 Asp.Net Core 3.1 生成的 Swagger Angular 客户端时遇到困难。
我创建了一个 ASP.NET 核心应用程序并将以下内容添加到 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);
}
DTO 定义为:
public class TestDto
{
public string Title { get; set; }
public List<TestItem> DataList { get; set; }
}
public class TestItem
{
public string Title { get; set; }
}
我从以下来源生成 swagger 文件:
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);
});
});
我用
调用 Rest 接口
public getDataWithSwagger() {
this.testClient.tList().subscribe((data) => {
this.myData = data;
this.title = data.title;
},
() => { console.warn("Could not call REST") }
);
}
}
但是变量数据没有填充,Title没有定义,dataList根本没有出现
但以下代码有效,Title 和 dataList 已填充
public getData() {
this.http.get('https://localhost:44383/api/test/TList').subscribe((data: TestDto) => {
this.myData = data;
this.title = data.title;
});
}
我需要在 dotnet-nswag 或 nswag 命令中提供哪些额外参数?
以下是 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);
}
问题是因为 Swagger 生成的后端需要 Pascal Cased Json 属性,但 ASP.NET Core 默认提供驼峰式。要解决此问题:
services.AddControllersWithViews()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy=null;
});
如果您更喜欢驼峰式大小写,可能可以在 NSwagStudio 中更改它。
我在使用 Asp.Net Core 3.1 生成的 Swagger Angular 客户端时遇到困难。
我创建了一个 ASP.NET 核心应用程序并将以下内容添加到 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);
}
DTO 定义为:
public class TestDto
{
public string Title { get; set; }
public List<TestItem> DataList { get; set; }
}
public class TestItem
{
public string Title { get; set; }
}
我从以下来源生成 swagger 文件:
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);
});
});
我用
调用 Rest 接口 public getDataWithSwagger() {
this.testClient.tList().subscribe((data) => {
this.myData = data;
this.title = data.title;
},
() => { console.warn("Could not call REST") }
);
}
}
但是变量数据没有填充,Title没有定义,dataList根本没有出现
但以下代码有效,Title 和 dataList 已填充
public getData() {
this.http.get('https://localhost:44383/api/test/TList').subscribe((data: TestDto) => {
this.myData = data;
this.title = data.title;
});
}
我需要在 dotnet-nswag 或 nswag 命令中提供哪些额外参数?
以下是 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);
}
问题是因为 Swagger 生成的后端需要 Pascal Cased Json 属性,但 ASP.NET Core 默认提供驼峰式。要解决此问题:
services.AddControllersWithViews()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy=null;
});
如果您更喜欢驼峰式大小写,可能可以在 NSwagStudio 中更改它。