Я начинаю путешествие по Angular 2+ (v8) и натолкнулся на несколько вопросов о передовой практике использования асинхронных функций c # WebApi.Вопросы в конце:
В моем примере WebApi (обратите внимание, что в будущем это будет вызывать хранилище асинхронно, но не для краткости) У меня есть следующая функция:
// GET api/values
[HttpGet]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(Task<IEnumerable<SearchResult>>), (int)HttpStatusCode.OK)]
public async Task<IActionResult> Get([FromQuery]string searchText, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
{
if (string.IsNullOrEmpty(searchText))
{
return BadRequest();
}
//Call a repository here and return a result
var searchResults = new List<SearchResult>()
{
new SearchResult()
{
SearchResultType = SearchResultType.Law, Id = Guid.NewGuid(),
Title = "A boring title",
Description = "A boring decription"
},
new SearchResult()
{
SearchResultType = SearchResultType.Law, Id = Guid.NewGuid(),
Title = "An interesting title",
Description = "An exciting description"
},
};
return Ok(await Task.FromResult(searchResults.Where(x => x.Title.Contains(searchText))));
}
Это возвращает Task<IActionResult>
, и я использовал Декоратор Swagger, чтобы сказать, что маршрут возвращается [ProducesResponseType(typeof(Task<IEnumerable<SearchResult>>)
.Однако в примере с ответом swagger ожидается модель задачи:
{
"result": [
{
"searchResultType": "Law",
"id": "string",
"title": "string",
"description": "string"
}
],
"id": 0,
"exception": {},
"status": "Created",
"isCanceled": true,
"isCompleted": true,
"isCompletedSuccessfully": true,
"creationOptions": "None",
"asyncState": {},
"isFaulted": true
}
Где фактический ответ:
[
{
"searchResultType": 1,
"id": "0ba4e4ef-37fd-4a76-98ed-4fad64d26b1b",
"title": "A boring title",
"description": "A boring description."
},
{
"searchResultType": 1,
"id": "e8c7e39d-cca6-43b2-90be-87537a4a0b8e",
"title": "An exciting title",
"description": "An exciting description."
}
]
В Angular 8 мой сервис потребляет:
@Injectable()
export class SearchService {
constructor(private http: HttpClient) {}
search(
filter: { searchTerm: string } = { searchTerm: "" },
page = 1
): Observable<ISearchResult[]> {
return this.http.get<ISearchResult[]>("api/v1/Search?searchText=" + filter.searchTerm);
}
}
Итак, вопросы:
Должно ли [ProducesResponseType(typeof(Task<IEnumerable<SearchResult>>)
действительно быть [ProducesResponseType(typeof(IEnumerable<SearchResult>)
?
Будет ли Task<>
когда-либовозвращено клиенту?
Я спрашиваю об этом, потому что я изначально забыл await
возвращаемое значение в API и модель Task была фактически возвращена клиенту Angular, а затем в AngularСервис Я должен был использовать следующее, чтобы получить результат, который грязный:
return this.http.get<ISearchResult[]>("api/v1/Search?searchText=" + filter.searchTerm)
.pipe(
map((res:ISearchResult[]) => res.result)
);
Правильно ли я делаю это?Есть ли способ лучше ?