5

I have a client program (WPF app on .Net 4.8) and a Web API (.Net Core 3.1). I'm trying to get the two to communicate over SignalR Core. It works perfectly when both are running locally on my PC (i.e. on localhost). But as soon as I publish my API to Azure App Service (and point the WPF app to the new URL) it doesnt work. SignalR establishes a connection, but when the API sends data to the WPF app, the app never receives it.

I'm not sure if it's related to CORS. CORS on Azure App Service is disabled. On my Web API, I this this Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        services.AddCors(options =>
        {
            options.AddPolicy(MyAllowSpecificOrigins,
                builder => builder
                .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()                    
                );
        });

        string connectionString = Configuration.GetConnectionString("eBallDatabase");
        services.AddDbContext<EBallContext>(options =>
                options.UseSqlServer(connectionString));

        var config = new AutoMapper.MapperConfiguration(cfg =>
        {
            cfg.AddProfile(new AutoMapperProfileConfiguration());
        });
        var mapper = config.CreateMapper();
        services.AddSingleton(mapper);

        services.AddSignalR(options =>
        {
            options.EnableDetailedErrors = true;
        });

        services.AddApplicationInsightsTelemetry();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors("corsPolicy");
        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapHub<ChatHub>("/chatHub");
        });
    }

I think I once read that you cannot have AllowAnyOrigin() with SignalR. You need to specify the desired origins. But I'm not sure what my origin will be as this is a WPF app running on various users computers, all with different domains/IP addresses.

Like I said, it works perfectly when everything is on loclahost. But as soon as the API is on Azure App Service, the two manage to establish a SignalR connection, but that's about it. No data is received by the WPF app from the API.

Any ideas?

Fabricio Rodriguez
  • 3,769
  • 11
  • 48
  • 101

1 Answers1

4

Yes you need to specify the origins. And order of the CORS methods also maters. And you need the CORS to comunicate beetween your Framework app and the .NET Core app. So you can try this:

services.AddCors(options =>
{
    options.AddPolicy(CorsPolicy, builder => builder.WithOrigins("https://yourFrameworkApp.azurewebsites.com")
        .AllowAnyHeader()
        .AllowAnyMethod()
        .AllowCredentials()
        .SetIsOriginAllowed((host) => true));
});

Also you can see on the client side what error do you have when connecting to the hub. For example, when the client side call the endpoint to your hub to negotiate you can have:

CORS error - try add it like bellow.

404 not found - you are pointing to the wrong controller/hub.

405 method not allowed - this is when the user is not authorized to call methods in your hub.

Also, on your Startup (Configure method) check if you are adding Web Sockets:

app.UseWebSockets();

Edit: you can also try using Azure SignalR so you don't need to worry about this type of problems.

Kiril1512
  • 3,231
  • 3
  • 16
  • 41
  • Thanks for the reply Kiril512. I will try it tongiht when I'm home. Quick question, when you say I have to specify the Origin as "https://yourFrameworkApp.azurewebsites.com", is this the URL where the API is hosted? Or is this the URL of the WPF app? Because the WPF app doesn't have a URL - it's a Windows app running on various users computers... – Fabricio Rodriguez Jan 28 '20 at 09:53
  • Also, funny enough, I don't get an error when the WPF app connects to the SignalR hub. The connection actually succeeds. But then, when the API tries to send SignalR data to the WPF app, the WPF app doesn't receive the data. (Except when the API is also running on localhost, then the WPF app receives the data) – Fabricio Rodriguez Jan 28 '20 at 09:55
  • @FabricioRodriguez "yourFrameworkApp.azurewebsites.com" is the where the app is hosted, not the client WPF app. – Kiril1512 Jan 28 '20 at 11:56
  • Ok, so where the API is hosted? Sorry, trying to understand.. – Fabricio Rodriguez Jan 28 '20 at 12:15
  • @FabricioRodriguez, you have two APP's. One is your .NET FW 4.8 app an another is .NET Core 3.1 app. They are both web apps hosted on azure. You should get the url of your .NET FW app to add to the CORS. – Kiril1512 Jan 28 '20 at 12:19
  • Oh, maybe I am missing something. I only have one app hosted on Azure App Service - the Web API (.Net Core 3.1). The other app - the client app - is just a regular Windows application, written in C# / WPF (.Net 4.8), that's installed on users computers. It is not hosted on Azure at all. But maybe I am misunderstanding something... – Fabricio Rodriguez Jan 28 '20 at 12:23
  • @FabricioRodriguez ok I understand now. You have cross domain requests to you .NET Core 3.1 app by those WPF apps. You said that it connects to the hub correctly. Did you tried to use ```Azure SignalR``` to test if you still receive the data? – Kiril1512 Jan 28 '20 at 12:27
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/206787/discussion-between-kiril1512-and-fabricio-rodriguez). – Kiril1512 Jan 28 '20 at 12:29
  • 2
    Thanks Kiril512. I'm not sure why, but using .SetIsOriginAllowed((host) => true)); did it! At one point I had something similar: .SetIsOriginAllowed(_ => true)); which never worked... – Fabricio Rodriguez Jan 28 '20 at 19:10
  • @FabricioRodriguez very nice. Good luck on your project! – Kiril1512 Jan 29 '20 at 09:44