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 = "" } );
kaivalya
fonte

Respostas:

409

O que você quer é essa sobrecarga:

//linkText, actionName, controllerName, routeValues, htmlAttributes
<%=Html.ActionLink("Details", "Details", 
    "Product", new {id = item.ID}, null) %>
Çağdaş Tekin
fonte
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!

Stephan Venter
fonte
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
)
Psi-Ed
fonte
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

James Avery
fonte
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 })) %>
Craig Stuntz
fonte
6

tente isso está funcionando bem

  <%:Html.ActionLink("Details","Details","Product",  new {id=item.dateID },null)%>
barasker de areia
fonte
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>
George Chondrompilas
fonte
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)
Outro
fonte
0

esse código funcionou para mim em vista parcial:

<a href="/Content/[email protected]">@item.Title</a>
Amin Saadati
fonte
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