来自URI的Web API ModelBinding

lbr*_*him 11 c# asp.net-web-api asp.net-web-api2

所以我有一个为DateTime类型实现的自定义Model Binder ,我将其注册如下:

void Application_Start(object sender, EventArgs e)
{
    // Code that runs on application startup
    GlobalConfiguration.Configuration.BindParameter(typeof(DateTime), new CurrentCultureDateTimeAPI());
}
Run Code Online (Sandbox Code Playgroud)

然后我设置了2个示例操作以查看我的自定义模型绑定是否发生:

    [HttpGet]
    public void BindDateTime([FromUri]DateTime datetime)
    {
        //http://localhost:26171/web/api/BindDateTime?datetime=09/12/2014
    }


    [HttpGet]
    public void BindModel([FromUri]User user)
    {
        //http://localhost:26171/web/api/BindModel?Name=ibrahim&JoinDate=09/12/2014
    }
Run Code Online (Sandbox Code Playgroud)

当我运行,并从提到的URL调用这两个动作,userJoinDate财产被成功地使用定制绑定我配置的约束,但BindDateTimedatetime参数没有得到使用自定义粘合剂粘结.

我已经在配置中指定所有DateTime应该使用我的自定义绑定器然后为什么冷漠?建议非常感谢.

CurrentCultureDateTimeAPI.cs:

public class CurrentCultureDateTimeAPI: IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        var date = value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
        bindingContext.Model = date;
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:如果我使用,[FromUri(Binder=typeof(CurrentCultureDateTimeAPI))]DateTime datetime那么它按预期工作,但又为什么?

now*_*ed. 6

非常令人惊讶:)

我最初的疑问是这一行:

 GlobalConfiguration.Configuration.BindParameter(typeof(DateTime), new CurrentCultureDateTimeAPI());
Run Code Online (Sandbox Code Playgroud)

MSDNGlobalConfiguration=> GlobalConfiguration provides a global System.Web.HTTP.HttpConfiguration for ASP.NET application.

但出于奇怪的原因,这似乎不适用于这种特殊情况.

所以,

只需在静态类中添加此行 WebApiConfig

 config.BindParameter(typeof(DateTime), new CurrentCultureDateTimeAPI());
Run Code Online (Sandbox Code Playgroud)

这样你的WebAPIConfig文件看起来像:

 public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "web/{controller}/{action}/{datetime}",
                defaults: new { controller = "API", datetime = RouteParameter.Optional }
            );

            config.BindParameter(typeof(DateTime), new CurrentCultureDateTimeAPI());
        }
Run Code Online (Sandbox Code Playgroud)

一切正常,因为这个方法是直接调用的,WebAPI framework所以一定要CurrentCultureDateTimeAPI注册.

用您的解决方案检查这一点,效果很好.

注意:( 来自评论)你仍然可以支持Attribute Routing,你不需要注释掉这一行config.MapHttpAttributeRoutes().

但是,如果有人能说出为什么不成功,那就太好GlobalConfiguration