1

リフレクションを使用して、BindingContext から取得した指定された型のオブジェクトにプロパティを割り当てる汎用モデル バインダーを構築しようとしています。だから、このようなもの:

public class ModelBinder : IModelBinder
{
    public object BindModel<T, K> (ControllerContext controllerContext, ModelBindingContext bindingContext)
        where T : class, new()
        where K : class
    {
        Type ObjectType = typeof(T);
        Type InterfaceType = typeof(K);
        T obj = new T();

        foreach (var Property in ObjectType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance))
        {
            Type PropertyType = Property.PropertyType;

            // checks if property is a custom data object
            if (!(PropertyType.GetGenericArguments().Count() > 0 && PropertyType.GetGenericArguments()[0].GetInterfaces().Contains(InterfaceType)))
            {
                Property.SetValue(obj, bindingContext.ValueProvider.GetValue(Property.Name), null);   
            }
        }

        return obj;
    }

IModelBinder インターフェイスを正しく実装していないため、明らかにこれは機能しません。このようなことは可能ですか?

編集:

私がこれを行っている理由をさらに詳しく説明すると、私たちのオブジェクトはさまざまなカスタム オブジェクトを使用しています。たとえば、 Class オブジェクト:

public class Class : ModelBase<Class>
{
    public Class () { }

    public virtual string ClassDescription { get; set; }
    public virtual string ClassName { get; set; }
    public virtual LookUp ClassType { get; set; }
    public virtual double Credits { get; set; }
    public virtual bool Documents { get; set; }
    public virtual LookUp PracticeArea { get; set; }
}

LookUp クラスを使用します。

public class LookUp : ModelBase<LookUp>
{
    public LookUp () { }

    public virtual string DisplayName { get; set; }
    public virtual LookUpType Type { get; set; }
}

ドロップダウンはルックアップやその他のオブジェクトに使用されるため、クラス/作成用のカスタム モデル バインダーは次のようになります。

LookUp ClassType = LookUp.Load(long.Parse(bindingContext.ValueProvider.GetValue("ClassType").AttemptedValue))

DefaultModelBinder を使用してこのような処理を行う方法がわかりません。

4

1 に答える 1

2

だから私は(今のところ)実用的な解決策を思いついた。現時点ではあまり一般的ではありませんが、私の目的には機能します。

public class ModelBinder : DefaultModelBinder
{
    public override object BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var ModelType = bindingContext.ModelType;
        var Instance = Activator.CreateInstance(ModelType);
        var Form = bindingContext.ValueProvider;

        foreach (var Property in ModelType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance))
        {
            Type PropertyType = Property.PropertyType;

            // I'm using an ORM so this checks whether or not the property is a
            // reference to another object
            if (!(PropertyType.GetGenericArguments().Count() > 0 ))
            {
                // This is the not so generic part.  It really just checks whether or 
                // not it is a custom object.  Also the .Load() method is specific
                // to the ORM
                if (PropertyType.FullName.StartsWith("Objects.Models"))
                {
                    var Load = PropertyType.GetMethod("Load", BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Static, null, new Type[] { typeof(long) }, null);
                    var Value = Load.Invoke(new object(), new object[] { long.Parse(Form.GetValue(Property.Name + ".ID").AttemptedValue) });
                    Property.SetValue(Instance, Value, null);
                }
                // checkboxes are weird and require a special case
                else if (PropertyType.Equals(typeof(bool)))
                {
                    if (Form.GetValue(Property.Name) == null)
                    {
                        Property.SetValue(Instance, false, null);
                    }
                    else if (Form.GetValue(Property.Name).Equals("on"))
                    {
                        Property.SetValue(Instance, true, null);
                    }
                }
                else
                {
                    Property.SetValue(Instance, Convert.ChangeType(bindingContext.ValueProvider.GetValue(Property.Name).AttemptedValue, PropertyType), null);
                }
            }
        }

        return Instance;
    }
}
于 2012-10-17T22:18:35.760 に答える