Список <BaseType>Связывание модели с дескриптором типа - PullRequest
1 голос
/ 08 сентября 2011

Учитывая следующие производные типы:

public class Base {
    public string Id {get;set;}
}

public class Contact : Base {
    public string FirstName {get;set;}
    public string LastName {get;set;
}

public class Organization : Base {
    public string Name {get;set;}
}

Я хотел бы связать что-то вроде этого, используя привязку пользовательской модели:

[HttpPost]
public ActionResult UpdateMultiple(List<Base> items) {
    for each (var item in items) {
        if (item.GetType().Equals(typeof(Contact)) {
             // update
        } else if (item.GetType().Equals(typeof(Organization)) {
             // update
        }
    }
    return RedirectToAction("index");
}

Мой план состоит в том, чтобы каждый элемент имелдескриптор пользовательского типа:

<input type="hidden" name="items[0].EntityType" value="MyNamespace.Contact, MyNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<input type="text" name="items[0].FirstName" />
<input type="text" name="items[0].LastName" />

<input type="hidden" name="items[1].EntityType" value="MyNamespace.Organization, MyNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<input type="text" name="items[1].Name" />

Я разработал привязку пользовательской модели для одного объекта (не для коллекции):

 public class EntityTypeModelBinder : DefaultModelBinder
    {
        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
            var typeValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".EntityType");
            var type = Type.GetType((string)typeValue.ConvertTo(typeof(string)),true);
            var model = Activator.CreateInstance(type);
            bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
            return model;
        }
    }

Но есть ли у кого-нибудь какие-либо предложения о том, как я могупреобразовать эту модель связующего для обработки коллекции?Я в растерянности.

С наилучшими пожеланиями и спасибо за ответ.

Hal

1 Ответ

1 голос
/ 08 сентября 2011

Эта модель переплета, которую вы показали, уже обрабатывает коллекции. Все, что вам нужно, это вставить следующую строку в Application_Start:

ModelBinders.Binders.Add(typeof(Base), new EntityTypeModelBinder());

Он достаточно интеллектуален и будет работать с коллекциями, так как для List<Base> не зарегистрировано связыватель модели, это будет связывание модели по умолчанию, которое будет вызываться. Он обнаруживает, что у вас есть коллекция, и вызывает соответствующую привязку модели для каждого элемента коллекции. А поскольку вы зарегистрировали подшивку модели для типа Base, автоматически подойдет пользовательская подшивка.

...