Estou curioso para saber se você pode sobrecarregar os métodos do controlador no asp.net MVC. Sempre que tento, recebo o erro abaixo. Os dois métodos aceitam argumentos diferentes. Isso é algo que não pode ser feito?
A solicitação atual de ação 'MyMethod' no tipo de controlador 'MyController' é ambígua entre os seguintes métodos de ação:
c#
asp.net-mvc
overloading
Papa Burgundy
fonte
fonte
Respostas:
Você pode usar o atributo se desejar que seu código sobrecarregue.
Mas, você precisará usar um nome de ação diferente para o mesmo método http (como outros já disseram). Portanto, é apenas semântica nesse ponto. Você prefere ter o nome no seu código ou atributo?
Phil tem um artigo relacionado a isso: http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx
fonte
return View();
. Por exemplo:return View("MyOverloadedName");
.Sim. Consegui fazer isso definindo o
HttpGet
/HttpPost
(ouAcceptVerbs
atributo equivalente ) para cada método do controlador como algo distinto, ou seja,HttpGet
ouHttpPost
, mas não ambos. Dessa forma, ele pode dizer com base no tipo de solicitação qual método usar.Uma sugestão que tenho é que, para um caso como esse, seria uma implementação privada na qual os dois métodos públicos de Ação dependem para evitar a duplicação de código.
fonte
Show()
métodos têm assinaturas diferentes. Se e quando você precisar enviar informações para a versão Get, suas versões Get e Post acabarão com a mesma assinatura e você precisará doActionName
atributo ou de uma das outras correções mencionadas nesta postagem.ActionNameAttribute
. Na prática, raramente achei esse o caso.Aqui está outra coisa que você poderia fazer ... você quer um método capaz de ter um parâmetro e não.
Por que não tentar isso ...
Isso funcionou para mim ... e neste método, você pode realmente testar para ver se possui o parâmetro recebido.
Atualizado para remover a sintaxe anulável inválida na sequência e usar um valor de parâmetro padrão.
fonte
string
Não pode ser anulável.)string
não pode sernullable
; mas pode sernull
! De qualquer maneira, postei o comentário inicial sem sinceridade.Não, Não e Não. Vá e tente o código do controlador abaixo, onde temos o "LoadCustomer" sobrecarregado.
Se você tentar invocar a ação "LoadCustomer", receberá um erro, conforme mostrado na figura abaixo.
Polimorfismo faz parte da programação C # enquanto HTTP é um protocolo. HTTP não entende polimorfismo. O HTTP funciona na URL ou no conceito e a URL pode ter apenas nomes exclusivos. Portanto, o HTTP não implementa polimorfismo.
Para corrigir o mesmo, precisamos usar o atributo "ActionName".
Portanto, agora, se você fizer uma chamada para o URL "Customer / LoadCustomer", a ação "LoadCustomer" será chamada e, com a estrutura de URL "Customer / LoadCustomerByName", o "LoadCustomer (string str)" será chamado.
A resposta acima que tirei deste artigo de codeproject -> MVC Action overloading
fonte
Para superar esse problema, você pode escrever um
ActionMethodSelectorAttribute
que analise oMethodInfo
para cada ação e o compare com os valores do formulário postados e, em seguida, rejeite qualquer método para o qual os valores do formulário não coincidam (excluindo o nome do botão, é claro).Aqui está um exemplo: - http://blog.abodit.com/2010/02/asp-net-mvc-ambiguous-match/
MAS, isso não é uma boa ideia.
fonte
Tanto quanto eu sei, você só pode ter o mesmo método ao usar diferentes métodos http.
ie
fonte
[HttpPost]
atributo em vez de[AcceptVerbs("POST")]
.Consegui isso com a ajuda do roteamento de atributos no MVC5. É certo que eu sou novo no MVC vindo de uma década de desenvolvimento web usando WebForms, mas o seguinte funcionou para mim. Diferentemente da resposta aceita, isso permite que todas as ações sobrecarregadas sejam renderizadas pelo mesmo arquivo de visualização.
Primeiro, ative o roteamento de atributos em App_Start / RouteConfig.cs.
Opcionalmente, decore sua classe de controlador com um prefixo de rota padrão.
Em seguida, decore as ações do seu controlador que se sobrecarregam com uma rota e parâmetros comuns adequados. Usando parâmetros de tipo restrito, você pode usar o mesmo formato de URI com IDs de tipos diferentes.
Espero que isso ajude e não leve alguém a seguir o caminho errado. :-)
fonte
Você pode usar um único
ActionResult
para lidar com ambosPost
eGet
:Útil se seus métodos
Get
ePost
tiverem assinaturas correspondentes.fonte
Acabei de me deparar com essa pergunta e, apesar de já estar antiga, ainda é muito relevante. Ironicamente, o único comentário correto neste tópico foi postado por um iniciante confesso no MVC quando ele escreveu o post. Mesmo os documentos do ASP.NET não estão totalmente corretos. Tenho um projeto grande e sobrecarrego com êxito os métodos de ação.
Se você entender o roteamento, além do padrão de rota padrão simples de {controller} / {action} / {id}, pode ser óbvio que as ações do controlador podem ser mapeadas usando qualquer padrão exclusivo. Alguém aqui falou sobre polimorfismo e disse: "HTTP não entende polimorfismo", mas o roteamento não tem nada a ver com HTTP. É, simplesmente, um mecanismo para correspondência de padrões de string.
A melhor maneira de fazer isso funcionar é usar os atributos de roteamento, por exemplo:
Essas ações cuidarão de URLs como
/cars/usa/new-york
e/cars/usa/texas/dallas
, que serão mapeados para a primeira e a segunda ações do Índice, respectivamente.Examinando este exemplo de controlador, é evidente que ele vai além do padrão de rota padrão mencionado acima. O padrão funciona bem se sua estrutura de URL corresponder exatamente às convenções de nomenclatura de código, mas esse nem sempre é o caso. O código deve ser descritivo do domínio, mas os URLs geralmente precisam ir além, porque seu conteúdo deve ser baseado em outros critérios, como requisitos de SEO.
O benefício do padrão de roteamento padrão é que ele cria automaticamente rotas exclusivas. Isso é imposto pelo compilador, já que os URLs corresponderão a tipos e membros exclusivos de controladores. A rolagem de seus próprios padrões de rota exigirá uma reflexão cuidadosa para garantir a exclusividade e o funcionamento.
Nota importante A única desvantagem é que o uso de roteamento para gerar URLs para ações sobrecarregadas não funciona quando baseado em um nome de ação, por exemplo, ao usar UrlHelper.Action. Mas funciona se alguém usa rotas nomeadas, por exemplo, UrlHelper.RouteUrl. E usar rotas nomeadas é, de acordo com fontes bem respeitadas, o caminho a seguir de qualquer maneira ( http://haacked.com/archive/2010/11/21/named-routes-to-the-rescue.aspx/ ).
Boa sorte!
fonte
Você pode usar [ActionName ("NewActionName")] para usar o mesmo método com um nome diferente:
fonte
Eu precisava de uma sobrecarga para:
Havia poucos argumentos suficientes onde acabei fazendo isso:
Não é uma solução perfeita, especialmente se você tiver muitos argumentos, mas funciona bem para mim.
fonte
Também enfrentei o mesmo problema no meu aplicativo. Sem modificar nenhuma informação de método, eu forneci [ActionName ("SomeMeaningfulName")]] no cabeçalho Action. Problema resolvido
fonte
Crie o método base como virtual
Crie o método substituído como substituição
Editar: Isso obviamente se aplica somente se o método de substituição estiver em uma classe derivada que parece não ter sido a intenção do OP.
fonte
Eu gosto desta resposta postada em outro tópico
Isso é usado principalmente se você herdar de outro controlador e desejar substituir uma conta do controlador base
Substituindo uma ação com parâmetros diferentes
fonte
Há apenas uma assinatura pública permitida para cada método do controlador. Se você tentar sobrecarregá-lo, ele será compilado, mas você está recebendo o erro em tempo de execução que ocorreu.
Se você não estiver disposto a usar verbos diferentes (como os atributos
[HttpGet]
e[HttpPost]
) para diferenciar métodos sobrecarregados (que funcionarão) ou alterar o roteamento, o que resta é que você pode fornecer outro método com um nome diferente ou pode despachar dentro do método existente. Aqui está como eu fiz isso:Uma vez, entrei em uma situação em que tinha que manter a compatibilidade com versões anteriores. O método original esperava dois parâmetros, mas o novo tinha apenas um. Sobrecarregar da maneira que eu esperava não funcionou porque o MVC não encontrou mais o ponto de entrada.
Para resolver isso, fiz o seguinte:
Criou um novo método público que continha "apenas" 2 parâmetros de string. Aquele atuou como despachante, ou seja:
Obviamente, isso é um hack e deve ser refatorado mais tarde. Mas, por enquanto, funcionou para mim.
Você também pode criar um expedidor como:
Você pode ver que UpdateAction precisa de 2 parâmetros, enquanto DeleteAction precisa apenas de um.
fonte
Desculpe o atraso. Eu estava com o mesmo problema e encontrei um link com boas respostas, poderia ajudar novos caras
Todos os créditos para o site BinaryIntellect e os autores
Basicamente, existem quatro situações: usando verbos diferentes , roteamento , marcação de sobrecarga com o atributo [NoAction] e altere o nome do atributo de ação com [ActionName]
Então, depende de seus requisitos e da sua situação.
No entanto, siga o link:
Link: http://www.binaryintellect.net/articles/8f9d9a8f-7abf-4df6-be8a-9895882ab562.aspx
fonte
Se for uma tentativa de usar uma ação GET para várias visualizações que POST a várias ações com modelos diferentes, tente adicionar uma ação GET para cada ação POST que redireciona para o primeiro GET para impedir 404 na atualização.
Plano geral, mas comum.
fonte