Passer le paramètre au contrôleur depuis @ Html.ActionLink MVC 4

110

Dans cette ligne:

@Html.ActionLink("Reply", "BlogReplyCommentAdd", "Blog",
         new { blogPostId = blogPostId, replyblogPostmodel = Model,
         captchaValid = Model.AddNewComment.DisplayCaptcha })

J'obtiens l'erreur d'exécution suivante sur blogPostId:

Le dictionnaire de paramètres contient une entrée nulle pour le paramètre 'blogPostId' de type non nullable 'System.Int32' pour la méthode 'System.Web.Mvc.ActionResult BlogReplyCommentAdd (Int32, Nop.Web.Models.Blogs.BlogPostModel, Boolean)' dans «Nop.Web.Controllers.BlogController». Un paramètre facultatif doit être un type référence, un type Nullable ou être déclaré en tant que paramètre facultatif. Nom du paramètre: paramètres

J'ai déjà attribué une valeur pour cela en plus, telle que

    @{         
        var blogPostId = Model.Id;          
     }

Mon contrôleur:

 public ActionResult BlogReplyCommentAdd(int blogPostId, BlogPostModel model, bool captchaValid)
    {}

Est-ce que je fais quelque chose de mal? Veuillez me donner un exemple.

NetraSW
la source

Réponses:

258

Vous utilisez une mauvaise surcharge de l' Html.ActionLinkassistant. Ce que vous pensez routeValuesest en fait htmlAttributes! Regardez simplement le HTML généré, vous verrez que la propriété href de cette ancre ne ressemble pas à ce que vous attendez.

Voici ce que vous utilisez:

@Html.ActionLink(
    "Reply",                                                  // linkText
    "BlogReplyCommentAdd",                                    // actionName
    "Blog",                                                   // routeValues
    new {                                                     // htmlAttributes
        blogPostId = blogPostId, 
        replyblogPostmodel = Model, 
        captchaValid = Model.AddNewComment.DisplayCaptcha 
    }
)

et voici ce que vous devez utiliser:

@Html.ActionLink(
    "Reply",                                                  // linkText
    "BlogReplyCommentAdd",                                    // actionName
    "Blog",                                                   // controllerName
    new {                                                     // routeValues
        blogPostId = blogPostId, 
        replyblogPostmodel = Model, 
        captchaValid = Model.AddNewComment.DisplayCaptcha 
    },
    null                                                      // htmlAttributes
)

Il y a aussi un autre problème très sérieux avec votre code. RouteValue suivante:

replyblogPostmodel = Model

Vous ne pouvez pas transmettre des objets complexes comme celui-ci dans un ActionLink. Alors débarrassez-vous-en et supprimez également le BlogPostModelparamètre de l'action de votre contrôleur. Vous devez utiliser le blogPostIdparamètre pour récupérer le modèle à partir de l’endroit où ce modèle est conservé, ou si vous préférez l’endroit où vous avez récupéré le modèle dans l’action GET:

public ActionResult BlogReplyCommentAdd(int blogPostId, bool captchaValid)
{
    BlogPostModel model = repository.Get(blogPostId);
    ...
}

En ce qui concerne votre problème initial avec une mauvaise surcharge, je vous recommande d'écrire vos helpers en utilisant des paramètres nommés:

@Html.ActionLink(
    linkText: "Reply",
    actionName: "BlogReplyCommentAdd",
    controllerName: "Blog",
    routeValues: new {
        blogPostId = blogPostId, 
        captchaValid = Model.AddNewComment.DisplayCaptcha
    },
    htmlAttributes: null
)

Maintenant, non seulement votre code est plus lisible, mais vous n'aurez jamais de confusion entre les milliards de surcharges que Microsoft a faites pour ces assistants.

Darin Dimitrov
la source
Vous devez changer les commentaires controllerNameetactionName
webdeveloper
@DarinDimitrov: comment passer le modèle en paramètre?
NetraSW
1
@ DarinDimitrov, @ webdeveloper: Dois-je mentionner [httppost] sur actionresult?
NetraSW
@NetraSW, vous ne devriez pas avoir de [HttpPost]dans l'action car le lien envoie une requête GET. [HttpPost]signifie que l'action de votre contrôleur n'est accessible qu'avec une requête POST.
Darin Dimitrov le
@DarinDimitrov: Comment puis-je faire en sorte que cela se produise? le modèle envoie la valeur des propriétés vide. Guidez-moi s'il-vous-plaît.
NetraSW
12

Je dois passer deux paramètres comme:

/ Contrôleur / Action / Param1Value / Param2Value

Par ici:

@Html.ActionLink(
    linkText,
    actionName,
    controllerName,
    routeValues: new {
        Param1Name= Param1Value, 
        Param2Name = Param2Value 
    },
    htmlAttributes: null
)

va générer cette URL

/ Controller / Action / Param1Value? Param2Name = Param2Value

J'ai utilisé une méthode de contournement en fusionnant le paramètre deux dans le paramètre un et j'obtiens ce que je voulais:

@Html.ActionLink(
    linkText,
    actionName,
    controllerName,
    routeValues: new {
        Param1Name= "Param1Value / Param2Value" ,      
    },
    htmlAttributes: null
)

Et j'obtiens:

/ Contrôleur / Action / Param1Value / Param2Value

MuniR
la source
Apparemment, cela se produit lorsque Param1Value est nul. Je viens de rencontrer le même problème.
AFract le
3

Vous pouvez transmettre des valeurs en utilisant ce qui suit.

@Html.ActionLink("About", "About", "Home",new { name = ViewBag.Name }, htmlAttributes:null )

Manette:

public ActionResult About(string name)
        {
            ViewBag.Message = "Your application description page.";
            ViewBag.NameTransfer = name;
            return View();
        }

Et l'URL ressemble à

http://localhost:50297/Home/About?name=My%20Name%20is%20Vijay
Vijay Vj
la source
0

Le problème doit être lié à la valeur Model.Id qui est nulle. Vous pouvez confirmer en attribuant une valeur, par ex.

@{         
     var blogPostId = 1;          
 }

Si l'erreur disparaît, vous devez vous assurer que votre identifiant de modèle a une valeur avant de le transmettre à la vue

sawe
la source
1
Non, ce n'est pas le problème.
Darin Dimitrov le