Issue with base response type
See original GitHub issueI try to implement validation behavior in asp.net core 2.1 application. My controller:
[HttpPost]
public async Task<CommandResponse<Application>> Post([FromBody] CreateApplicationCommand command)
{
var response = await _mediator.Send(command);
return response;
}
ValidationBehavior:
public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TResponse : CommandResponse
{
private readonly IEnumerable<IValidator> _validators;
public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators)
{
_validators = validators;
}
public Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var failures = _validators
.Select(v => v.Validate(request))
.SelectMany(result => result.Errors)
.Where(f => f != null)
.ToList();
return failures.Any()
? Errors(failures)
: next();
}
private static Task<TResponse> Errors(IEnumerable<ValidationFailure> failures)
{
var response = new CommandResponse();
foreach (var failure in failures)
{
response.AddError(failure.ErrorMessage);
}
return Task.FromResult(response as TResponse);
}
}
Response:
public class CommandResponse
{
private readonly IList<string> _errorMessages = new List<string>();
public void AddError(string errorMessage)
{
_errorMessages.Add(errorMessage);
}
public bool IsSucceed => !_errorMessages.Any();
public IReadOnlyCollection<string> Errors => new ReadOnlyCollection<string>(_errorMessages);
}
public class CommandResponse<TModel> : CommandResponse where TModel : class
{
public CommandResponse(TModel model)
{
Result = model;
}
public TModel Result { get; }
}
Container registration (Asp.Net Core DI with Scrutor):
public static void AddMediator(this IServiceCollection services)
{
services.AddScoped<ServiceFactory>(p => p.GetService);
services.AddScoped<IMediator, Mediator>();
services.Scan(scan => scan
.FromAssemblies(Assembly.GetExecutingAssembly())
.AddClasses(classes => classes.AssignableTo(typeof(IRequestHandler<,>)))
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(IValidator<>)))
.AsImplementedInterfaces()
.WithScopedLifetime());
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
}
If CreateApplicationCommand is valid everything works fine. When validation failure occures I expect to receive an instance of CommandResponse class with error messages. However response in controller in this case is null. What I am doing wrong?
Issue Analytics
- State:
- Created 5 years ago
- Comments:11 (4 by maintainers)
Top Results From Across the Web
Type 'BaseResponse<IavailableParameters[]>' is missing ...
It is an object with properties isSuccessful , error , and results . The property results is an array IavailableParameters[] .
Read more >responseType setting base on have responsed · Issue #1500
I have the same issue. Example: axios.get('/file', { responseType ...
Read more >Response: type property - Web APIs - MDN Web Docs
The type read-only property of the Response interface contains the type of the response. It can be one of the following: basic :...
Read more >Help creating a base response class to use in a Web API
So I recently picked up ASP.NET project for the first time and have been working on a Web API. I am not used...
Read more >Handle errors in ASP.NET Core web APIs
Learn about error handling with ASP.NET Core web APIs.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@MaciejWierzchowski Fixed using an
Activator
Caveat : Your TResponse should have a default constructor
Yep, basically what @joaomatossilva said. A base class of that can be Success or Failure, and the Failure result has properties for validation failure messages or any other metadata needed. All handled by a pipeline behavior that injects
IValidators
similar to what you have above. All request responses are wrapped in the particular Result response type and we have custom interfaces to help simplify this as well when creating commands, queries and handlers.