【问题标题】:Web API Model Binding string value to Enum[]Web API 模型绑定字符串值到 Enum[]
【发布时间】:2019-07-12 08:28:45
【问题描述】:

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

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

例如,我的 API 的用户必须提供状态值“InProgress”或“Completed”,但我希望模型绑定将“InProgress”映射到 MyStatusEnum 数组,其中的值被视为为“InProgress”,同样为“Completed”。

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。

【问题讨论】:

  • 你看this answer了吗?解决方案是让您的序列化程序将字符串值映射到您的枚举属性。只需将您的 Status 属性归因即可。

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


【解决方案1】:

一种方法可以使用 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...
    }
}

【讨论】:

    【解决方案2】:
    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 上测试时

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 2018-01-30
      • 2014-05-21
      • 1970-01-01
      相关资源
      最近更新 更多