Pase el parámetro al controlador desde @ Html.ActionLink MVC 4

109

En esta línea:

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

Recibo el siguiente error de tiempo de ejecución en blogPostId:

El diccionario de parámetros contiene una entrada nula para el parámetro 'blogPostId' de tipo no anulable 'System.Int32' para el método 'System.Web.Mvc.ActionResult BlogReplyCommentAdd (Int32, Nop.Web.Models.Blogs.BlogPostModel, Boolean)' en 'Nop.Web.Controllers.BlogController'. Un parámetro opcional debe ser un tipo de referencia, un tipo que acepte valores NULL o declararse como un parámetro opcional. Nombre del parámetro: parámetros

Ya he asignado un valor para esto en la parte superior, como

    @{         
        var blogPostId = Model.Id;          
     }

Mi controlador:

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

¿Estoy haciendo algo mal? Por favor, dame un ejemplo.

NetraSW
fuente

Respuestas:

257

Está utilizando una sobrecarga incorrecta del Html.ActionLinkayudante. ¡Lo que crees que routeValueses en realidad htmlAttributes! Solo mire el HTML generado, verá que la propiedad href de este ancla no tiene el aspecto que espera.

Esto es lo que está usando:

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

y esto es lo que debe usar:

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

También hay otro problema muy serio con su código. El siguiente routeValue:

replyblogPostmodel = Model

No es posible pasar objetos complejos como este en un ActionLink. Así que deshágase de él y también elimine el BlogPostModelparámetro de la acción de su controlador. Debe usar el blogPostIdparámetro para recuperar el modelo desde donde persiste este modelo, o si lo prefiere desde donde recuperó el modelo en la acción GET:

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

En lo que respecta a su problema inicial con la sobrecarga incorrecta, le recomendaría que escriba sus ayudantes utilizando parámetros con nombre:

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

Ahora, no solo su código es más legible, sino que nunca tendrá confusión entre los miles de millones de sobrecargas que Microsoft hizo para esos ayudantes.

Darin Dimitrov
fuente
Necesita cambiar los comentarios controllerNameyactionName
webdeveloper
@DarinDimitrov: ¿cómo pasar el modelo como parámetro?
NetraSW
1
@ DarinDimitrov, @ webdeveloper: ¿Tengo que mencionar [httppost] en actionresult?
NetraSW
@NetraSW, no debería tener un [HttpPost]en la acción porque el enlace envía una solicitud GET. [HttpPost]significa que la acción de su controlador es accesible solo con una solicitud POST.
Darin Dimitrov
@DarinDimitrov: ¿Cómo puedo hacer que esto suceda? el modelo envía el valor de las propiedades vacío. Por favor guíame.
NetraSW
12

Tengo que pasar dos parámetros como:

/ Controlador / Acción / Param1Value / Param2Value

De esta manera:

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

generará esta URL

/ Controlador / Acción / Param1Value? Param2Name = Param2Value

Usé un método de solución al fusionar el parámetro dos en el parámetro uno y obtengo lo que quería:

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

Y obtengo:

/ Controlador / Acción / Param1Value / Param2Value

MuniR
fuente
Aparentemente, esto sucede cuando Param1Value es nulo. Acabo de encontrar el mismo problema.
AFract
3

Puede pasar valores utilizando lo siguiente.

@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();
        }

Y la URL parece

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

El problema debe estar en el valor Model.Id que es nulo. Puede confirmar asignando un valor, p. Ej.

@{         
     var blogPostId = 1;          
 }

Si el error desaparece, debe asegurarse de que la identificación de su modelo tenga un valor antes de pasarlo a la vista

sawe
fuente
1
No, ese no es el problema.
Darin Dimitrov