public ActionResult<string> GetUserName(string userId, [FromServices]IUserService userService) { return Ok($"{userService.GetUserName(userId)}"); }
4、执行结果如下:
参数验证
参数验证是非常重要的,否则本来是 4XX 的问题就会变成 5XX 的问题,参数验证有这么几种:
Data Annotations
自定义 Attribute
实现 IValitableObject 接口
使用第三方的验证库,比如 FluentValidation
Data Annotations
1、在 User 的实体类上添加相关特性
1 2 3 4 5 6 7 8
public class User { [Required(ErrorMessage = "姓名不能为空")] public string Name { get; set; } [EmailAddress(ErrorMessage = "邮件格式不正确")] public string Email { get; set; } }
1、将 User 类继承 IValitableObject 接口,并实现 Validate 方法,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
public class User: IValidatableObject { [Required(ErrorMessage = "姓名不能为空")] public string Name { get; set; } [EmailAddress(ErrorMessage = "邮件格式不正确")] public string Email { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (Name == Email) { yield return new ValidationResult("名称不能和邮箱相等", new []{nameof(Name),nameof(Email)}); } } }
1、创建 NameNotEqualEmailAttribute 类,用来实现判断 User 类中的名称和邮箱不能相等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
public class NameNotEqualEmailAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var user = validationContext.ObjectInstance as User; if (user.Name == user.Email) { return new ValidationResult("名称不能和邮箱相等", new []{nameof(User)}); } return ValidationResult.Success; } }
2、在 User 类上添加此特性
1 2 3 4 5 6 7 8 9
[NameNotEqualEmail] public class User { [Required(ErrorMessage = "姓名不能为空")] public string Name { get; set; } [EmailAddress(ErrorMessage = "邮件格式不正确")] public string Email { get; set; } }
public class StringToListModelBinder: IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { if (!bindingContext.ModelMetadata.IsEnumerableType) { bindingContext.Result = ModelBindingResult.Failed(); return Task.CompletedTask; }
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).ToString(); if (string.IsNullOrWhiteSpace(value)) { bindingContext.Result = ModelBindingResult.Success(null); return Task.CompletedTask; }
var elementType = bindingContext.ModelType.GetTypeInfo().GenericTypeArguments[0]; var converter = TypeDescriptor.GetConverter(elementType);
var values = value.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) .Select(x => converter.ConvertFromString(x.Trim())).ToArray(); var typedValues = Array.CreateInstance(elementType, values.Length); values.CopyTo(typedValues,0);
[HttpGet("ids")] public ActionResult<List<User>> GetUsersByIds( [ModelBinder(BinderType = typeof(StringToListModelBinder))]IEnumerable<string> ids) { if (ids == null) { return BadRequest(); }
return Ok();
}
3、调用结果
返回值
返回 XML 格式
尽管使用 Web API 通常都是使用 JSON 格式,但有些时候需要返回 XML 格式,默认情况下,即使请求头中添加了 Accept=application/xml,接口依然会返回 JSON 格式的结果,想要返回 XML 格式,修改 Startup 类的 ConfigureServices 方法即可。
public static class IEnumerableExtension { public static IEnumerable<ExpandoObject> GetData<T> (this IEnumerable<T> source, string fields) { if (source == null) { throw new ArgumentNullException(nameof(source)); } var objectList = new List<ExpandoObject>(source.Count()); var propertyInfoList = new List<PropertyInfo>();
if (string.IsNullOrWhiteSpace(fields)) { var propertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); propertyInfoList.AddRange(propertyInfos); } else { var fieldSplit = fields.Split(','); foreach (var field in fieldSplit) { var propertyName = field.Trim(); var propertyInfo = typeof(T).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); if (propertyInfo == null) { throw new Exception($"属性名:{propertyName} 没有找到"); }
propertyInfoList.Add(propertyInfo); } }
foreach (T t in source) { var obj=new ExpandoObject(); foreach (var propertyInfo in propertyInfoList) { var value = propertyInfo.GetValue(t); ((IDictionary<string, object>) obj).Add(propertyInfo.Name, value); } objectList.Add(obj); } return objectList; } }
2、创建获取用户列表的 Action 方法
1 2 3 4 5 6 7 8 9 10 11 12 13
[HttpGet] public ActionResult GetUsers([FromBody]string fields) { var userList =new List<User>() { new User(){ Name = "oec2003",Email = "[email protected]",Password = "123456"}, new User(){ Name = "oec2004",Email = "[email protected]",Password = "123456"}, new User(){ Name = "oec2004",Email = "[email protected]",Password = "123456"} }; var returnResult = base.Mapper.Map<List<UserDto>>(userList); //使用扩展方法按需获取 return Ok(returnResult.GetData(fields)); }
3、查看调用结果
返回一个属性 Name
返回所有
最后
本文只是涉及了在 Web API 中比较常用的一些功能点,限于篇幅,每个点并没有写的非常深入,也较少涉及原理,但我们在学习过程中,除了实现效果外还应该深入去了解其中细节和原理。