Passe o parâmetro para o controlador de @ Html.ActionLink MVC 4

109

Nesta linha:

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

Recebo o seguinte erro de tempo de execução em blogPostId:

O dicionário de parâmetros contém uma entrada nula para o parâmetro 'blogPostId' do tipo não anulável 'System.Int32' para o método 'System.Web.Mvc.ActionResult BlogReplyCommentAdd (Int32, Nop.Web.Models.Blogs.BlogPostModel, Boolean)' em 'Nop.Web.Controllers.BlogController'. Um parâmetro opcional deve ser um tipo de referência, um tipo anulável ou ser declarado como um parâmetro opcional. Nome do parâmetro: parâmetros

Já atribuí um valor para isso no topo, como

    @{         
        var blogPostId = Model.Id;          
     }

Meu controlador:

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

Estou fazendo algo errado? Por favor me dê um exemplo.

NetraSW
fonte

Respostas:

257

Você está usando uma sobrecarga incorreta do Html.ActionLinkauxiliar. O que você pensa routeValuesé realmente htmlAttributes! Basta olhar para o HTML gerado, você verá que a propriedade href dessa âncora não tem a aparência esperada.

Aqui está o que você está usando:

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

e aqui está o que você deve usar:

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

Além disso, há outro problema muito sério com seu código. O seguinte routeValue:

replyblogPostmodel = Model

Você não pode passar objetos complexos como este em um ActionLink. Portanto, livre-se dele e remova também o BlogPostModelparâmetro da ação do controlador. Você deve usar o blogPostIdparâmetro para recuperar o modelo de onde quer que este modelo seja persistido ou, se preferir, de onde quer que tenha recuperado o modelo na ação GET:

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

No que diz respeito ao seu problema inicial está relacionado com a sobrecarga errada, eu recomendo que você escreva seus ajudantes usando parâmetros nomeados:

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

Agora, além de seu código ser mais legível, você nunca mais terá confusão entre os zilhões de sobrecargas que a Microsoft criou para esses ajudantes.

Darin Dimitrov
fonte
Você precisa alterar os comentários controllerNameeactionName
webdeveloper
@DarinDimitrov: como passar o modelo como parâmetro?
NetraSW
1
@ DarinDimitrov, @ webdeveloper: Preciso mencionar [httppost] em actionresult?
NetraSW
@NetraSW, você não deve ter um [HttpPost]na ação porque o link está enviando uma solicitação GET. [HttpPost]significa que sua ação do controlador está acessível apenas com uma solicitação POST.
Darin Dimitrov
@DarinDimitrov: Como posso fazer isso acontecer? o modelo envia o valor da propriedade vazio. Por favor me guie.
NetraSW
12

Tenho que passar dois parâmetros como:

/ Controlador / Ação / Param1Value / Param2Value

Deste jeito:

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

irá gerar este url

/ Controlador / Ação / Param1Value? Param2Name = Param2Value

Usei um método alternativo mesclando o parâmetro dois no parâmetro um e obtive o que queria:

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

E eu consigo:

/ Controlador / Ação / Param1Value / Param2Value

MuniR
fonte
Aparentemente, isso acontece quando Param1Value é nulo. Acabo de encontrar o mesmo problema.
AFract
3

Você pode passar valores usando o abaixo.

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

Controlador:

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

E o URL parece

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

O problema deve ser com o valor Model.Id que é nulo. Você pode confirmar atribuindo um valor, por exemplo

@{         
     var blogPostId = 1;          
 }

Se o erro desaparecer, então você precisa se certificar de que o Id do modelo tem um valor antes de passá-lo para a visualização

ver
fonte
1
Não, esse não é o problema.
Darin Dimitrov