0

I'm trying to emulate the behavior of the [ApiController] attribute for model validation, however I'd like to return a JSON object I've made with the validation errors in an Error array within the JSON.

The challenge I'm facing is that I'm unsure how to access validation errors from within the Attribute and I'd like to use the attribute at the class level, so it will run on all controller methods without need of supplying the attribute for each action.

Any direction would be much appreciated.

edit: linked duplicate is how to create custom attribute. I'm looking how to access model validation errors from within an attribute.

expenguin
  • 1,052
  • 2
  • 21
  • 42
  • Please show your code and what you have tried. – Mohammed Noureldin Jun 01 '18 at 16:13
  • Possible duplicate of [How to create a custom validation attribute?](https://stackoverflow.com/questions/11959431/how-to-create-a-custom-validation-attribute) – Mohammed Noureldin Jun 01 '18 at 16:14
  • @MohammedNoureldin I don't have any code as this is more a concept that I'm not familiar with. Since .net core 2.1 is super new, there isn't any real information out there as to how to do this, so I'm trying to start the process by asking here. I know how to create a custom attribute, my issue is how to access validation errors from a model within the attribute and how to set an attribute to be used at the class level. – expenguin Jun 01 '18 at 17:09

1 Answers1

0

I was able to figure out my issue. I was able to utilize ModelState.IsValid in an OnActionExecuting method to access the errors. Unfortunately I'm not familiar enough with making a class level attribute so I have to apply this to all post/patch methods in order for it to work. If someone else comes up with a way to do that easily, let me know!

Project.Structure is for formatting JSON for those curious.

using System;
using System.Collections.Generic;
using System.Linq;
using Project.Structure;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Project.Attributes
{
   public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (!context.ModelState.IsValid)
            {
                var errorList = new List<string>();
                foreach (var modelError in context.ModelState.Values)
                {
                    errorList.AddRange(modelError.Errors.Select(error => error.ErrorMessage));
                }

                var response = new ResponseDto<object>
                {
                    Success = false,
                    TransactionId = Guid.NewGuid().ToString(),
                    ResponseType = ResponseType.Operation.Description(),
                    Response = null,
                    Errors = errorList,
                    Warnings = null
                };

                context.Result = new BadRequestObjectResult(response);
            }
        }
    }
}
expenguin
  • 1,052
  • 2
  • 21
  • 42