我想写我自己的模式粘合剂 DateTime 类型。首先,我想写一个新的属性,我可以连接到我的模特性,如:

[DateTimeFormat("d.M.yyyy")]
public DateTime Birth { get; set,}

这是容易的部分。但粘合剂的一部分是一个比较困难。我想添加一个新的模式粘合剂的类型 DateTime.我可以

  • 实施 IModelBinder 接口和写我自己 BindModel() 方法
  • 继承 DefaultModelBinder 和复盖 BindModel() 方法

我的模式有一个酒店看到的上述(Birth).所以当该模型试图绑定的要求数据为这个酒店,我的型号的粘合剂 BindModel(controllerContext, bindingContext) 得到援引。一切都好,但是。 我如何获得财产的属性,从控制器/bindingContext,来分析我的日期正确?我怎么能得到的 PropertyDesciptor 财产 Birth?

编辑

由于分离的问题我的类型被限定在大会没有(并且不应)的参考系统。网。软件。设置定义结合(类似于 斯科特Hanselman的例子)的属性是一个没有放在这里。

有帮助吗?

解决方案

我不认为你应该把区域特定的属性模型。

其他两个可能的解决方案,这个问题是:

  • 有你的网页翻译的日期从该区域特定的格式通用格式,如yyyy-mm-dd在JavaScript。(工作,但需要JavaScript。)
  • 写一个模式粘合剂,认为当前用户界面培养当分析的日期。

来回答你的实际问题的方式,获得自定属性(用软2), 写一AssociatedMetadataProvider.

其他提示

你可以更改的缺省模式粘合剂使用的用户的文化,使用IModelBinder

public class DateTimeBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);

        return value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
    }
}

public class NullableDateTimeBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);

        return value == null
            ? null 
            : value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
    }
}

并且在全球。Asax以下内容添加到Application_Start():

ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder());
ModelBinders.Binders.Add(typeof(DateTime?), new NullableDateTimeBinder());

阅读更多 这个优秀的博客 这描述为什么视框架的团队实现的默认文化的所有用户。

我有个非常大的问题我自己和后小时的尝试和失败,我有一个工作方案喜欢你问。

首先,因为具有一种粘合剂的只是一个酒店是不室味必须实现全ModelBinder.因为你不希望结合所有单一的财产,但只有一个你关心你可以继承DefaultModelBinder然后绑在单一的财产:

public class DateFiexedCultureModelBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
    {
        if (propertyDescriptor.PropertyType == typeof(DateTime?))
        {
            try
            {
                var model = bindingContext.Model;
                PropertyInfo property = model.GetType().GetProperty(propertyDescriptor.Name);

                var value = bindingContext.ValueProvider.GetValue(propertyDescriptor.Name);

                if (value != null)
                {
                    System.Globalization.CultureInfo cultureinfo = new System.Globalization.CultureInfo("it-CH");
                    var date = DateTime.Parse(value.AttemptedValue, cultureinfo);
                    property.SetValue(model, date, null);
                }
            }
            catch
            {
                //If something wrong, validation should take care
            }
        }
        else
        {
            base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
        }
    }
}

在我的例子中,我析日期与fiexed文化,但是你想要做什么是可能的。你应该创建一个CustomAttribute(如DateTimeFormatAttribute),并把它放在你的财产:

[DateTimeFormat("d.M.yyyy")]
public DateTime Birth { get; set,}

现在BindProperty方法,而不是寻找一日期时间酒店你可以找个酒店有你DateTimeFormatAttribute,抢格式中指定的构造,然后分析新的日期时间。ParseExact

我希望这可以帮助,我花了很久才来这个解决方案。它实际上是容易有这样的解决方案一旦我知道如何搜索:(

你能实现一个自定义DateTime粘合剂喜欢这样,但你必须照顾有关假定的文化和价值的实际客户的要求。可能你会得到一个日期像/月/日在en-US,并希望它转换的系统的文化en-GB(其它会像日/月/年)或一个不变的文化,像我们这样做,那么你必须能够分析之前和使用的静态立面转换,以改变其行为。

    public class DateTimeModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var valueResult = bindingContext.ValueProvider
                              .GetValue(bindingContext.ModelName);
            var modelState = new ModelState {Value = valueResult};

            var resDateTime = new DateTime();

            if (valueResult == null) return null;

            if ((bindingContext.ModelType == typeof(DateTime)|| 
                bindingContext.ModelType == typeof(DateTime?)))
            {
                if (bindingContext.ModelName != "Version")
                {
                    try
                    {
                        resDateTime =
                            Convert.ToDateTime(
                                DateTime.Parse(valueResult.AttemptedValue, valueResult.Culture,
                                    DateTimeStyles.AdjustToUniversal).ToUniversalTime(), CultureInfo.InvariantCulture);
                    }
                    catch (Exception e)
                    {
                        modelState.Errors.Add(EnterpriseLibraryHelper.HandleDataLayerException(e));
                    }
                }
                else
                {
                    resDateTime =
                        Convert.ToDateTime(
                            DateTime.Parse(valueResult.AttemptedValue, valueResult.Culture), CultureInfo.InvariantCulture);
                }
            }
            bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
            return resDateTime;
        }
    }

无论如何,文化基DateTime分析在一个无国籍的应用程序可以由一个残酷...特别是当你工作结果的方式javascript客户方和倒退。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top