Signalr: Дополнительные параметры

Созданный на 19 апр. 2012  ·  19Комментарии  ·  Источник: SignalR/SignalR

Небольшая проблема, с которой я столкнулся сегодня. Клиенту не удается вызвать серверный метод (ошибка: значение не может быть нулевым), если серверный метод принимает необязательные параметры, а клиентский вызов исключает необязательный параметр:

Сервер:

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

Клиент:

myHub.GetAll(12);

Самый полезный комментарий

Я не думаю, что необязательные параметры работают должным образом. У нас есть вызов без параметров, к которому я хочу добавить параметр.

К сожалению, нет способа сделать это без нарушения обратной совместимости, поскольку наш клиентский код в настоящее время вызывает без аргументов, я получаю System.IO.InvalidDataException: Invocation предоставляет 0 аргументов, но цель ожидает 1 - даже с одним необязательным параметром _nullable_.

Если мне нужно изменить своего клиента, чтобы передать значение null, я не смогу поддерживать обратную совместимость, а также могу вообще не использовать необязательный параметр 😦

Обходной путь: добавьте и вызовите новый метод с другим именем, который переадресуется обратно к исходному, если не передан параметр. Неутешительно

Все 19 Комментарий

Мы можем улучшить разрешение методов.

Определенно хорошая идея. Начал фактически работать над этим, но вернулся к реализации базовой реализации динамических концентраторов как можно скорее.

Кстати о разрешении метода ...
В текущей реализации мы также можем добавить поддержку перегрузок методов. Можно было бы также добавить разрешение именованных параметров, но это потребовало бы некоторых изменений в том, как параметры фактически передаются между клиентом и сервером (передача пар ключ-значение вместо просто значений). Что ты думаешь?

Применимо ли это также к параметру, допускающему значение NULL? У меня есть метод с 3 параметрами, последний из которых является обнуляемым int (int?). Если я установлю последний параметр равным null, я получу исключение:

Значение не может быть нулевым.
Имя параметра: o

в Newtonsoft.Json.Utilities.ValidationUtils.ArgumentNotNull (значение объекта, String имя параметра)
в Newtonsoft.Json.Linq.JToken.FromObjectInternal (Object o, JsonSerializer jsonSerializer)
в Newtonsoft.Json.Linq.JToken.FromObject (Object o, JsonSerializer jsonSerializer)
в Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke T
в GeoTag.App.Core.Services.SignalRClientService.d__9.MoveNext ()

Обратите внимание, что я не установил для него значение по умолчанию на сервере

Мы переместим это в новое репо в качестве кандидата v3.

@JasonBSteele - Я знаю, что это было давно, но проблема, о которой вы говорите, только что решена. Ожидайте увидеть это в следующем выпуске.

Я не понимаю, в каком состоянии находится эта проблема. Было ли это исправлено в каком-либо выпуске SignalR?

@paulirwin Нет

...

Исправление находится в версии 2.2.1, выпущенной в июле (https://github.com/SignalR/SignalR/releases/tag/2.2.1).

Я повторно проверил то, с чем столкнулся вчера, вот мои выводы:
Метод концентратора, который будет вызывать клиент

public async Task EpicMethod( int? daysTillNETStandard20 ) {}

Попытки вызова метода клиент-сервер .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

поэтому на данный момент я удалил значение NULL из метода концентратора и передал 0 со стороны клиента

Повторное открытие в соответствии с вашим выводом ...

У меня тоже есть эта проблема. Разрешится?

Похоже на то, что связыватель не преобразует null в Nullable<T> . Я займусь расследованием.

Получается, что это на самом деле задумано. Как на самом деле следует передавать массив объектов со значением null. Как это на вашем примере
await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), new object[] {null}).ConfigureAwait(false);

Что вы делали, так это устанавливали для массива params, который использует преобразователь параметров, значение null вместо передачи нулевого значения в массив params.

Предполагается, что проблема будет решена в текущей версии? Поскольку дата выпуска была 5 лет назад, но необязательные параметры все еще не работают для меня?

@AlameerAshraf - покажите, что именно вы пытаетесь сделать. Я не думаю, что на данный момент есть какие-либо планы что-либо менять в этой области.

Я не думаю, что необязательные параметры работают должным образом. У нас есть вызов без параметров, к которому я хочу добавить параметр.

К сожалению, нет способа сделать это без нарушения обратной совместимости, поскольку наш клиентский код в настоящее время вызывает без аргументов, я получаю System.IO.InvalidDataException: Invocation предоставляет 0 аргументов, но цель ожидает 1 - даже с одним необязательным параметром _nullable_.

Если мне нужно изменить своего клиента, чтобы передать значение null, я не смогу поддерживать обратную совместимость, а также могу вообще не использовать необязательный параметр 😦

Обходной путь: добавьте и вызовите новый метод с другим именем, который переадресуется обратно к исходному, если не передан параметр. Неутешительно

Я действительно думаю, что необязательные параметры метода и перегрузка должны поддерживаться - на самом деле это может быть запоздалым, поскольку обычно используются и те, и другие, а не интуитивно не использовать их при использовании SignalR.

Здесь в 2020 году перегрузка методов работает, но необязательные параметры - нет, в любом случае я думаю, что все еще легко просто вызвать параметризованный метод из непараметризованного и сохранить обратную совместимость.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги