#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. Пожалуйста, добавьте дополнительные сведения, чтобы расширить свой ответ, например, ссылки на рабочий код или документацию.