Przekaż parametr do kontrolera z @ Html.ActionLink MVC 4

110

W tej linii:

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

W blogPostId pojawia się następujący błąd w czasie wykonywania:

Słownik parametrów zawiera wpis o wartości null dla parametru „blogPostId” typu „System.Int32” nie dopuszczającego wartości null dla metody „System.Web.Mvc.ActionResult BlogReplyCommentAdd (Int32, Nop.Web.Models.Blogs.BlogPostModel, Boolean)” w „Nop.Web.Controllers.BlogController”. Opcjonalny parametr musi być typem referencyjnym, typem dopuszczającym wartość null lub być zadeklarowany jako parametr opcjonalny. Nazwa parametru: parametry

Już przypisałem wartość temu na górze, taką jak

    @{         
        var blogPostId = Model.Id;          
     }

Mój kontroler:

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

czy robię coś źle? Podaj mi przykład.

NetraSW
źródło

Odpowiedzi:

258

Używasz niewłaściwego przeciążenia Html.ActionLinkpomocnika. To, co myślisz, routeValuesjest w rzeczywistości htmlAttributes! Wystarczy spojrzeć na wygenerowany kod HTML, a zobaczysz, że właściwość href tej kotwicy nie wygląda tak, jak powinna.

Oto czego używasz:

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

a oto czego powinieneś użyć:

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

Jest też inny bardzo poważny problem z Twoim kodem. Następująca trasa Wartość:

replyblogPostmodel = Model

Nie możesz przekazać tak złożonych obiektów w ActionLink. Pozbądź się go, a także usuń BlogPostModelparametr z akcji kontrolera. Należy użyć blogPostIdparametru, aby pobrać model z dowolnego miejsca, w którym ten model jest utrwalony, lub jeśli wolisz z dowolnego miejsca, w którym pobrałeś model w akcji GET:

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

Jeśli chodzi o twój początkowy problem związany z niewłaściwym przeciążeniem, radziłbym napisać pomocników przy użyciu nazwanych parametrów:

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

Teraz nie tylko twój kod jest bardziej czytelny, ale nigdy nie będziesz mieć pomyłki między miliardami przeciążeń, które Microsoft stworzył dla tych pomocników.

Darin Dimitrov
źródło
Musisz zmienić komentarze controllerNameiactionName
webdeveloper
@DarinDimitrov: jak przekazać model jako parametr?
NetraSW
1
@ DarinDimitrov, @ webdeveloper: Czy muszę wspominać o [httppost] w wynikach akcji?
NetraSW
@NetraSW, nie powinno być [HttpPost]w akcji, ponieważ łącze wysyła żądanie GET. [HttpPost]oznacza, że ​​akcja kontrolera jest dostępna tylko za pomocą żądania POST.
Darin Dimitrov
@DarinDimitrov: JAK mogę to zrobić? model wysyła wartość właściwości pustą. Proszę, prowadź mnie.
NetraSW
12

Muszę podać dwa parametry takie jak:

/ Kontroler / Akcja / Param1Value / Param2Value

Tą drogą:

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

wygeneruje ten adres URL

/ Controller / Action / Param1Value? Param2Name = Param2Value

Użyłem metody obejścia, łącząc parametr drugi z parametrem pierwszym i otrzymałem to, co chciałem:

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

I otrzymuję:

/ Kontroler / Akcja / Param1Value / Param2Value

MuniR
źródło
Najwyraźniej dzieje się tak, gdy Param1Value ma wartość null. Właśnie napotkałem ten sam problem.
AFract
3

Możesz przekazać wartości, korzystając z poniższych.

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

Kontroler:

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

A URL wygląda jak

http://localhost:50297/Home/About?name=My%20Name%20is%20Vijay
Vijay Vj
źródło
0

Problem musi dotyczyć wartości Model.Id, która ma wartość null. Możesz potwierdzić, nadając wartość, np

@{         
     var blogPostId = 1;          
 }

Jeśli błąd zniknie, przed przekazaniem go do widoku należy upewnić się, że identyfikator modelu ma wartość

pił
źródło
1
Nie, to nie jest problem.
Darin Dimitrov