Hosting gRPC service in a Windows Forms Application - c#

I want to create a gRPC service but I need to host in a winform .net application.
there is an extraordinary example of how Hosting ASP.NET Core API in a Windows Forms Application
I would like someone to explain to me, what I need to install and what I should change in that example, to host a grpc service in the form of Windows ...

You could follow the same steps but with several additional:
Install the package Microsoft.AspNetCore.Grpc.HttpApi This is going to map your gRPC endpoints to the classical HTTP. It is not automatic you need to specify the services in the Startup.cs as follow:
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<MygRPCService>();
});
Into your protos you need to indicate the HTTP path, something like this:
rpc Get(GetRequest) returns (GetReply) {
option (google.api.http) = {
get: '/my-endpoint'
body: '*'
};
}
Add to your Startup.cs ConfigureService method:
services.AddGrpc();
services.AddGrpcHttpApi();

Related

Blazor httpclient endpoint address configs

I'm playing around with Blazor in .net core 3 preview 5.
My solution is quite simple, with one project for the web api and a second for the blazor client app.
The api is currently serving on localhost:5000 and the blazor app on localhost:5001, and I'm using httpclient to make http calls to the rest endpoint.
One thing in struggling with is understanding the best way to avoid baking in the api server URLs into the blazor app.
Is there am established pattern which will enable be to specify the base url by config or run time?
Edit to add info from comment:
Ultimately, I'd like to run it in a container in our test k8s cluster, that means the target url for the api would change to (say) api.test.companydns.com. the blazor app will end up running inside a container, so ideally I could pass in the api url as a parameter. I wasnt sure of the best way to do that as the blazor code ends up being executed on the client side
Question:
Is there am established pattern which will enable be to specify the base url by config or run time?
Answer: Yes, the base Uri of your Blazor client side is determined by the <base> HTML element set in /wwwroot/index.html like so:
<base href="/" />
Hope this helps...
I've done a bit of a hack which works for me (posted more to show I'm putting effort into solving the problem for myself!!):
I've added a config file to wwwroot\config\config.json which contains:
{
"apiBaseUrl": "api.url.com"
}
Next, I've created an AppState.cs which used the HttpClient to download and store the base URL (Defaul DI instance of HttpClient has a BaseURL of the url serving the Blazor client app).
The AppState class is then made available using DI, so now all my Services can make calls to the new endpoint.
Lastly, I can use a build pipeline / CI / Docker volume / K8s config map to supply the relivent config.json depending on the hosting environment and without further changes to any Blazor app code.

Is there way to create a true selfhosted .Net ( Core) wepApp without any proxy

I can in ASP.NET and .NET Core create a selfhosted web service (WCF,REST, based on Kastrel or Katana and so on). But is there a way to create a full working web site, or SPA, may be based MVC ?
For example I can inside .NET Core Startup file add code:
app.Run(async (context) =>
{
await context.Response.WriteAsync($"Hello World! {
//insert your web site here :-)
}");
});
- but I should to create all html, js and so on code by myself. May be we have a better way ?
Of course I know that we have a big parts like ASP and so on - but we can't create selfhosted app, we need a web server - usually IIS !
I guess you mean that your self-hosted web server of visual studio is not accessible from the outside?
Assuming that your port forwarding and firewall are correctly configured. You need to change the bind address of your application:
new WebHostBuilder()
.UseKestrel()
...
.UseUrls("http://*:80")
...;
Note:
This should never be used without reverse proxy.
More info about why this should not be done without reverse proxy: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.0&tabs=aspnetcore2x

Host WepAPI on Service Fabric

We just stood up an on-premise MS Service Fabric cluster. I have some WebAPI's i'd like to host in it. I'm looking for resources on how to take our standard 4.5 WebAPI's and host them in Service Fabric without have to create a Service Fabric project and migrate it; that just seems too complex.
I looked at some of the Service Fabric sample projects, and it seems all the projects are tightly coupled with Service Fabric. My goal is keep these apps unaware of Service Fabric.
Any links of information is greatly appreciated, thanks!
We did this way:
Created the service fabric projects in the same solution of our WebAPI.
Inside the ServiceFabricHost project we created our HttpListenerService to expose the ports using service fabric, the same you would do to a SelfHosted WebApi.
Configure the ServiceFabricHost to open the needed endpoints.
Add the reference to the WebApi project
Use the WebApi Startup to send the IAppBuilder and configure the api with our external(SF) configuration, like ports and URL.
The secret is: when you create a self hosted web api, your generaly create a console application, like the asp.net docs. With service fabric, you replace the console with the ServiceFabricService, that is similar to a ConsoleApplication, but in this case will be a statelessService.
In this case, we used a stateless service for HttpListenerService, if you need a StateFull service, you will need to refactor your Api to use the reliable collections.
The fellow Vaclac, created a nice tutorial for this:
https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-services-communication-webapi/
If it's a standalone web application with a self-hosted web server (e.g., Katana, not IIS), then you can simply run it as a Guest Executable.
If it's not self-hosted and requires a separate web server to run, like IIS, then you can look at running it in a Container.
I had the same problem and solved it by using the DependencyResolver.GetService() method on the HttpConfiguration object in the Startup() class. Create a new Service Fabric Stateless/Statefull WebAPI project. In the Startup() class, add the following code:
public static class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public static void ConfigureApp(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
// Allow custom routes in controller attributes.
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "{controller}/{action}/{id}",
defaults: new { controller = "API", action = "HealthCheck", id = RouteParameter.Optional }
);
//inject controllers here
config.DependencyResolver.GetService(typeof({{YourWebAPIRootNamespace}}.Controllers.APIController));
appBuilder.UseWebApi(config);
}
}
This allows you to deploy your existing APIs into Service Fabric without having to migrate the entire code base to a new project. Don't forget to update the app.config in the new project with all applicable settings from your web.config.
Full blog post here http://thenameisirrelevant.com/hosting-an-existing-webapi-in-service-fabric

How ASPNET CORE start up to listen httprequest?

well, I am now learning aspnet core , I can't understand when does the application start its server(like IIS or KestrelServer),and how the server listen the httprequest and forwards the request to the application. can anybody help me? thanks
Well, let's start from beginning (As I couldn't figure out your knowledge about C#)
Every C# application must contain a single Main method specifying where program execution is to begin, so there it is, by default the templates have a Class Program where you can set the type of WebServer that you'll use, and tell the server to start listening for HTTP requests, something like:
public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
var host = new WebHostBuilder()
.UseKestrel()
.UseConfiguration(config)
.UseStartup<Startup>()
.Build();
host.Run();
}
In AspNetCore and even in AspNet (MVC or WebApi) you can (and should) use OWIN (aka Katana or vNext, that are Microsoft's OWIN implementations for AspNet and AspNetCore respectively).
OWIN represents a Interface (just a specification), that tell how WebServers should comunicate with WebApplications. Normally it handle the Http Requests to a pipeline that you can plug Middlewares, like Authentication/Authorization, Log, Error Handlings and so on, and in the end of the pipeline you should plug your Web Application.
In AspNetCore you set your Middleware Pipeline by using UseStartup<MyStartupClass> in your Host configuration see Main method above and simple as that your Pipeline will handle every HttpRequest.
When building a MVC applications in AspNetCore (.UseMvc()) you are setting a middleware that tells your application to look for classes that inherit from Microsoft.AspNetCore.Mvc.Controller to look for RESTful entry points (HTTP GET, POST...)
This is just a simple overview, and you can learn a lot more looking in the documentation of this technologies. Just search for tags like Katana, vNext, OWIN, OWIN Middleware, OWIN Pipeline...
ASP.NET Core application anatomy is discussed here at this asp.net core introduction.
Some important text that answers your question is as follows from the tutorial:
An ASP.NET Core app is simply a console app that creates a web server in its Main method. Main uses WebHostBuilder, which follows the builder pattern, to create a web application host. The builder has methods that define the web server (for example UseKestrel) and the startup class (UseStartup). In the example above, the Kestrel web server is used, but other web servers can be specified. The Startup class is where you define the request handling pipeline and where any services needed by the app are configured. The Startup class must be public and contain the following methods:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app)
{
}
}
I guess this will help you to understand how asp.net core handles Http requests.
Thanks

Any way to get OWIN to host a SOAP service?

How do I get OWIN to host a SOAP endpoint (do not care if WCF is or isn't involved, SOAP gives WSDL which makes services easier to consume by certain clients, that's why I want SOAP and REST)
I suspect the answer is: Implement your own middleware that hosts a SOAP endpoint. If that's the answer so be it, but that's a lot of work so I'll probably just end up sticking with WCF and avoiding OWIN if that's the case. I find it hard to believe no one has implemented a SOAP hosting middleware yet...
As a rule we like to do both REST and SOAP endpoints on our services; currently we use IIS and the WCF restful bits to host the SOAP with [ServiceContract]/[OperationContract] attributes, and the rest is defined with [WebInvoke] attributes, with these attributes the services need no reimplementation for the different endpoint types.
We just use the ASP.NET routes to add new ServiceRoutes which add a rest binding to URI/REST with the same service as a soap binding to URI/SOAP.
Now we're looking at doing some new services work and I'd like to move forward to using OWIN so we can implement our new services with hosting agnosticism as some services will be better served by windows service hosting and some better served by IIS service hosting.
All of my fiddling with things and so far I can come up with no way of getting a SOAP endpoint hosted by OWIN. I have the rest handled fine by making my service inherit from ApiController and then using this little snippet of code in the OWIN app's Configuration method:
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
app.UseWebApi(config);
[...]
There is a custom OWIN middleware example on MSDN that shows how to support SOAP requests. It is not a general purpose WCF host but may be enough to expose your existing WCF Services (i.e. [ServiceContract/OperationContract]) within an ASP.NET Core app. The example does not include support for [WebGet/WebInvoke] but may be enough to get you started.
https://blogs.msdn.microsoft.com/dotnet/2016/09/19/custom-asp-net-core-middleware-example/
If your primary goal is simply to begin writing new services using OWIN and you still plan to host them in IIS using Microsoft.Owin.Host.SystemWeb. You could ignore the WCF requests within the OWIN pipeline and allow the IIS ASP.NET pipeline to handle them. This would enable you to write services that are a combination of OWIN middleware and traditional WCF endpoints.
public static class WCFAppBuilderExtensions
{
public static IAppBuilder IgnoreWCFRequests(this IAppBuilder builder)
{
return builder.MapWhen(context => IsWCFRequest(context), appBuilder =>
{
// Do nothing and allow the IIS ASP.NET pipeline to process the request
});
}
private static bool IsWCFRequest(IOwinContext context)
{
// Determine whether the request is to a WCF endpoint
return context.Request.Path.Value.EndsWith(".svc", StringComparison.OrdinalIgnoreCase);
}
}
Then call the IgnoreWCFRequests extension method when configuring your app.
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
app
.IgnoreWCFRequests()
.UseWebApi(config)
.Run(context =>
{
return context.Response.WriteAsync("Default Response");
});
}
}
It's not so easy to host a WCF infrastructure over an OWIN one, sure it can be possible, with a bit of work it's clear possible to adapt, or proxy the owing request-response layer to the WCF infrastructure; WCF provides a not so easy but a complete infrastructure to do something like that.
cpowers answer may work for some, but didn't for me because I have other Filesystems setup within Owin, and I couldn't get both behaviors (fallback to other handlers when needed and also go through OWIN pipelines).
This was the configuration which made it work for me:
Use Owin automatic startup (Remove any appSettings named owin:AutomaticAppStartup)
Do not manually add its handlers in your web.config (or Startup will run twice) (Remove OwinHttpHandlerfrom from <handlers> in you web.config)
Add appBuilder.UseStageMarker(PipelineStage.MapHandler) after builder.UseFileServer()
UseFileServer must happen after all pipelines you setup, otherwise the ones setup after it will not work and you'll get 404
Optionally Fork the pipeline like cpower mentioned
If your OWIN pipelines does not register middlewares for the paths where your legacy stuff is you don't even need to fork your pipeline (my case).

Categories

Resources