0

I have a SignalR service and an Uno Platform WASM Client (with Prism). I want to call a hub method, which returns a model. The problem is, i have two identical models (Properties, Methods, etc.) but the client can only receive one of them upon calling the hub methods. With the other model a exception gets thrown on deserialization.

Hub:

using Microsoft.AspNetCore.SignalR;
using ReservationManagement.SignalRInterface.Model;
using System.Threading.Tasks;

namespace ReservationManagement.Service.Hubs
{
    public class TestServiceHub: Hub
    {
        public async Task<LocationModel> LocationModel()
        {
            return new LocationModel() { Name = "Location" };
        }

        public async Task<TestModel> TestModel()
        {
            return new TestModel() { Name = "Test" };

        }
    }
}

Models:

namespace ReservationManagement.SignalRInterface.Model
{
    public class TestModel
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
}


namespace ReservationManagement.SignalRInterface.Model
{
    public class LocationModel
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
}

ViewModel:

using Microsoft.AspNetCore.SignalR.Client;
using Prism.Commands;
using ReservationManagement.SignalRInterface.Model;

namespace ReservationManagement.UnoPrism.ViewModels
{
    class TestViewModel: ViewModelBase
    {

        private HubConnection HubConnection { get; set; }

        public DelegateCommand Loaded { get; private set; }


        public LocationModel LocationModel
        {
            get => _locationModel;
            set { SetProperty(ref _locationModel, value); }
        }

        private LocationModel _locationModel;

        public TestModel TestModel
        {
            get => _testModel;
            set { SetProperty(ref _testModel, value); }
        }

        private TestModel _testModel;

        public TestViewModel()
        {
            Loaded = new DelegateCommand(LoadedExecute);
        }

        private async void LoadedExecute()
        {


            HubConnection = new HubConnectionBuilder()
                .WithUrl("http://localhost:5000/TestServiceHubAnyOrigin")
                .WithAutomaticReconnect()
                .Build();

            await HubConnection.StartAsync();

            LocationModel = await HubConnection.InvokeAsync<LocationModel>("LocationModel");
            TestModel = await HubConnection.InvokeAsync<TestModel>("TestModel");
        }
    }
}

The call for LocationModel works fine and it is set to what the service returns. The call for TestModel results in an exception. If i switch the calling order (1. TestModel, 2. LocationModel) the exception will still be thrown on the TestModel-call.

Everything works perfectly fine when i build for Uwp.

Exception:

System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'ReservationManagement.SignalRInterface.Model.TestModel'. Path: $ | LineNumber: 0 | BytePositionInLine: 1. ---> System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'ReservationManagement.SignalRInterface.Model.TestModel'.

I also tried this, as the exception suggests, with a singular parameterized constructor and a parameterized constructor annotated with 'JsonConstructorAttribute', but still the same exception.

Gareld
  • 3
  • 3

1 Answers1

0

This is a generic issue related to the IL Linker step, which removes members that are detected as not used, in some cases incorrectly when reflection is used.

You will need to add linker descriptors to fix this in the LinkerConfig.xml file in the WebAssembly project, likely in the assembly that contains the ReservationManagement namespace.

You can find additional documentation about the linker configuration here.

Jérôme Laban
  • 5,224
  • 3
  • 20
  • 17