Get The Unix Epoch Time in C#
int epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
References
https://dzone.com/articles/get-unix-epoch-time-one-line-c
int epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
References
https://dzone.com/articles/get-unix-epoch-time-one-line-c
public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
References
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-5.0
dotnet add package Microsoft.AspNetCore.HttpOverrides
Configure a proxy server
Invoke the UseForwardedHeaders
method at the top of Startup.Configure
before calling other middleware. Configure the middleware to forward the X-Forwarded-For
and X-Forwarded-Proto
headers:
// using Microsoft.AspNetCore.HttpOverrides; app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); app.UseAuthentication();
// using System.Net; services.Configure<ForwardedHeadersOptions>(options => { options.KnownProxies.Add(IPAddress.Parse("10.0.0.100")); });
Forwarded Headers Middleware order
Forwarded Headers Middleware should run before other middleware. This ordering ensures that the middleware relying on forwarded headers information can consume the header values for processing. Forwarded Headers Middleware can run after diagnostics and error handling, but it must be run before calling UseHsts:
using Microsoft.AspNetCore.HttpOverrides; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; }); var app = builder.Build(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseForwardedHeaders(); app.UseHsts(); } else { app.UseDeveloperExceptionPage(); app.UseForwardedHeaders(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAuthorization(); app.MapRazorPages(); app.Run();
Alternatively, call UseForwardedHeaders
before diagnostics:
using Microsoft.AspNetCore.HttpOverrides; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; }); var app = builder.Build(); app.UseForwardedHeaders(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAuthorization(); app.MapRazorPages(); app.Run();
Forwarded Headers Middleware options
using System.Net; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.Configure<ForwardedHeadersOptions>(options => { options.ForwardLimit = 2; options.KnownProxies.Add(IPAddress.Parse("127.0.10.1")); options.ForwardedForHeaderName = "X-Forwarded-For-My-Custom-Header-Name"; }); var app = builder.Build(); app.UseForwardedHeaders(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAuthorization(); app.MapRazorPages(); app.Run();
References
https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-5.0
https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-6.0
Run your app as a Linux service with systemd
To configure your ASP.NET Core application to run as a Linux service (or daemon in Linux parlance), install the Microsoft.Extensions.Hosting.Systemd
package from NuGet. Then add a call to UseSystemd
to the CreateHostBuilder
method in Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseSystemd() // Enable running as a Systemd service .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
dotnet publish -c Release -r linux-x64 -o ./publish
/etc/systemd/system/myapp.service
[Unit] Description=My gRPC Application [Service] Type=notify ExecStart=/usr/sbin/myapp [Install] WantedBy=multi-user.target
sudo systemctl daemon-reload sudo systemctl status myapp
sudo systemctl start myapp.service sudo systemctl enable myapp
References
https://docs.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/self-hosted
This works (server side) with Kestrel:
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.ConfigureKestrel(options => { options.Listen(IPAddress.Loopback, 5000); options.Listen(IPAddress.Loopback, 5005, configure => configure.UseHttps()); }); webBuilder.UseStartup<Startup>(); });
client side:
var httpHandler = new HttpClientHandler { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator }; AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); using var channel = GrpcChannel.ForAddress("https://localhost:5005", new GrpcChannelOptions { HttpHandler = httpHandler } ); var client = new Greeter.GreeterClient(channel);
References
https://stackoverflow.com/questions/63827667/bind-grpc-services-to-specific-port-in-aspnetcore
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/options?view=aspnetcore-5.0
https://andrewlock.net/5-ways-to-set-the-urls-for-an-aspnetcore-app/
// This switch must be set before creating the GrpcChannel/HttpClient. AppContext.SetSwitch( "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); // The port number(5000) must match the port of the gRPC server. var channel = GrpcChannel.ForAddress("http://localhost:5000"); var client = new Greet.GreeterClient(channel);
The System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport
switch is only required for .NET Core 3.x. It does nothing in .NET 5 and isn’t required.
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.ConfigureKestrel(options => { // Setup a HTTP/2 endpoint without TLS. options.ListenLocalhost(5000, o => o.Protocols = HttpProtocols.Http2); }); webBuilder.UseStartup<Startup>(); });
When an HTTP/2 endpoint is configured without TLS, the endpoint’s ListenOptions.Protocols
must be set to HttpProtocols.Http2
References
https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-5.0#call-insecure-grpc-services-with-net-core-client
https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-5.0#unable-to-start-aspnet-core-grpc-app-on-macos
var httpHandler = new HttpClientHandler(); // Return `true` to allow certificates that are untrusted/invalid httpHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions { HttpHandler = httpHandler }); var client = new Greet.GreeterClient(channel);
Add a .proto file to a C# app
<ItemGroup> <Protobuf Include="Protos\greet.proto" GrpcServices="Server" /> </ItemGroup>
C# Tooling support for .proto files
Server:
<PackageReference Include="Grpc.AspNetCore" Version="2.28.0" />
Client:
<PackageReference Include="Google.Protobuf" Version="3.11.4" /> <PackageReference Include="Grpc.Net.Client" Version="2.28.0" /> <PackageReference Include="Grpc.Tools" Version="2.28.1">
Generated C# assets
Server Side:
To ensure only the server assets are generated in a server project, the GrpcServices attribute is set to Server.
<ItemGroup> <Protobuf Include="Protos\greet.proto" GrpcServices="Server" /> </ItemGroup>
public class GreeterService : Greeter.GreeterBase { private readonly ILogger<GreeterService> _logger; public GreeterService(ILogger<GreeterService> logger) { _logger = logger; } public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) { return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); } }
Client Side:
static async Task Main(string[] args) { // The port number(5001) must match the port of the gRPC server. using var channel = GrpcChannel.ForAddress("https://localhost:5001"); var client = new Greeter.GreeterClient(channel); var reply = await client.SayHelloAsync( new HelloRequest { Name = "GreeterClient" }); Console.WriteLine("Greeting: " + reply.Message); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); }
References
https://docs.microsoft.com/en-us/aspnet/core/grpc/basics?view=aspnetcore-5.0
1 – Using the query string
Navigating page:
page.NavigationService.Navigate(new Uri("/Views/Page.xaml?parameter=test", UriKind.Relative));
Destination page:
string parameter = string.Empty; if (NavigationContext.QueryString.TryGetValue("parameter", out parameter)) { this.label.Text = parameter; }
2 – Using NavigationEventArgs
Navigating page:
page.NavigationService.Navigate(new Uri("/Views/Page.xaml?parameter=test", UriKind.Relative)); // and .. protected override void OnNavigatedFrom(NavigationEventArgs e) { // NavigationEventArgs returns destination page Page destinationPage = e.Content as Page; if (destinationPage != null) { // Change property of destination page destinationPage.PublicProperty = "String or object.."; } }
Destination page:
// Just use the value of "PublicProperty"..
3 – Using Manual navigation
Navigating page:
page.NavigationService.Navigate(new Page("passing a string to the constructor"));
Destination page:
public Page(string value) { // Use the value in the constructor... }
References
https://stackoverflow.com/questions/12444816/how-to-pass-values-parameters-between-xaml-pages
<Window x:Class="FrameSample.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Grid> <TextBlock>Outside area of frame</TextBlock> <Frame Source="Page1.xaml"> </Frame> </Grid> </Window>
navigate to a URI in a WPF Frame
<Window x:Class="FrameSample.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Grid> <TextBlock>Outside area of frame</TextBlock> <Frame Name="FrameWithinGrid" > </Frame> <Button Height="23" Margin="114,12,25,0" Name="button1" VerticalAlignment="Top" Click="button1_Click">Navigate to C# Corner </Button> </Grid> </Window>
private void button1_Click(object sender, RoutedEventArgs e) { FrameWithinGrid.Navigate(new System.Uri("Page1.xaml", UriKind.RelativeOrAbsolute)); }
navigate to an external website URL and opens the ASPX page within a Frame
FrameWithinGrid.Source = new Uri("http://www.c-sharpcorner.com/Default.aspx", UriKind.Absolute);
this code first creates a NavigationWindow and then sets its Source to a URI
NavigationWindow window = new NavigationWindow(); Uri source = new Uri("http://www.c-sharpcorner.com/Default.aspx", UriKind.Absolute); window.Source = source; window.Show();
private void NavigationViewItemHome_OnClick(object sender, RoutedEventArgs e) { FrameMain.Navigate(new PageItems()); }
References
https://www.c-sharpcorner.com/UploadFile/mahesh/using-xaml-frame-in-wpf857/
https://www.youtube.com/watch?v=YoZcAx_0rNM