Signalr: Parâmetros Opcionais

Criado em 19 abr. 2012  ·  19Comentários  ·  Fonte: SignalR/SignalR

Um problema menor que encontrei hoje. O cliente não consegue fazer uma chamada para um método do servidor (erro: o valor não pode ser nulo), se o método do servidor aceitar parâmetros opcionais e a chamada do cliente excluir o parâmetro opcional:

Servidor:

public void GetAll(long Id, bool DoSomething=false)

Cliente:

myHub.GetAll(12);
Bug

Comentários muito úteis

Não acho que os parâmetros opcionais estejam funcionando conforme o esperado. Temos uma chamada sem parâmetros, à qual estou procurando adicionar um parâmetro.

Infelizmente, não há como fazer isso sem quebrar a compatibilidade com versões anteriores, porque nosso código de cliente atualmente chama sem argumentos, eu obtenho System.IO.InvalidDataException: Invocation fornece 0 argumento (s), mas o destino espera 1 - mesmo com um único _parâmetro opcional anulável_.

Se eu tiver que mudar meu cliente para passar um nulo, então não posso manter a compatibilidade com versões anteriores e também posso não usar o parâmetro opcional 😦

Solução alternativa: adicione e chame um novo método com um nome diferente, que encaminha de volta ao original se nenhum parâmetro for passado. Decepcionante 👎

Todos 19 comentários

Podemos tornar a resolução de métodos mais inteligente.

Definitivamente, uma boa ideia. Comecei realmente a trabalhar nisso, mas reverti para empurrar a implementação de hubs dinâmicos básicos o mais rápido possível naquele momento.

Por falar em método de resolução ...
Com a implementação atual, também podemos adicionar suporte a sobrecargas de método. A resolução de parâmetros nomeados também seria possível adicionar, mas isso implicaria em algumas modificações em como os parâmetros são realmente passados ​​entre o cliente e o servidor (passando pares de valores-chave em vez de apenas valores). O que você achou?

Isso também se aplica a um parâmetro anulável? Eu tenho um método com 3 parâmetros, o último dos quais é um int anulável (int?). Se eu definir o último parâmetro como nulo, obtenho a exceção:

Valor não pode ser nulo.
Nome do parâmetro: o

em Newtonsoft.Json.Utilities.ValidationUtils.ArgumentNotNull (Valor do objeto, String parameterName)
em Newtonsoft.Json.Linq.JToken.FromObjectInternal (Object o, JsonSerializer jsonSerializer)
em Newtonsoft.Json.Linq.JToken.FromObject (Object o, JsonSerializer jsonSerializer)
em Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke T
em GeoTag.App.Core.Services.SignalRClientService.d__9.MoveNext ()

Observe que não defini um valor padrão para ele no servidor

Vamos mover isso para o novo repo como um candidato v3

@JasonBSteele - Sei que já faz um tempo, mas o problema que você está mencionando acabou de ser corrigido. Espere vê-lo no próximo lançamento.

Estou confuso quanto ao status deste problema. Foi corrigido em alguma versão do SignalR?

@paulirwin Não

...

A correção está em 2.2.1 que foi lançado em julho (https://github.com/SignalR/SignalR/releases/tag/2.2.1)

Testei novamente o que encontrei ontem, aqui estão minhas descobertas:
Método de hub que o cliente chamará

public async Task EpicMethod( int? daysTillNETStandard20 ) {}

Tentativas de invocação do método do servidor cliente .NET:

1. await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), null).ConfigureAwait(false);

System.ArgumentNullException: Value cannot be null.
Parameter name: args
   at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke[TResult,TProgress](String method, Action`1 onProgress, Object[] args)
   at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke(String method, Object[] args)

2. await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), null, null).ConfigureAwait(false);

System.InvalidOperationException: 'EpicMethod' method could not be resolved. Potential candidates are: 
EpicMethod(daysTillNETStandard20:Nullable`1):Task

3. await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), null, new object[] {}).ConfigureAwait(false);

System.InvalidOperationException: 'EpicMethod' method could not be resolved. Potential candidates are: 
EpicMethod(daysTillNETStandard20:Nullable`1):Task
4. await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), null, new object[] {null}).ConfigureAwait(false);
System.InvalidOperationException: 'EpicMethod' method could not be resolved. Potential candidates are: 
EpicMethod(daysTillNETStandard20:Nullable`1):Task

então, por enquanto, removi a nulidade do método hub e passando 0 do lado do cliente

Reabrindo de acordo com sua descoberta ...

Eu tenho esse problema tambem. Será resolvido?

Parece uma questão simples de o fichário não converter null em Nullable<T> . Eu vou investigar.

Acontece que isso é realmente intencional. Como você realmente deve passar uma matriz de objetos com o valor null. Curta usando seu exemplo
await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), new object[] {null}).ConfigureAwait(false);

O que você estava fazendo era definir o array params que o resolvedor de parâmetros estava usando como nulo em vez de passar um valor nulo para um array params.

O problema deve ser resolvido na versão atual? Como a data de emissão foi há 5 anos, mas os parâmetros opcionais ainda não funcionam para mim?

@AlameerAshraf - mostre exatamente o que você está tentando fazer. Não acho que haja planos de mudar nada nesta área neste momento.

Não acho que os parâmetros opcionais estejam funcionando conforme o esperado. Temos uma chamada sem parâmetros, à qual estou procurando adicionar um parâmetro.

Infelizmente, não há como fazer isso sem quebrar a compatibilidade com versões anteriores, porque nosso código de cliente atualmente chama sem argumentos, eu obtenho System.IO.InvalidDataException: Invocation fornece 0 argumento (s), mas o destino espera 1 - mesmo com um único _parâmetro opcional anulável_.

Se eu tiver que mudar meu cliente para passar um nulo, então não posso manter a compatibilidade com versões anteriores e também posso não usar o parâmetro opcional 😦

Solução alternativa: adicione e chame um novo método com um nome diferente, que encaminha de volta ao original se nenhum parâmetro for passado. Decepcionante 👎

Eu realmente acho que parâmetros de método opcionais e sobrecarga devem ser suportados - isso pode estar atrasado na verdade, pois é comum usar ambos e é contra-intuitivo não usá-los ao usar SignalR.

Aqui em 2020, a sobrecarga de método funciona, mas os parâmetros opcionais não, de qualquer maneira, acho que ainda é fácil simplesmente chamar o método parametrizado de não parametrizado e manter a compatibilidade com versões anteriores.

Esta página foi útil?
0 / 5 - 0 avaliações