Генератор кода машинописи NSwag с шаблоном angular не выдает правильный тип ответа - PullRequest
0 голосов
/ 21 февраля 2020

My. net В базовом приложении есть пост-контроллер, который возвращает json ответ. Я использую шаблон nswag angular.

Вот как выглядит мой контроллер:

[HttpPost]
public async Task<ActionResult<RoutineResponse>> PostRoutine([FromBody] RoutineRequest routine)
{
    var res = await _routineService.AddAsync(new Routine
    {
        Title = routine.Title, 
        Description = routine.Description, 
        Steps = routine.Steps.Select(s => new Step
        {
            Description = s.Description,
            Order = s.Order,
            PartOfDay = s.PartOfDay
        }).ToList(),
    });

    var response = _mapper.Map<RoutineResponse>(res);
    response.Href = _linkGenerator.GetPathByPage("/Routines/Details", null, new {res.Identifier});

    return CreatedAtAction("GetRoutine", new { id = res.Id }, response);
}

Полученный сгенерированный код выглядит следующим образом:

postRoutine(routine: RoutineRequest | null): Observable<RoutineResponse | null> {
    let url_ = this.baseUrl + "/api/Routines";
    url_ = url_.replace(/[?&]$/, "");

    const content_ = JSON.stringify(routine);

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

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

protected processPostRoutine(response: HttpResponseBase): Observable<RoutineResponse | 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 ? RoutineResponse.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<RoutineResponse | null>(<any>null);
}

Проблемы:

  • Сгенерированный код не соответствует правильному типу ответа: ожидается 200 вместо 201 created
  • Не возвращает json ответ

1 Ответ

0 голосов
/ 21 февраля 2020

Оказалось, что чванство не подобрало правильный интерфейс контроллера. Мне пришлось добавить следующие аннотации, чтобы исправить это

[HttpPost]
[SwaggerResponse(StatusCodes.Status201Created, typeof(RoutineResponse))]
public async Task<ActionResult<RoutineResponse>> PostRoutine([FromBody] RoutineRequest routine)
{
    var res = await _routineService.AddAsync(new Routine
    {
        Title = routine.Title, 
        Description = routine.Description, 
        Steps = routine.Steps.Select(s => new Step
        {
            Description = s.Description,
            Order = s.Order,
            PartOfDay = s.PartOfDay
        }).ToList(),
    });

    var response = _mapper.Map<RoutineResponse>(res);
    response.Href = _linkGenerator.GetPathByPage("/Routines/Details", null, new {res.Identifier});

    return CreatedAtAction("GetRoutine", new { id = res.Id }, response);
}

Сгенерированный машинописный код теперь корректно создает правильный метод записи

postRoutine(routine: RoutineRequest | null): Observable<RoutineResponse> {
    let url_ = this.baseUrl + "/api/Routines";
    url_ = url_.replace(/[?&]$/, "");

    const content_ = JSON.stringify(routine);

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

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

protected processPostRoutine(response: HttpResponseBase): Observable<RoutineResponse> {
    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 === 201) {
        return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
        let result201: any = null;
        let resultData201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
        result201 = RoutineResponse.fromJS(resultData201);
        return _observableOf(result201);
        }));
    } else if (status !== 200 && status !== 204) {
        return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
        return throwException("An unexpected server error occurred.", status, _responseText, _headers);
        }));
    }
    return _observableOf<RoutineResponse>(<any>null);
}
...