Dans mon application Web ASP.NET MVC 2, je permet aux utilisateurs de créer des champs d'entrée personnalisés de différents types de données pour étendre notre formulaire d'entrée de base. Bien que délicat, la construction du formulaire d'entrée d'une collection de champs personnalisés est suffisamment avancé. P>
Cependant, je suis maintenant au point où je veux gérer la publication de cette forme et je ne suis pas certain de quoi le meilleur moyen de gérer cela serait. Normalement, nous utiliserions des modèles d'entrée fortement dactylographiés qui sont liés à partir des différentes entrées statiquement typées disponibles sur le formulaire. Cependant, je suis à perte de la manière de le faire avec un nombre variable de champs de saisie représentant différents types de données. P>
Un formulaire d'entrée représentatif pourrait ressembler à quelque chose comme: strong> p>
Les idées que j'ai pensées sont: strong> p>
Quelqu'un a-t-il abordé un problème comme ça avant? Si oui, comment l'avez-vous résolu? P>
My "Base" est traité sur une autre zone d'entrée ensemble, une solution n'a donc pas besoin de rendre compte de la magie de l'héritage pour cela. Je suis juste intéressé par la gestion des champs personnalisés sur cette interface, pas ma "base". P>
Merci à bras et à SmartCaveman; Vous avez tous deux fourni de bonnes directives pour la manière dont cela pourrait être fait. Je mettrai à jour cette question avec ma solution finale une fois sa mise en œuvre. P>
3 Réponses :
jeter un coup d'œil sur ce que j'ai fait ici: action MVC2 à gérer Multiples modèles et voir si peut vous obtenir sur la bonne voie.
Si vous utilisez un formulaire de formulaire comme l'un de vos paramètres de votre action, vous pouvez ensuite aller à travers cette collection de formulaires à la recherche de bits de données ici ou là-bas. Afin de lier ces valeurs à tout ce que vous enregistrez les données. Vous aurez probablement besoin de profiter des modèles de stratégie et de commandement pour que cela fonctionne. P>
Bonne chance, n'hésitez pas à poser des questions de suivi. P>
Modifier : P>
Votre méthode que le travail doit ressembler à quelque chose comme ceci: p>
Merci pour cette information, votre approche a l'air très intéressante. Je vais probablement avoir des suivis pour vous lundi.
BRAS; Je serais heureux de vous accorder la prime si vous êtes prêt à poster / partager des détails de mise en œuvre plus pertinents.
La partie la plus importante de ceci est iuiwrapper.canhandle (vous voudrez utiliser un SELECT plutôt que SIMOADEFAULT pour obtenir plusieurs wrappers). La méthode Canhandle prend une formeCollection et tente de saisir un élément de collection (var x = collection ["quelqueévalue"]; retour x! = Null;) qui déterminera si l'élément de collecte de formulaire existe. Une fois votre collection d'emballages, chaque wrapper aura une commande pour enregistrer cet élément particulier à votre référentiel, puis il vous suffit d'exécuter simplement la collection de commandes pour stocker les données sur votre référentiel. Encore une fois, n'hésitez pas à demander un suivi.
@Arm: Merci d'avoir mis à jour votre message; Je pense à mon scénario que je devrais compter sur plus d'une entrée de formulaire logique dans la collection par champ. Plus important encore, je devrais connaître l'identifiant et le type de données de mon champ personnalisé et basé sur le type de données, essayez de lancer la troisième entrée d'intérêt au type approprié.
Tant que vous savez quel sera le nom et le type de formulaire, vous pouvez créer un liant pour ce nom de formulaire. Sinon, vous pouvez créer quelques valeurs de formulaire cachées ("mynumberfield" avec "mynumberfield_id" et "mynumberfield_type"), puis utilisez ceux-ci pour faire la liaison. Cependant, ils entreraient tous comme des chaînes, et comment convertir la chaîne "INT" en classe int puis lier "mynumberfield" à cette classe est un problème que j'ai heureusement ne pas avoir à résoudre.
@Am: Oui, ma situation est quelque peu plus compliquée, mais je pense avoir correspondant à des champs cachés «métadonnées» correspondants qui révèlent le type et l'ID des entrées personnalisées sont un moyen décent de résoudre ce problème. J'attends que les autres pèsent ici, mais votre approche ressemble à un bon point de départ pour moi.
Il n'est probablement pas bon d'exécuter la sauvegarde du modèle. Il semble que c'est assez évidemment la responsabilité du contrôleur (et peut-être des conféroirs d'action). Toutefois, si la méthode d'action du contrôleur prend une commande en tant que paramètre de modèle, il est logique de créer le modèle de commande dans le classeur.
Je pense que l'une des options les meilleures est de créer un liant de modèle personnalisé, ce qui permet d'avoir une logique personnalisée dans les coulisses et toujours un code très personnalisable derrière. P>
Peut-être que ces articles peuvent vous aider: p>
http://www.gregshackles.com/2010/03/templed-helpers-and-custom-model-binders-in-asp-net-mvc-2/ p>
http://www.singingels.com/articles/model_binders_in_aspnet_mvc.aspx < / p>
Plus spécifiquement, je prendrais probablement comme l'argument du contrôleur une classe personnalisée avec toutes les propriétés "Base" incluses. La classe pourrait alors par exemple inclure un dictionnaire reliant le nom de chaque champ à un objet ou une interface que vous appliquez une fois pour chaque type de données, ce qui permet de traiter les données ultérieurement. P>
/ victor p>
Voici comment je commencerais à aborder la question. Un clinique de modèle personnalisé serait assez facile à construire en fonction de la propriété de formidable (qui pourrait être déterminé par l'index et / ou l'étiquette, selon).
public interface IForm : IFormComponent { Guid FormId { get; } void Add(IFormComponent component); } public interface IFormRepository { IForm GetForm(Guid id); } public class CustomFormModelBinder : IModelBinder { private readonly IFormRepository _repository; public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ValueProviderResult result; if(bindingContext.ValueProvider.TryGetValue("_customFormId", out result)) { var form = _repository.GetForm(new Guid(result.AttemptedValue)); var fields = form.GetChildren(); // loop through the fields and bind their values return form; } throw new Exception("Form ID not found."); } }
Merci pour les commentaires, très perspicace.