ASP.NET Web API模型绑定

Gle*_*hes 6 asp.net-mvc asp.net-web-api

我在ASP .NET MVC 4 RC中使用Web API,我有一个方法,它采用具有可为空的DateTime属性的复杂对象.我希望从查询字符串中读取输入的值,所以我有这样的事情:

public class MyCriteria
{
    public int? ID { get; set; }
    public DateTime? Date { get; set; }
}

[HttpGet]
public IEnumerable<MyResult> Search([FromUri]MyCriteria criteria)
{
    // Do stuff here.
}
Run Code Online (Sandbox Code Playgroud)

如果我在查询字符串中传递标准日期格式(例如01/15/2012),这很有效:

http://mysite/Search?ID=1&Date=01/15/2012
Run Code Online (Sandbox Code Playgroud)

但是,我想为DateTime指定一个自定义格式(可能是MMddyyyy)...例如:

http://mysite/Search?ID=1&Date=01152012
Run Code Online (Sandbox Code Playgroud)

编辑:

我已经尝试应用自定义模型绑定器,但我没有运气只将其应用于DateTime对象.我试过的ModelBinderProvider看起来像这样:

public class DateTimeModelBinderProvider : ModelBinderProvider
{
    public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType == typeof(DateTime) || bindingContext.ModelType == typeof(DateTime?))
        {
            return new DateTimeModelBinder();
        }
        return null;
    }
}

// In the Global.asax
GlobalConfiguration.Configuration.Services.Add(typeof(ModelBinderProvider), new DateTimeModelBinderProvider());
Run Code Online (Sandbox Code Playgroud)

创建了新的模型绑定程序提供程序,但GetBinder仅调用一次(对于复杂模型参数,但不是模型中的每个属性).这是有道理的,但我想找到一种方法来使用my DateTimeModelBinderfor DateTime属性,同时使用非DateTime属性的默认绑定.有没有办法覆盖默认值ModelBinder并指定每个属性的绑定方式?

谢谢!!!

Fau*_*ust 1

考虑将视图模型的Date属性设置为 typestring

然后编写一个实用函数来处理视图模型类型和域模型类型之间的映射:

public static MyCriteria MapMyCriteriaViewModelToDomain(MyCriteriaViewModel model){

    var date = Convert.ToDateTime(model.Date.Substring(0,2) + "/" model.Date.Substring(2,2) + "/" model.Date.Substring(4,2));

    return new MyCriteria
    {
        ID = model.ID,
        Date = date
    };

}
Run Code Online (Sandbox Code Playgroud)

或者使用像AutoMapper这样的工具,如下所示:

在 Global.asax 中

//if passed as MMDDYYYY:
Mapper.CreateMap<MyCriteriaViewModel, MyCriteria>().
    .ForMember(
          dest => dest.Date, 
          opt => opt.MapFrom(src => Convert.ToDateTime(src.Date.Substring(0,2) + "/" src.Date.Substring(2,2) + "/" src.Date.Substring(4,2)))
);
Run Code Online (Sandbox Code Playgroud)

并在控制器中:

public ActionResult MyAction(MyCriteriaViewModel model)
{
    var myCriteria = Mapper.Map<MyCriteriaViewModel, MyCriteria>(model);

    //  etc.
}
Run Code Online (Sandbox Code Playgroud)

从这个例子来看,AutoMapper 似乎没有提供任何附加值。当您使用通常具有比此示例更多属性的对象配置多个或多个映射时,它的价值就出现了。CreateMap 将自动映射具有相同名称和类型的属性,因此它可以节省大量输入,而且更加干燥。

  • 我使用过 AutoMapper,并且喜欢它提供的功能,但我仍然更喜欢在执行操作之前应用此映射。恕我直言,这样看起来更干净。我还需要定义 API 控制器实现的接口。该接口将用于动态创建 API 客户端。我希望接口在定义期望时更加明确,而不是接受字符串。 (2认同)