14

我需要使用某种自定义模型绑定器来始终处理英国格式的传入日期,我已经设置了一个自定义模型绑定器并像这样注册:

GlobalConfiguration.Configuration.BindParameter(typeof(DateTime), new DateTimeModelBinder());

这似乎只适用于查询字符串参数,并且只有当我像这样在我的参数上指定 [ModelBinder] 时才有效,有没有办法让所有操作都使用我的模型绑定器:

public IList<LeadsLeadRowViewModel> Get([ModelBinder]LeadsIndexViewModel inputModel)

另外,我怎样才能将我发布的表单发送到我的 Api 控制器以使用我的模型绑定器?

4

4 回答 4

6

您可以通过实现 ModelBinderProvider 并将其插入服务列表来全局注册模型绑定器。

Global.asax 中的使用示例:

GlobalConfiguration.Configuration.Services.Insert(typeof(ModelBinderProvider), 0, new Core.Api.ModelBinders.DateTimeModelBinderProvider());

下面是演示 ModelBinderProvider 和 ModelProvider 实现的示例代码,它以文化感知方式(使用当前线程文化)转换 DateTime 参数;

DateTimeModelBinderProvider 实现:

using System;
using System.Web.Http;
using System.Web.Http.ModelBinding;

...

public class DateTimeModelBinderProvider : ModelBinderProvider
{
    readonly DateTimeModelBinder binder = new DateTimeModelBinder();

    public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType)
    {
        if (DateTimeModelBinder.CanBindType(modelType))
        {
            return binder;
        }

        return null; 
    }
}

DateTimeModelBinder 实现:

public class DateTimeModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        ValidateBindingContext(bindingContext);

        if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName) ||
            !CanBindType(bindingContext.ModelType))
        {
            return false;
        }

        bindingContext.Model = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName)
            .ConvertTo(bindingContext.ModelType, Thread.CurrentThread.CurrentCulture);

        bindingContext.ValidationNode.ValidateAllProperties = true;

        return true;
    }

    private static void ValidateBindingContext(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException("bindingContext");
        }

        if (bindingContext.ModelMetadata == null)
        {
            throw new ArgumentException("ModelMetadata cannot be null", "bindingContext");
        }
    }

    public static bool CanBindType(Type modelType)
    {
        return modelType == typeof(DateTime) || modelType == typeof(DateTime?);
    }
}
于 2013-02-21T16:28:23.760 回答
5

我认为您不需要模型活页夹。你的方法不正确。日期的正确方法是使用客户端全球化库(如globalize 库)来解析以任何语言格式化的日期并将它们转换为 JavaScript 日期对象。然后,您可以使用浏览器以 JSON 格式序列化您的数据脚本数据结构JSON.stringify,这应该可以。最好始终使用标准格式的日期并使用格式化程序而不是模型活页夹。如果您使用 C# DateTime 对象的kind参数来指定日期时间是以本地时间还是以 UTC 时间表示,可用的格式化程序也可以正确处理 TimeZones 。

于 2012-09-09T23:33:22.873 回答
3

属性路由似乎与模型绑定冲突。如果您使用属性路由,您可以将global.asax配置包装到单个GlobalConfiguration.Config调用中以避免初始化问题:

GlobalConfiguration.Configure(config =>
{
    config.BindParameter(typeof(DateTime), new DateTimeModelBinder());
    config.MapHttpAttributeRoutes();
}

(如果它与错误 #1165相关,这可能会在即将发布的 ASP.NET 5 中得到修复。)

于 2014-12-02T20:57:16.330 回答
0

您不需要自定义模型绑定器。如果您的网站一直使用这种方式,您应该将线程文化更改为 UK 或将web.config 设置设置为 UK。

如果没有,您仍然可以将 CurrentCulture 的 DateTimeFormatInfo 更改为 UK 之一。

Scott Hanselman也有一篇关于模型活页夹的好文章

你可以把它放在 Global.asax 中:

ModelBinders.Binders[typeof(DateTime)] = new DateAndTimeModelBinder()  
于 2012-09-07T18:14:35.960 回答