web-dev-qa-db-fra.com

stocker un tableau de chaînes dans un HiddenField asp.net

J'ai besoin de stocker un tableau de chaîne dans un champ masqué dans mon formulaire Web avec asp.net. Quelqu'un peut-il s'il vous plaît me dire comment je peux y parvenir? Merci

11
user1438482

Quelques méthodes fonctionneraient probablement.

1) Sérialiser la chaîne [] en JSON

Cela serait assez facile dans .NET en utilisant la classe JavaScriptSerializer et éviterait les problèmes liés aux caractères de délimitation. Quelque chose comme:

String[] myValues = new String[] { "Red", "Blue", "Green" };
string json = new JavaScriptSerializer().Serialize(myValues);

2) Trouver un délimiteur qui n'apparaît jamais dans les chaînes

Délimitez chaque chaîne avec un caractère tel que ||| qui n'apparaîtra jamais dans la chaîne. Vous pouvez utiliser String.Join() pour construire cette chaîne. Quelque chose comme:

String[] myValues = new String[] { "Red", "Blue", "Green" };
string str = String.Join("|||", myValues);

Et puis reconstruisez le comme:

myValues = str.Split(new string[] { "|||" }, StringSplitOptions.RemoveEmptyEntries);

Cela pourrait être la meilleure option si vous pouvez faire confiance à votre contribution, telle qu'une série de nombres de choix prédéfinis. Sinon, vous voudrez probablement vérifier vos chaînes d'entrée pour vous assurer qu'elles ne contiennent pas ce délimiteur si vous voulez être très sûr. Vous pouvez éventuellement utiliser HttpUtility.HtmlEncode() pour échapper en premier à chaque chaîne.

13
Mike Christensen

Pour stocker le tableau

string[] myarray = new string[] {"1","2"};

myHiddenField.Value = String.Join(",", myarray);

Pour obtenir le tableau

string[] myarray = myHiddenField.Value.Split(',');
6
codingbiz

Voulez-vous réellement le stocker dans un seul champ?

Si vous mettez chaque valeur dans son propre champ caché et donnez à tous les champs cachés le nom de votre propriété, la liaison de modèle traitera cela comme un tableau.

foreach (var option in Model.LookOptions)
{
    @Html.Hidden(Html.NameFor(model => model.LookOptions).ToString(), option)
}
5
David

Réponses existantes

Je préfère toujours utiliser la propriété par défaut et le classeur de modèle que d'avoir à emballer un tableau dans un fichier CSV et à s'inquiéter de le scinder et de le joindre à chaque aller-retour chez le client (comme dans les réponses de @Mike Christensen et @codingbiz ). C'est exactement ce que le modèle de classeur est là.

La réponse de @ David nous oriente dans la bonne direction, mais je préférerais ne pas intégrer ce type de logique à votre vue et le reléguer à un EditorTemplate à la place. 

Solution préférée

Vous pouvez donc ajouter la vue suivante ~/Views/Shared/EditorTemplates/HiddenArray.cshtml

@model Array

@foreach (var value in Model)
{
    <input type="hidden" value="@value"
           name="@Html.NameFor(model => model)"
           id="@(Html.IdFor(model => model))_@value" />
}

Puis appelez comme ceci depuis votre modèle:

@Html.EditorFor(model => model.FavoriteAnimals, "HiddenArray")

Stratégies alternatives

Voici comment je suis arrivé à spécifier manuellement le nom et la variable id pour chaque entrée masquée:

 Hidden For Array

  • A) Impossible d'utiliser HiddenFor() à l'intérieur d'une boucle, car elle pense que le nom de la propriété inclut désormais la valeur 
  • B) Lorsque nous appelons EditorFor, le modèle actuel est ajouté au préfixe de route. Ainsi, si nous transmettons le nom du modèle actuel sous forme de chaîne à Hidden() , nous doublons et le nom de la propriété. ne sera pas capable de se lier sur le chemin du retour. 
  • C) Cela semble étrange, mais nous pouvons simplement passer une chaîne vide comme nom et compter sur le préfixe de route pour faire son travail, mais comme nous sommes dans une boucle, l'identifiant produit n'est pas ' t valide HTML 
  • D) En récupérant le nom et l'ID du modèle et en incrémentant l'ID factice, nous pouvons continuer à générer du code HTML valide, même si cela n'affectera probablement que des indicateurs et des vérifications HTML.

Lectures complémentaires:

0
KyleMit