MVC2 Действие для обработки нескольких моделей - PullRequest
0 голосов
/ 30 августа 2010

Я искал ответ на этот вопрос, но я не могу поверить, что его раньше не спрашивали, но безуспешно я пытаюсь здесь.

У меня есть форма регистрации, котораянемного отличается в зависимости от типа участника, который запрашивающий.При написании тестов для решения я понял, что все действия делали одно и то же, поэтому я пытаюсь объединить действия в одно с использованием шаблона стратегии.

public abstract class BaseForm { common properties and methods }
public class Form1 : BaseForm { unique properties and overrides }
....
public class FormX : BaseForm { unique properties and overrides... in all about 5 forms }

Вот объединенное действие:

[ModelStateToTempData, HttpPost]
public ActionResult Signup(int id, FormCollection collection)
{
    uiWrapper= this.uiWrapperCollection.SingleOrDefault(w => w.CanHandle(collection));
    // nullcheck on uiWrapper, redirect if null
    var /*BaseForm*/ form = uiWrapper.GetForm();  // Returns FormX corresponding to collection.
    this.TryUpdateModel(form, collection.ToValueProvider()); // Here is the problem
    form.Validate(this.ModelState);  // Multi-Property validation unique to some forms.
    if (!this.ModelState.IsValid)
        return this.RedirectToAction(c => c.Signup(id));

    this.Logic.Save(form.ToDomainClass());
    return this.RedirectToAction(c => c.SignupComplete());
}

Проблема, с которой я столкнулся, заключается в том, что TryUpdateModel связывает только общие свойства, найденные в BaseForm.Мой предыдущий код использовал общедоступное ActionNesult FormName (int id, FormX form), которое связывалось правильно.Однако я провел некоторое тестирование и обнаружил, что если я заменю форму var на форму FormX, форма связывается, и все работает, но я возвращаюсь к одному действию для каждого типа формы.

Я надеюсь найти способчтобы это правильно связывалось.form.GetType () возвращает правильный не базовый класс формы, но я не уверен, как захватить конструктор, создать экземпляр класса и затем выбросить его в TryUpdateModel.Я знаю, что другой возможностью является пользовательский ModelBinder, но я не вижу способа создать его, не сталкиваясь с той же проблемой FormBase.

Есть идеи или предложения, где искать?

Ответы [ 2 ]

0 голосов
/ 31 августа 2010

Я понял это!

Ответ Эрика не был решением, но по какой-то причине он заставил меня задуматься над решением.

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

dynamic form = uiWrapper.GetForm();

Все работает:)

Кроме того, logic.Save (form.ToDomainClass ()) также идет непосредственно к Save (DomainTypeOfForm), а не к Save (BaseDomainForm), поэтому я также могу избежать головной боли. Я знал, что, как только я выясню проблему, я смог применить ответ и в своем классе логики.

0 голосов
/ 31 августа 2010

Я пытался сделать что-то похожее на Linq, я пытался создать класс, который унаследовал бы некоторые стандартные поля (ID и т. Д.).Я обнаружил, что движок Linq по умолчанию будет использовать поля только из экземпляра класса, а не из любых унаследованных классов или интерфейсов.

Чтобы создать Type, просто используйте код вроде:

var form = Activator.CreateInstance(uiWrapper.GetForm()); 
...