Использование .NET Core Mediatr не все пути кода возвращают значение

#c# #mediatr

Вопрос:

В своем API я пытаюсь использовать MediatR; поэтому в своем коде контроллера я написал:

 [HttpPost("AdminLogin")    
public async Task<ActionResult<Admin>> GetContractById(Admin admin)
{
    var response = await _mediator.Send(new UserLoginRequest(admin));    

    if (response.HasError)
    {
        return BadRequest(response);
    }    

    return Ok(response);
}
 

Затем в моем UserLoginRequest.cs я написал этот код:

 using MediatR;
using SinavAlemiPanel.Domain.Models;
using SinavAlemiPanel.Infrastructure.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SinavAlemiPanel.Application.Requests.UserRequests
{
    public class UserLoginRequest :IRequest<BaseResponse<Admin>>
    {
        private Admin admin;

        public UserLoginRequest(Admin admin)
        {
            this.admin = admin;
        }

        public Admin UserCredentials { get; set; }
    }

    public sealed class UserLoginRequestHandlers : IRequestHandler<UserLoginRequest, BaseResponse<Admin>>
    {
        private readonly IUserService _userService;

        public UserLoginRequestHandlers(IUserService userService)
        {
            _userService = userService;
        }

        public async Task<BaseResponse<Admin>> Handle(UserLoginRequest request, CancellationToken cancellationToken)
        {
            await Task.Run(() =>
            {
                return _userService.Login(request.UserCredentials);
            });
        }
    }
}
 

И на моей службе у меня есть:

 using Dapper;
using SinavAlemiPanel.Domain.Models;
using SinavAlemiPanel.Infrastructure.Interfaces;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace SinavAlemiPanel.Infrastructure.Services
{
    public class UserService : IUserService
    {
        private readonly IBaseService _baseService;
        private readonly DBConnection _db;

        public UserService(IBaseService baseService)
        {
            _baseService = baseService;
        }

        public Admin Login(Admin admin)
        {   
            Admin result = new Admin();
            var dynamicParams = new DynamicParameters();
            var conn = _baseService.GetConnection(_db.GetConnString());

            try
            {
                dynamicParams.Add("@username", admin.Username, DbType.String, ParameterDirection.Input);
                dynamicParams.Add("@pass", admin.Password, DbType.String, ParameterDirection.Input);

                result = SqlMapper.Query<Admin>(conn, "dbo.SP_Admin_Login @username, @pass", dynamicParams).SingleOrDefault();

                conn.Close();

                if (result != null amp;amp; result.Id > 0)
                {
                    result.Accesses = (result != null amp;amp; result.Id > 0) ? Accesses(result.Id) : new List<Access>();
                }

                return resu<
            }
            catch(Exception ex)
            {
                return resu<
            }
        }

        public List<Access> Accesses(int refAdmin)
        {
            List<Access> result = new List<Access>();
            var dynamicParams = new DynamicParameters();

            var conn = _baseService.GetConnection(_db.GetConnString());

            try
            {
                dynamicParams.Add("@refAdmin", refAdmin, DbType.Int32, ParameterDirection.Input);

                result = SqlMapper.Query<Access>(conn, "dbo.SP_Admin_Accesses @refAdmin", dynamicParams).ToList();

                conn.Close();

                return resu<
            }
            catch (Exception e)
            {
                return resu<
            }
        }
    }
}
 

Моя проблема в том, что код не принимает в дескрипторе запроса, я получаю эту ошибку:

Ошибка CS0161
‘UserLoginRequestHandlers.Дескриптор(UserLoginRequest, CancellationToken)’: не все пути кода возвращают значение

Я новичок в C#, поэтому не смог обнаружить ошибку. Как я могу решить эту проблему?

Заранее спасибо

Комментарии:

1. Ручка нуждается в возврате

2. похоже, что использование Task.Run() здесь не является правильным использованием. смотрите здесь использование для docs.microsoft.com/en-us/dotnet/api/. … вы можете просто сделать public async Task<BaseResponse<Admin>> Handle(UserLoginRequest request, CancellationToken cancellationToken) { return _userService.Login(request.UserCredentials); }

3. return await Task.FromResult(_userService.Login(request.UserCredentials));

4. Не знаю, почему вы пытаетесь использовать Task.Run здесь. Вместо этого просто сделайте return await Task.FromResult(_userService.Login(request.UserCredentials));

5. @DavidG заранее я думаю, что ожидание результата Task.FromResult -это тоже немного странная вещь.

Ответ №1:

В методе отсутствует оператор return Handle , но его добавление само по себе не исправит компиляцию, которую вам нужно перевести Admin , возвращенную _userService.Login в BaseResponse<Admin> . Кроме того, поскольку _userService.Login это метод синхронизации — нет необходимости Task.Run и вместо этого используется ожидание Task.FromResult синхронизации. Что-то вроде этого (усваивание существования соответствующего BaseResponse ctor):

 public Task<BaseResponse<Admin>> Handle(UserLoginRequest request, CancellationToken cancellationToken)
{
    var admin = _userService.Login(request.UserCredentials);
    return Task.FromResult(new BaseResponse<Admin>(admin)); // no need for Task.Run and async-await cause Login is synchronous method
}
 

Ответ №2:

Другой подход заключается в создании вашего сервиса как async :

  public async Task<Admin> Login(Admin admin)
 

И вам нужен соответствующий конструктор в вашем BaseResponse классе:

 public async Task<BaseResponse<Admin>> Handle(UserLoginRequest request, CancellationToken cancellationToken)
{   
    Admin admin = await _userService.Login(request.UserCredentials);           
   
    return new BaseResponse<Admin>(admin);            
}
 

BaseResponse пример:

 public class BaseResponse<T>
{
    private T Response;

    public BaseResponse(T response)
    {
        Response = response;
    }
}
 

Комментарии:

1. Это решение предполагает, что Task<Admin> оно неявно преобразуется в BaseResponse<Admin> . Если вы предлагаете сделать Login метод асинхронным, то я согласен, но этот фрагмент кода сам по себе неверен.

2. Пожалуйста, добавьте дополнительные сведения, чтобы расширить свой ответ, например, ссылки на рабочий код или документацию.