Asp.net mvc ASP.NET Web API模型绑定

Asp.net mvc ASP.NET Web API模型绑定,asp.net-mvc,asp.net-web-api,Asp.net Mvc,Asp.net Web Api,我在ASP.NETMVC4RC中使用WebAPI,我有一个方法,它接受一个具有可为空的日期时间属性的复杂对象。我希望从查询字符串中读取输入值,因此我有如下内容: public class MyCriteria { public int? ID { get; set; } public DateTime? Date { get; set; } } [HttpGet] public IEnumerable<MyResult> Search([FromUri]MyCrit

我在ASP.NETMVC4RC中使用WebAPI,我有一个方法,它接受一个具有可为空的日期时间属性的复杂对象。我希望从查询字符串中读取输入值,因此我有如下内容:

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

[HttpGet]
public IEnumerable<MyResult> Search([FromUri]MyCriteria criteria)
{
    // Do stuff here.
}
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());
但是,我想为DateTime指定一种自定义格式(可能是MMddyyyy)。。。例如:

http://mysite/Search?ID=1&Date=01152012

编辑: 我曾尝试应用自定义模型绑定器,但没有成功地将其仅应用于DateTime对象。我尝试过的ModelBinderProvider如下所示:

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

[HttpGet]
public IEnumerable<MyResult> Search([FromUri]MyCriteria criteria)
{
    // Do stuff here.
}
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
(对于复杂模型参数,但不针对模型中的每个属性)。这是有道理的,但我想找到一种方法,使之能够对DateTime属性使用我的
DateTimeModelBinder
,而对非DateTime属性使用默认绑定。是否有方法覆盖默认的
ModelBinder
,并指定如何绑定每个属性


谢谢

考虑将视图模型的
Date
属性设置为type
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
    };

}
或者使用像这样的工具:

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

[HttpGet]
public IEnumerable<MyResult> Search([FromUri]MyCriteria criteria)
{
    // Do stuff here.
}
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());
在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)))
);
//如果作为MMDDYYYY传递:
Mapper.CreateMap()。
福门博先生(
目的地=>目的地日期,
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.
}
公共操作结果MyAction(MyCriteriaViewModel模型)
{
var myCriteria=Mapper.Map(模型);
//等等。
}

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

-同样的问题,可能会对你有所帮助。这篇文章适用于MVC网页中的控制器操作,但我还没有找到与web API等效的。我已经尝试为WebAPI注册一个自定义模型绑定器,我认为如果我的方法采用单独的参数,它会起作用。但是,我希望它以一个复杂的对象作为输入,而我还没有找到一种方法来覆盖DateTime属性的绑定,同时对其他属性使用默认绑定。正如您已经正确提到的,您可以通过自定义绑定器来解决它吗?你到底有什么问题?我会使用一个专用的视图模型而不是域模型来向视图发送信息并再次绑定模型。然后,我将MyCriteriaViewModel.Date设置为键入字符串,并在将其映射到控制器或映射层中的域模型(MyCriteria.Date)时处理转换。@alexanderb我已更新了我的问题以提供更多详细信息。。。我还没有弄清楚如何只为某些类型的属性注册模型绑定器。我使用过AutoMapper,我喜欢它提供的功能,但我仍然希望在执行操作之前应用此映射。这样看起来更干净,伊姆霍。我还需要定义API控制器实现的接口。该接口将用于为API动态创建客户端。我希望接口在定义期望时更加明确,而不是接受字符串。