Übergeben Sie den Parameter von @ Html.ActionLink MVC 4 an den Controller

109

In dieser Zeile:

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

Ich erhalte den folgenden Laufzeitfehler auf blogPostId:

Das Parameterwörterbuch enthält einen Nulleintrag für den Parameter 'blogPostId' vom nicht nullbaren Typ 'System.Int32' für die Methode 'System.Web.Mvc.ActionResult BlogReplyCommentAdd (Int32, Nop.Web.Models.Blogs.BlogPostModel, Boolean)' in 'Nop.Web.Controllers.BlogController'. Ein optionaler Parameter muss ein Referenztyp oder ein nullbarer Typ sein oder als optionaler Parameter deklariert werden. Parametername: Parameter

Ich habe dafür bereits einen Wert vergeben, wie z

    @{         
        var blogPostId = Model.Id;          
     }

Mein Controller:

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

Mache ich etwas falsch? Bitte geben Sie mir ein Beispiel.

NetraSW
quelle

Antworten:

257

Sie verwenden eine falsche Überlastung des Html.ActionLinkHelfers. Was Sie denken, routeValuesist tatsächlich htmlAttributes! Schauen Sie sich einfach den generierten HTML-Code an. Sie werden feststellen, dass die href-Eigenschaft dieses Ankers nicht so aussieht, wie Sie es erwarten.

Folgendes verwenden Sie:

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

und hier ist, was Sie verwenden sollten:

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

Es gibt auch ein anderes sehr ernstes Problem mit Ihrem Code. Der folgende routeValue:

replyblogPostmodel = Model

Sie können solche komplexen Objekte unmöglich in einem ActionLink übergeben. Entfernen Sie es also und entfernen Sie den BlogPostModelParameter aus Ihrer Controller-Aktion. Sie sollten den blogPostIdParameter verwenden, um das Modell von jedem Ort abzurufen, an dem dieses Modell beibehalten wird, oder wenn Sie es vorziehen, von jedem Ort aus, an dem Sie das Modell in der GET-Aktion abgerufen haben:

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

In Bezug auf Ihr anfängliches Problem mit der falschen Überlastung würde ich Ihnen empfehlen, Ihre Helfer mit benannten Parametern zu schreiben:

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

Jetzt ist Ihr Code nicht nur besser lesbar, sondern Sie werden auch nie mehr Verwirrung über die Unmengen von Überladungen haben, die Microsoft für diese Helfer vorgenommen hat.

Darin Dimitrov
quelle
Sie müssen Kommentare ändern controllerNameundactionName
Webentwickler
@DarinDimitrov: Wie übergebe ich ein Modell als Parameter?
NetraSW
1
@ DarinDimitrov, @ webdeveloper: Muss ich [httppost] im Aktionsergebnis erwähnen?
NetraSW
@NetraSW, Sie sollten keine [HttpPost]in der Aktion haben, da der Link eine GET-Anfrage sendet. [HttpPost]bedeutet, dass auf Ihre Controller-Aktion nur mit einer POST-Anforderung zugegriffen werden kann.
Darin Dimitrov
@DarinDimitrov: Wie kann ich das geschehen lassen? Modell sendet Propeties Wert leer. Bitte führen Sie mich.
NetraSW
12

Ich muss zwei Parameter übergeben wie:

/ Controller / Action / Param1Value / Param2Value

Diesen Weg:

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

wird diese URL generieren

/ Controller / Action / Param1Value? Param2Name = Param2Value

Ich habe eine Problemumgehungsmethode verwendet, indem ich Parameter zwei in Parameter eins zusammengeführt habe, und ich bekomme, was ich wollte:

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

Und ich bekomme:

/ Controller / Action / Param1Value / Param2Value

MuniR
quelle
Anscheinend passiert dies, wenn Param1Value null ist. Ich bin gerade auf das gleiche Problem gestoßen.
Nach dem
3

Sie können Werte wie folgt übergeben.

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

Regler:

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

Und die URL sieht aus wie

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

Das Problem muss mit dem Wert Model.Id liegen, der null ist. Sie können dies bestätigen, indem Sie einen Wert zuweisen, z

@{         
     var blogPostId = 1;          
 }

Wenn der Fehler verschwindet, müssen Sie sicherstellen, dass Ihre Modell-ID einen Wert hat, bevor Sie ihn an die Ansicht übergeben

sawe
quelle
1
Nein, das ist nicht das Problem.
Darin Dimitrov