Usando Html.ActionLink para chamar ação em um controlador diferente


224

Estou tentando navegar entre os controladores usando ActionLink. Vou contar o meu problema com um exemplo.

Estou na exibição de índice do controlador Hat e estou tentando usar o código abaixo para criar um link para a ação Detalhes do controlador do produto.

<%= Html.ActionLink("Details", "Details", "Product", new { id=item.ID }) %>

Em vez de criar um link para Detalhes no controlador do Produto, isso gera um link para a ação Detalhes em Hat controller e anexa um parâmetro Length ao final dele:

Hat/Details/9?Length=7

Não consigo usar HTML.ActionLinkpara alternar entre controladores devido a esse problema. Agradeço se você puder me indicar o que estou fazendo de errado. obrigado

PS: estou usando a configuração de rota padrão que acompanha o MVC

routes.MapRoute("Default", "{controller}/{action}/{id}", 
                     new { controller = "Home", action = "Index", id = "" } );

Respostas:


409

O que você quer é essa sobrecarga:

//linkText, actionName, controllerName, routeValues, htmlAttributes
<%=Html.ActionLink("Details", "Details", 
    "Product", new {id = item.ID}, null) %>

1
Você pode explicar por que essa sobrecarga específica funciona e o korki's não? Como a configuração de htmlAttributes como nulo afeta o roteamento do link?
Derek Hunziker

35
É porque se você usar os outros parâmetros, ele pressupõe que o terceiro argumento seja o valor da rota e o quarto argumento seja o atributo htmlat. A adição de um quinto argumento força o método a usar a sobrecarga correta. Percorra as sobrecargas no intellisense e isso fará mais sentido.
Banford

2
A sobrecarga do ActionLink é realmente desajeitada. O objetivo de aceitar um 'objeto routeValues' em vez de um RouteValueCollection é reduzir a quantidade de digitação. No entanto, você precisará digitar um valor nulo extra. Não-intuitivo e contra produtivo ...
TiMoch

3
Eu concordo, os parâmetros de sobrecarga são mal projetados .. Eu pensei que era um bug por mais tempo. Eu realmente tive que olhar a 9ª hora em tudo o intellisense para entender que eu estava usando a assinatura errada
Bkwdesign

1
Para futuros leitores, se você acertar esse problema e tentar adicionar um estilo css, essa é a sobrecarga correta. @ Html.ActionLink ("MyText", "MyAction", "MyController", null, new {@class = "myClass"})
granadaCoder

17

Com esses parâmetros, você está acionando a função / método sobrecarregado errado.

O que funcionou para mim:

<%= Html.ActionLink("Details", "Details", "Product", new { id=item.ID }, null) %>

Ele dispara HtmlHelper.ActionLink (string linkText, string actionName, string controllerName, objeto routeValues, objeto htmlAttributes)

Estou usando o MVC 4.

Cheerio!


2
Sua linha de código não aciona a sobrecarga mencionada, mas HtmlHelper.ActionLink (string linkText, string actionName, objeto routeValues, objeto htmlAttributes). Isso gera o mesmo resultado que o OP estava tentando evitar. Você precisa adicionar um parâmetro nulo adicional.
TiMoch

Obrigado TiMoch, perdeu esse?
Stephan Venter

12

Eu recomendaria escrever esses auxiliares usando parâmetros nomeados para maior clareza da seguinte maneira:

@Html.ActionLink(
    linkText: "Details",
    actionName: "Details",
    controllerName: "Product",
    routeValues: new {
        id = item.ID
    },
    htmlAttributes: null
)

A partir de 2019, esse recurso será implementado no ReSharper by JetBrains. Na verdade, é muito útil para essa circunstância.
28719 Jamie

10

Se você pegar o assembly MVC Futures (que eu recomendo), poderá usar um genérico ao criar o ActionLink e um lambda para construir a rota:

<%=Html.ActionLink<Product>(c => c.Action( o.Value ), "Details" ) %>

Você pode obter a montagem de futuros aqui: http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471


Obrigado pelo link real - estava tentando encontrá-lo!
0000 Perhentian

1
Cuidado com isso, pois ele não foi incluído no MVC2. O raciocínio é que as ações não são necessariamente métodos (com as quais concordo, mas será difícil migrar, já que estamos usando o método genérico há algum tempo). Aqui está o artigo completo sobre por que não foi mantido em 2: haacked.com/archive/2008/08/29/…
Stu

7

Você está acertando errado a sobrecarga do ActionLink. Tente isso em vez disso.

<%= Html.ActionLink("Details", "Details", "Product", new RouteValueDictionary(new { id=item.ID })) %>

6

tente isso está funcionando bem

  <%:Html.ActionLink("Details","Details","Product",  new {id=item.dateID },null)%>

3

Uma solução alternativa seria usar o Urlobjeto auxiliar para definir o hrefatributo de uma <a>tag como:

<a href="@Url.Action("Details", "Product",new { id=item.ID }) )">Details</a>

1

Observe que detalhes é uma página "Exibir" na pasta "Produtos".

ProductId é a chave primária da tabela. Aqui está a linha do Index.cshtml

 @Html.ActionLink("Details", "Details","Products" , new  {  id=item.ProductId  },null)

0

esse código funcionou para mim em vista parcial:

<a href="/Content/Index?SubCategoryId=@item.Id">@item.Title</a>

Enquanto isso funciona, ele contorna todo o ponto de usar o ActionLink ... o ponto principal do ActionLink é evitar digitar manualmente a URL e os possíveis problemas que podem ser criados #
Jon Story
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.