Web API模型将字符串值绑定到Enum []

时间:2019-07-12 08:28:45

标签: c# asp.net-web-api model-binding

我有一个.NET Web API,我的一种API方法采用了“状态”参数。

在我的代码中,我有一个带有各种状态值的枚举(MyStatusEnum),但是,我不希望我们API的用户提供任何那些值。相反,我希望它们提供一个更简单的状态值,该状态值最终会映射到我们的基础状态枚举值中的一个(或多个)。

例如,我的API的用户必须提供'InProgress'或'Completed'的状态值,但是我希望通过模型绑定将'InProgress'映射到MyStatusEnum数组,其中该值被认为是为“进行中”,同样为“完成”。

public enum MyStatusEnum
{
  StartedStepA = 1, // InProgress
  StartedStepB = 2, // InProgress
  StartedStepC = 3, // InProgress
  FinishedStepA = 4, // Completed
  FinishedStepB = 5, // Completed
  FinishedStepC = 6 // Completed
}

public class ApiInputModel
{
    public MyStatusEnum[] Status {get; set;}
}

因此,在此示例中,如果他们提供的状态值为Completed,则希望模型的MyStatsEnum(数组)属性包含FinishedStepA,FinishedStepB和FinishedStepC。

2 个答案:

答案 0 :(得分:0)

您可以使用DTO模式DTO PatternAutoMapper在反序列化之后执行映射的一种方法。我将草绘代码。

public class ApiInputModel
{
    public MyStatusEnum[] Status {get; set;}
}

public class ApiInputModelDTO
{
    // May be better to add an enum here to validate that the user is only inputting "InProgress" and "Completed".
    public string Status {get; set;}
}

现在使用AutoMapper创建这两种类型之间的映射配置文件(您可以在没有AutoMapper的情况下执行此操作,但是该库使它更容易实现):

public class MappingProfile : Profile
{
   this.CreateMap<ApiInputModelDTO, ApiInputModel>().ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.Status == "Completed" ? new[] { /* your array elements for "Completed" */ } : new[] { /* your array element for "InProgress" */ }))
}

现在在您的控制器中,您可以执行映射:

public class MyController
{
    private readonly IMapper mapper;

    public MyController(IMapper mapper)
    {
       this.mapper = mapper;
    }

    public IActionResult MyMethod(ApiInputModelDTO input)
    {
       var inputModel = this.mapper.Map<ApiInputModel>(input);
       // Do what you want with it...
    }
}

答案 1 :(得分:0)

public class ApiInputModel
{
  public MyStatusEnum Status {get; set;}
 }


[HttpPost]
 public IActionResult Test([FromBody] ApiInputModel model)
 {
        var statuses = Enum.GetNames(typeof(MyStatusEnum)).ToList();

        if (model.Status == MyStatusEnum.FinishedStepC)
        return Ok(statuses.Where(x => x.Contains("FinishedStep")));
        else
         return Ok();
  }

所以在Swagger上测试

enter image description here