Problem with SignalR when hosting Serverside Blazor App - websocket

When I run my server side Blazor app on development machine in Visual Studio code everything works fine.
But after deployment to a Linux server with Apache2 there is a problem with WSS:// SignalR connection from client to server.
Running Root page of https://shop.gastroblitz.de/
results in Console Error:
Firefox kann keine Verbindung zu dem Server unter wss://shop.gastroblitz.de/_blazor?id=P1LOmrVSgCD4fAWd9lAhHQ aufbauen. blazor.server.js:1:30021
[2019-07-17T14:58:20.948Z] Error: Failed to start the transport 'WebSockets': null
I have reverse proxy configuration that redirects
- https:// calls in server to http://localhost:5000 (where dotnet service is hosted)
- wss:// calls into ws://
seems to work fine on https:// but I don't get work the SignalR thing which is initiated with wss:// and results in the upper error...
Using Visual Studio newest preview and dotnetcore-preview6.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
SqlHub.ConnectionString = Configuration["ConnectionString"];
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddScoped<OrderState>();
services.AddScoped<StoreData>();
services.AddScoped<BasketManager>();
services.AddBlazoredModal();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
I want to have the whole Blazor app on the server like it is running in my Visual Studio environment. Would be great if someone has an useful hint regarding SSL / wss and all the configuration stuff... thx!

You need to enable websockets on your server for this to work.

Related

Blazor & Custom Certificates

I'm investigating the idea of using Blazor WASM to build a retail application that would run on an office Intranet. The application would be installed on a given machine, to be accessed via browser from any of several machines on the LAN.
The biggest stumbling block I'm running into is the question of how to go about securing the channel.
The app itself would run as a Windows Service, listening on port 443 on one of the workstations, e.g. https://reception/. But how do we tell Blazor to use a self-signed TLS cert for that hostname?
If there's a better way to go about this, I'm all ears. I can't use Let's Encrypt certs, because neither the application nor its hostname will be exposed to the public Internet.
There is a glut of information on working with Blazor to build such an app, but most if not all demos run on localhost. That works fine for dev, but not for production (in a self-hosting scenario, anyway). There doesn't seem to be much discussion at all of this aspect of things.
How can we use a custom certificate for browser requests from the client to a Blazor WASM app?
Any ideas?
I was able to get this working using some slightly modified sample code from the official documentation:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(443, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var testCert = CertificateLoader.LoadFromStoreCert(
"test", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(
StringComparer.OrdinalIgnoreCase)
{
["test"] = testCert
};
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name is not null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return testCert;
};
});
});
});
The easiest way to handle SSL is to use IIS that will act as a proxy for your Blazor app.
IIS will give you easy access to well documented SSL settings.
https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/webassembly?view=aspnetcore-6.0#standalone-deployment

How can I create a WCF Service Application in Visual Studio that does NOT use a Web Server

I have a simple task: A program (executable) is supposed to call a function of another program (also executable) with some parameters. Program A is supposed to be started, call the function and then terminate. Program B is legacy program that has a GUI and runs continuously. Both programs run on the same Windows PC and use the .NET Framework. I have no experience in web development and Program B is not supposed to run as a web service! Named pipes seem like a good option.
I researched what the best method would be and wanted to try WCF. The documentation claims that "A service endpoint can be part of a continuously available service hosted by IIS, or it can be a service hosted in an application". From that I understand that I can run Program B as a service without hosting a web server.
However everything I see in Visual Studio seems to presume I want to run a server. Wenn I want to create a new WCF project in Visual Studio the only options are a library or "A project for creating WCF service application that is hosted in IIS/WAS". Once I've created said project the debugger wants me to choose a browser for hosting the service.
In another StackOverflow topic a popular suggestion was using this website as a guide and simply removing the http references since the guide is for both named pipes and http. Another indication that it should be possible.
So can someone point me in the right direction? What am I missing? How can I use WCF with nothing related to Web Development involved?
You have already been on the way, it is enough to host the web service in Program B, without specifying a web server. this is called a self-hosted WCF. As the link you provided mentioned, the Service host class is used to host the WCF service, which means that we can host the service in the Console/Winform, and so on.
Here is an example of hosting the service in a Winform application.
public partial class Form1 : Form
{
ServiceHost serviceHost = null;
public Form1()
{
InitializeComponent();
Uri uri = new Uri("http://localhost:9009");
BasicHttpBinding binding = new BasicHttpBinding();
serviceHost = new ServiceHost(typeof(MyService), uri);
serviceHost.AddServiceEndpoint(typeof(IService), binding, "");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior()
{
HttpGetEnabled = true
};
serviceHost.Description.Behaviors.Add(smb);
System.ServiceModel.Channels.Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
serviceHost.Open();
}
private void Form1_Load(object sender, EventArgs e)
{
if (serviceHost.State==CommunicationState.Opened)
{
this.label1.Text = "Service is running";
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (serviceHost.State==CommunicationState.Opened&&serviceHost.State!=CommunicationState.Closed)
{
serviceHost.Close();
}
}
}
[ServiceContract]
public interface IService
{
[OperationContract]
string Test();
}
public class MyService:IService
{
public string Test()
{
return DateTime.Now.ToLongTimeString();
}
}
After that, we could consume it by using a client proxy.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/accessing-services-using-a-wcf-client
Feel free to let me know if there is anything I can help with.

Web API works locally but doesn’t work on azure

I have created a web API connected to azure sql server in .net core using visual studio for Mac đź’». Then I created a web app in azure and then published by project directly in visual studio for Mac to azure.
After I published I try to access the api using postman and chrome (URL/api/menu) but I got 500 server error which is generic and doesn’t tell me anything.
In visual studio for Mac I got the green light it said published and directly took me to the new url.
So, what do you guys thing is the problem.
This is my first time using azure so I didn’t change any setting or anything
Since many different problems can cause this error page, I can strongly recommend the following in order to determine the root cause quickly and easily, without struggling with Azure (or any server/platform for that matter) to get logs.
You can enable extremely helpful error messages at startup by setting the .UseSetting("detailedErrors", "true") and .CaptureStartupErrors(true) actions in your Program.cs file.
For ASP.NET CORE 2.1
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
.UseSetting("detailedErrors", "true")
.UseStartup<Startup>()
.Build();
}
Add these commands in your startup.cs class:
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
also enable stdoutLog in your web.config file
stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout"
Error code 500 in web api,usually, means problems with a configuration in Startup.cs - the most common problems include an issue with DB itself, an issue with migrations (if you are using Code First approach), problems with appsettings.js.
Please refer to the log file in .\logs\stdout.
Hope it helps.

Deploy ASP.net core 2.1 WEB API to IIS using Visual Studio Code

Working on an ASP.net core 2.1 web API project. I need to enable the API so that it can be accesed by client applications that we also have under developement.
So far, the only way I've found to publish to IIS is by doing a manual process:
Run dotnet publish -c Release
Copy the files in bin\Release\netcoreapp2.1\publish\ to my IIS Web App folder
I wonder if there is a more straight forward way of doing this.
Also It takes quite sometime to build this release, so for a development environment it's quite a slow process. The problem is that we cannot allow external access to the WEB api when running with F5 on the Integrated test server. How can we enable an more agile testing environment?
Another issue is that when calling for example fetch('MyAPIServer/api/MyItems') from a javascript application, I get a CORS error:
Failed to load http://localhost:86/api/shit: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8082' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled
Is enabling CORS absolutely necesary when developing this type of apps?
If I fetch like this:
fetch(
`http://localhost:86/api/shit`,{mode: 'no-cors'}
)
I get:
Uncaught (in promise) SyntaxError: Unexpected end of input
at eval (Pos.vue?7f37:68)
As far as the CORs issue goes you can add the following to your startup:
public void ConfigureServices(IServiceCollection services)
{
// Rest of config stuff ...
services.AddCors();
}
Then in you will also need to add the following.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors(builder =>
{
builder.WithOrigins("http://localhost:8080",
"http://localhost:8081",
"http://localhost:8082")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
app.UseMvc();
}

how to change default port in linux server for deploying aspnet core 2.0 project

I am trying to host aspnet core 2.0 application on Ubuntu Linux. It is working fine on 5000 port but when I change the port to something else like 6000 then ajax response comes null.
I'm using the below code in Program.cs
public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.Build();
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls("http://0.0.0.0:60000", "http://0.0.0.0:60001")
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
I'm using Nginx as reverse proxy in Ubuntu and when hosted with the default port, the application is working absolutely fine but when I'm trying to change the port the application not working. For now, I'm directly accessing the application without Nginx using Kestrel.

Resources