我在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.
}
如果我在查询字符串中传递标准日期格式(例如01/15/2012:
),这种方法很有效http://mysite/Search?ID=1&Date=01/15/2012
但是,我想为DateTime指定一个自定义格式(可能是MMddyyyy)...例如:
http://mysite/Search?ID=1&Date=01152012
我尝试过应用自定义模型绑定器,但我没有运气将其应用于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());
创建了新的模型绑定程序提供程序,但GetBinder
仅调用一次(对于复杂模型参数,但不是模型中的每个属性)。这是有道理的,但我想找到一种方法,使其使用我的DateTimeModelBinder
用于DateTime属性,同时使用非DateTime属性的默认绑定。有没有办法覆盖默认的ModelBinder
并指定每个属性的绑定方式?
感谢!!!
答案 0 :(得分:1)
考虑将视图模型的Date
属性设置为键入string
然后编写实用程序函数来处理viewmodel类型和域模型类型之间的映射:
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
};
}
或使用像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)))
);
并在控制器中:
public ActionResult MyAction(MyCriteriaViewModel model)
{
var myCriteria = Mapper.Map<MyCriteriaViewModel, MyCriteria>(model);
// etc.
}
从这个例子来看,似乎AutoMapper似乎没有提供任何附加价值。当您使用通常具有比此示例更多属性的对象配置多个或多个映射时,它就会产生价值。 CreateMap将自动映射具有相同名称和类型的属性,因此它可以节省大量的输入,并且可以节省很多DRYer。