如何与异步 foreach 和 IAsyncEnumerable 一起返回 ActionResult

Abu*_*ood 5 c# actionresult request-validation asp.net-core-webapi iasyncenumerable

我有这个签名的控制器方法:

public async IAsyncEnumerable<MyDto> Get()
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我需要做一些请求验证并相应地返回 401、400 和其他代码,但它不支持。或者,以下签名不会编译:

public async Task<ActionResult<IAsyncEnumerable<MyDto>>> Get()
Run Code Online (Sandbox Code Playgroud)

错误:

无法将类型“Microsoft.AspNetCore.Mvc.UnauthorizedResult”隐式转换为“MyApi.Responses.MyDto”

完整方法:

public async IAsyncEnumerable<MyDto> Get()
{
    if (IsRequestInvalid())
    {
        // Can't do the following. Does not compile.
        yield return Unauthorized();
    }
    var retrievedDtos = _someService.GetAllDtosAsync(_userId);

    await foreach (var currentDto in retrievedDtos)
    {
        yield return currentDto;
    }
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?似乎无法相信微软的设计目的IAsyncEnumerable是在没有返回任何其他东西的可能性/灵活性的情况下使用。

小智 0

这应该有效

    public ActionResult<IAsyncEnumerable<MyDto>> Get()
    {
        if(IsRequestInvalid())
        {
            // now can do.
            return Unauthorized();
        }

        return new ActionResult<IAsyncEnumerable<MyDto>>(DoSomeProcessing());

        IAsyncEnumerable<MyDto> DoSomeProcessing()
        {
            IAsyncEnumerable<MyDto> retrievedDtos = _someService.GetAllDtosAsync(_userId);

            await foreach(var currentDto in retrievedDtos)
            {
                //work with currentDto here

                yield return currentDto;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果在退货之前没有对物品进行处理更好:

public ActionResult<IAsyncEnumerable<MyDto>> Get()
    {
        if(IsRequestInvalid())
        {
            // now can do
            return Unauthorized();
        }

        return new ActionResult<IAsyncEnumerable<MyDto>>(_someService.GetAllDtosAsync(_userId));
    }
Run Code Online (Sandbox Code Playgroud)