Hand in hand to teach you the implementation of aspnetcore webapi data verification

Time:2021-1-4

preface

Xiao Ming is in trouble again recently. Xiao Hong hopes to verify the data transmitted by the interface. Since it’s Xiao Hong’s requirement, Xiao Ming says that everything must be satisfied. It’s not easy.

Traditional verification

[HttpPost]
public async Task<ActionResult<Todo>> PostTodo(Todo todo)
{
  if (string.IsNullOrEmpty(todo.Name))
  {
    Return OK ("name cannot be empty");
  }
  context.Todo.Add(todo);
  await context.SaveChangesAsync();

  return CreatedAtAction("GetTodo", new { id = todo.Id }, todo);
}

Xiaoming wrote that he found that many of the same interfaces had to be written in this way, which made the code cumbersome.

Using model validation

Annotate the parametric model

namespace App001.Models
{
  /// <summary>
  ///To do list
  /// </summary>
  public class Todo
  {
    /// <summary>
    /// ID
    /// </summary>
    public Guid Id { get; set; }
    /// <summary>
    ///Name
    /// </summary>
    [required (ErrorMessage = name cannot be empty)]
    public string Name { get; set; }
  }
}

When the value passed by postman test name is not empty, return:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "|df184e36-4e11844dfd38a626.",
  "errors": {
    "Name": [
      "Name cannot be empty"
    ]
  }
}

Note that web API controllers have the [apicontroller] feature, so they don’t have to be checked ModelState.IsValid 。 In this case, if the model state is invalid, an automatic HTTP 400 response with error details is returned.

Built in features

  • [creditcard]: verify that the attribute has a credit card format.
  • [compare]: verify whether two attributes in the model match.
  • [email address]: verify that the property has email format.
  • [phone]: verify that the property has a phone number format.
  • [range]: verify whether the attribute value is in the specified range.
  • [regularexpression]: verify that the property value matches the specified regular expression.
  • [required]: verify that the field is not null.
  • [stringlength]: verify whether the string property value does not exceed the specified length limit.
  • [url]: verify that the attribute has a URL format.
  • [remote]: verify the input on the client by calling the operation method on the server.

Error messages

The validation feature allows you to specify an error message to display for invalid input. For example:

[required (ErrorMessage = name cannot be empty)]

Use custom return message format

There are two ways:

  • Using custom filters
  • To use the default model validation, you need to add [apicontroller] to the controller.

Using custom filters

First, create the modelvalidateactionfilterattribute filter.

public class ModelValidateActionFilterAttribute : ActionFilterAttribute
{
  public override void OnActionExecuting(ActionExecutingContext context)
  {
    if (!context.ModelState.IsValid)
    {
      //Gets the model field that failed validation
      var errors = context.ModelState
        .Where(e => e.Value.Errors.Count > 0)
        .Select(e => e.Value.Errors.First().ErrorMessage)
        .ToList();

      var str = string.Join("|", errors);

      //Set return content
      var result = new
      {
        Code = 10000,
        MSG = failed data validation. "
        FullMsg = str
      };

      context.Result = new BadRequestObjectResult(result);
    }

  }
}

then, Startup.ConfigureServices In addition, we added the addtownsoft filter to the default model and verified it.

//Turn off default model validation
services.Configure<ApiBehaviorOptions>(opt => opt.SuppressModelStateInvalidFilter = true);
services.AddControllers(opt =>
{
  //Add filter
  opt.Filters.Add(typeof(ModelValidateActionFilterAttribute));
}).AddNewtonsoftJson(opt =>
{
  //JSON string case as is output
  opt.SerializerSettings.ContractResolver = new DefaultContractResolver();
});

Finally, let’s look at the return effect

{
  "Code": 10000,
  "MSG": "failed data validation. "
  "Fullmsg": "name cannot be empty. "
}

Use default model validation

services.Configure<ApiBehaviorOptions>(opt =>
{
  opt.InvalidModelStateResponseFactory = actionContext =>
  {
    //Gets the model field that failed validation 
    var errors = actionContext.ModelState
      .Where(e => e.Value.Errors.Count > 0)
      .Select(e => e.Value.Errors.First().ErrorMessage)
      .ToList();

    var str = string.Join("|", errors);

    //Set return content
    var result = new
    {
      Code = 10000,
      MSG = failed data validation. "
      FullMsg = str
    };

    return new BadRequestObjectResult(result);
  };
});

Summary

So far, Xiao Ming has finished the data verification, isn’t it so easy!

Here is the article about how to teach you the realization of aspnetcore webapi data verification. For more information about aspnetcore webapi data verification, please search previous articles of developer or continue to browse the following articles. I hope you can support developer more in the future!