Ação mvc2 para lidar com vários modelos
-
25-09-2019 - |
Pergunta
Eu tenho procurado uma resposta para isso, o que não acredito que não foi perguntado antes, mas sem sorte estou tentando aqui.
Eu tenho um formulário de inscrição que difere um pouco com base em que tipo de participante é o solicitante. Ao escrever testes para a solução, percebi que todas as ações fizeram as mesmas coisas, por isso estou tentando combinar as ações em uma usando um padrão de estratégia.
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 }
Aqui está a ação combinada:
[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());
}
O problema que estou tendo é que o TryUpDatemodel liga apenas as propriedades comuns encontradas no Baseform. Meu código anterior usou o Public ActionResult FormName (int id, formx formx) que vinculou corretamente. No entanto, fiz alguns testes e descobri que, se eu substituir o formulário VAR pelo formulário do formulário, o formulário se liga e tudo funcionar, mas estou de volta a uma ação por tipo de formulário.
Espero encontrar uma maneira de fazer isso se ligar adequadamente. Form.gettype () retorna a classe não-base adequada do formulário, mas não tenho certeza de como pegar o construtor, instanciar uma classe e depois jogá-la no TryUpDatemodel. Sei que a outra possibilidade é um Modelbinder personalizado, mas não vejo uma maneira de criar uma sem encontrar o mesmo problema de formbase.
Alguma idéia ou sugestão de onde procurar?
Solução 2
Eu descobri!
A resposta de Erik não foi a solução, mas por algum motivo me fez pensar na solução.
O que eu realmente quero que a forma seja é um tipo dinâmico. Se eu mudar esta linha:
dynamic form = uiWrapper.GetForm();
Tudo funciona :)
Além disso, o Logic.Save (form.todomainClass ()) também vai diretamente para salvar (domaintypeoffform) em vez de salvar (basearMainform) para que eu possa evitar a dor de cabeça lá também. Eu sabia que, uma vez que descobri o problema aqui, eu também poderia aplicar a resposta na minha aula de lógica.
Outras dicas
Eu estava tentando fazer algo semelhante ao LINQ, estava tentando criar uma classe que herdaria alguns campos padrão (ID, etc.). Descobri que o mecanismo LINQ padrão usaria apenas os campos da classe instanciada, não de quaisquer classes ou interfaces herdadas.
Para construir a Type
Basta usar o código como:
var form = Activator.CreateInstance(uiWrapper.GetForm());