NetraSW
NetraSW

Reputation: 1395

Pass parameter to controller from @Html.ActionLink MVC 4

In this line:

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

I get the following runtime error on blogPostId:

The parameters dictionary contains a null entry for parameter 'blogPostId' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult BlogReplyCommentAdd(Int32, Nop.Web.Models.Blogs.BlogPostModel, Boolean)' in 'Nop.Web.Controllers.BlogController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters

I have already assign a value for this on top such as

    @{         
        var blogPostId = Model.Id;          
     }

My Controller:

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

Am I doing something wrong? Please give me an example.

Upvotes: 127

Views: 400776

Answers (4)

Vijay Vj
Vijay Vj

Reputation: 367

You can pass values by using the below .

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

Controller:

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

And the URL looks like

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

Upvotes: 7

MoniR
MoniR

Reputation: 1391

I have to pass two parameters like:

/Controller/Action/Param1Value/Param2Value

This way:

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

will generate this url

/Controller/Action/Param1Value?Param2Name=Param2Value

I used a workaround method by merging parameter two in parameter one and I get what I wanted:

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

And I get :

/Controller/Action/Param1Value/Param2Value

Upvotes: 13

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

You are using a wrong overload of the Html.ActionLink helper. What you think is routeValues is actually htmlAttributes! Just look at the generated HTML, you will see that this anchor's href property doesn't look as you expect it to look.

Here's what you are using:

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

and here's what you should use:

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

Also there's another very serious issue with your code. The following routeValue:

replyblogPostmodel = Model

You cannot possibly pass complex objects like this in an ActionLink. So get rid of it and also remove the BlogPostModel parameter from your controller action. You should use the blogPostId parameter to retrieve the model from wherever this model is persisted, or if you prefer from wherever you retrieved the model in the GET action:

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

As far as your initial problem is concerned with the wrong overload I would recommend you writing your helpers using named parameters:

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

Now not only that your code is more readable but you will never have confusion between the gazillions of overloads that Microsoft made for those helpers.

Upvotes: 300

sawe
sawe

Reputation: 1151

The problem must be with the value Model.Id which is null. You can confirm by assigning a value, e.g

@{         
     var blogPostId = 1;          
 }

If the error disappers, then u need to make sure that your model Id has a value before passing it to the view

Upvotes: 0

Related Questions