2017-10-10 3 views
1

Je n'arrive pas à comprendre comment passer un tableau de GUID en tant que paramètre à un contrôleur ASP.NET MVC via POST. Qu'est-ce que je rate? Existe-t-il un moyen plus simple de faire cela?Liaison de paramètre ASP.NET MVC: comment POST une liste ou un tableau vers une méthode de contrôleur?

Dans mon AngularJS balisage:

<form method="post" action="/Foo/Bar" > 
    <input name="itemIds" type="hidden" value="{{ ctrl.itemIds }}"> 
    <button type="submit">Submit</button> 
</form> 

Quels sont les résultats en HTML:

<form method="post" action="/Foo/Bar" > 
    <input name="itemIds" type="hidden" value="[&quot;8cd52539-c371-402a-b8be-12775f03ab68&quot;,&quot;8c97f9e0-666c-41ba-a914-72815745d1f0&quot;]"> 
    <button type="submit">Submit</button> 
</form> 

Dans mon FooController:

[System.Web.Mvc.HttpPost] 
public ActionResult Bar([FromBody]Guid[] itemIds) => ... 

Quand je déboguer ci-dessus, mon HTTP POST semble être correct mais je reçois null itemIds en Bar. Pouvez-vous m'aider à changer cela pour travailler? Existe-t-il un meilleur moyen de remplir mon corps de requête, étant donné que j'ai déjà un tableau de GUID dans mon modèle JS?

+0

Je crois que le 'Guid' se présenterait comme une' chaîne', alors vous lanceriez un 'Guid'. Pour une raison étrange, il ne lance généralement pas le type en toute sécurité lorsque vous utilisez les paramètres MVC par défaut comme vous avez ci-dessus. – Greg

+0

Cela me rend triste. Changer le paramètre en une chaîne à la place de Guid [] donne une chaîne unique avec des barres obliques inverses, des crochets et des virgules, ce qui est encore pire. Des idées d'une manière plus élégante - au moins une où je peux obtenir un tableau de chaînes ou une liste plutôt qu'une seule chaîne? –

+0

Vous pouvez créer un objet Json de base, puis le transmettre. Avec un seul désérialiser, pour éviter une partie de l'encodage fou.'{Id = ''}' type d'objet, un objet de base avec une propriété Id. Évidemment valide Json aiderait. – Greg

Répondre

2

Voici ce qui se passe réellement:

itemIds qui est affiché comme une seule chaîne au contrôleur. Pourquoi? Car itemIds n'est pas interprété comme un tableau. Si vous voulez un tableau, vous devez avoir plusieurs valeurs cachées nommées itemIds[0], itemsIds[1] et ainsi de suite. Voici un test rapide pour prouver que ce que je dis est réellement ce qui se passe:

Créer un formulaire comme celui-ci. Voir nous créons une valeur cachée nommée itemIdsOld et 2 valeurs cachées nommées itemIds[0] et itemIds[1]:

<form method="post" action="/Foo/Bar"> 
    <input name="itemIdsOld" type="hidden" value="[&quot;f8b21933-419c-4bdd-b5b6-75295ff65612&quot;,&quot;67bb1d75-ae78-49e4-bc29-ee82a51bb9a1&quot;]"> 
    <input name="itemIds[0]" type="hidden" value="f8b21933-419c-4bdd-b5b6-75295ff65612"> 
    <input name="itemIds[1]" type="hidden" value="67bb1d75-ae78-49e4-bc29-ee82a51bb9a1"> 
    <button type="submit">Submit</button> 
</form> 

Créer un contrôleur comme ceci:

[System.Web.Mvc.HttpPost] 
public ActionResult Index(string[] itemIdsOld, Guid[] itemIds) 
{ 
    return null; 
} 

Lorsque vous publiez le formulaire ci-dessus, vous remarquerez que une seule chaîne est créée en itemIdsOld et elle aura les deux guids comme string. Cependant, le second, puisque nous avons créé des contrôles nommés itemIds[0] et itemIds[1] sera converti en Guid[] itemIds comme prévu.

Je ne sais pas comment faire cela dans angulaire, mais avec C# et rasoir, une façon de le faire serait comme ceci:

@using System.Collections.Generic 
@{ 
    var guids = new List<Guid> { Guid.NewGuid(), Guid.NewGuid() }; 
} 
<form method="post" action="/Test/Index"> 
    <input name="itemIdsOld" type="hidden" value="[&quot;f8b21933-419c-4bdd-b5b6-75295ff65612&quot;,&quot;67bb1d75-ae78-49e4-bc29-ee82a51bb9a1&quot;]"> 
    @{ 
     for (int i = 0; i < guids.Count; i++) 
     { 
      <input name="itemIds[@i]" type="hidden" value="@guids[i]"> 
     } 
    } 
    <button type="submit">Submit</button> 
</form> 

Je codé en dur les GUIDs mais vous pouvez obtenir ce à partir d'un modèle ... vous obtenez le point.


Vous pouvez également utiliser Javascript pour intercepter la soumission du formulaire et de récupérer la valeur de itemIds et la transformer en un tableau et que soumettre au contrôleur, qui fonctionnerait aussi.

+0

Oui. Je peux utiliser un ng-repeat pour faire ça avec Angular, merci - c'est peut-être le meilleur moyen. Existe-t-il un moyen de créer un POST et de simplement fournir le corps JSON au lieu d'utiliser des champs de formulaire cachés? –

+0

Je ne suis pas sûr d'avoir ce que vous voulez dire par corps JSON au lieu de passer par des champs de formulaire cachés. – CodingYoshi

+0

Il semble être une machine Rube Goldberg pour configurer des champs de formulaire cachés via AngularJS afin que je puisse POST quand j'ai toutes les données dont j'ai besoin dans mon état de code Javascript pour faire le POST. Si c'était AJAX, je créerais simplement la requête AJAX et je ferais, mais je pense qu'il n'y a aucun moyen de créer une requête POST non-AJAX à partir du code Javascript. –