#Install-Module -Name 'WebAdministration' Import-Module -Name WebAdministration function AddSelfSignedCertificateToSSL([String]$dnsname, [String]$siteName='Default Web Site'){ $newCert = New-SelfSignedCertificate -DnsName $dnsname -CertStoreLocation Cert:\LocalMachine\My $binding = Get-WebBinding -Name $siteName -Protocol "https" $binding.AddSslCertificate($newCert.GetCertHashString(), "My") $newCertThumbprint = $newCert.Thumbprint $sourceCertificate = $('cert:\localmachine\my\' + $newCertThumbprint) $store = new-object system.security.cryptography.X509Certificates.X509Store -argumentlist "Root", LocalMachine $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]"ReadWrite") $store.Add($newCert) return $newCertThumbprint } Write-Host Installing self-signed certificate Cert:\LocalMachine\My and Cert:\LocalMachine\Root .. $certinstalledThumbprint = AddSelfSignedCertificateToSSL 'someacmeapp.somedomain.net' Write-Host Added certificate $certinstalledThumbprint to Cert:\LocalMachine\My and Cert:\LocalMachine\Root and set this up as the SSL certificate on Default Web Site.
Wednesday, 10 June 2020
Creating a self signed certificate with Powershell and preparing it for IIS
I just wrote an automated routine in Powershell to create a self signed certificate.
Thursday, 28 May 2020
Creating an AngularJs directive for a horizontal scroller at top and bottom of HTML container element
I made an AngularJs directive today that adds a horizontal scroller at top and bottom of an HTML container element, such as text area, table or div.
The AngularJs directive uses the link function of AngularJs to prepend and wrap the necessary scrolling mechanism and add some Javascript scroll event handlers using
jQuery.
import angular from 'angular'; var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope, $compile) { $scope.name = 'Dual wielded horizontal scroller'; }); app.directive('doubleHscroll', function($compile) { return { restrict: 'C', link: function(scope, elem, attr){ var elemWidth = parseInt(elem[0].clientWidth); elem.wrap(`<div id='wrapscroll' style='width:${elemWidth}px;overflow:scroll'></div>`); //note the top scroll contains an empty space as a 'trick' $('#wrapscroll').before(`<div id='topscroll' style='height:20px; overflow:scroll;width:${elemWidth}px'><div style='min-width:${elemWidth}px'> </div></div>`); $(function(){ $('#topscroll').scroll(function(){ $("#wrapscroll").scrollLeft($("#topscroll").scrollLeft()); }); $('#wrapscroll').scroll(function() { $("#topscroll").scrollLeft($("#wrapscroll").scrollLeft()); }); }); } }; });The HTML that uses this directive, restricted to 'C' (class) is then simply using the class 'double-Hscroll' following AngularJs 'snake escaping' naming convention of capitalization and dashes.
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="lib/style.css" /> <script src="lib/script.js"></script> <script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script> </head> <body ng-app="plunker" ng-cloak> <div ng-controller="MainCtrl"> <h1>Hello {{name}}</h1> <p>Dual horizontal scroll top and below a text area.</p> <textarea noresize class="double-hscroll" rows="10" cols="30"> lorem ipsum dolores lorem ipsum dolores lorem ipsum dolores lorem ipsum dolores sit amen lorem ipsum dolores lorem ipsum dolores sit amen lorem ipsum dolores lorem ipsum dolores amen sit </textarea> </div> </body> </html>
Etiketter:
AngularJs,
Directive,
Javascript,
Js,
Webdev
Tuesday, 7 April 2020
Writing to Event Log in .Net Core (Tested with .Net Core 3.1)
Writing to the Event Log in .Net Core requires first a Nuget package installation
Install-Package Microsoft.Extensions.Logging.EventLog -Version 3.1.2Note that the correct version to install depends on the version of .Net Core you are running.The package above was tested OK with .Net Core. Then we need to add EventLog. In the Program class we can do this like so:
using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.EventLog; namespace SomeAcme.SomeApi { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureLogging((hostingContext, logging) => { logging.ClearProviders(); logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddEventLog(new EventLogSettings() { **SourceName = "SomeApi", LogName = "SomeApi",** Filter = (x, y) => y >= LogLevel.Warning }); logging.AddConsole(); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartupAnd our appsettings.json file includes setup:(); }); } }
{ "ConnectionStrings": { "DefaultConnection": "Server=.\\SQLEXPRESS;Database=SomeApi;Trusted_Connection=True;MultipleActiveResultSets=true" }, **"Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } },** "AllowedHosts": "*" }We can inject the ILogger instance
using SomeAcme.SomeApi.SomeModels; using SomeAcme.SomeApi.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System.Collections.Generic; namespace SomeAcme.SomeApi.Controllers { [Route("api/[controller]")] [ApiController] public class SomeController : ControllerBase { private readonly ISomeService _healthUnitService; private readonly ILoggerMore advanced use, add a global exception handler inside Configure method of Startup class in .Net Core:_logger; public SomeController(ISomeService someService, ILogger logger) { _someService= someService; _logger = logger; } // GET: api/Some [HttpGet] public IEnumerable GetAll() { return _someService.GetAll(); } } }
//Set up a global error handler for handling Unhandled exceptions in the API by logging it and giving a HTTP 500 Error with diagnostic information in Development and Staging app.UseExceptionHandler(errorApp => { errorApp.Run(async context => { context.Response.StatusCode = 500; // or another Status accordingly to Exception Type context.Response.ContentType = "application/json"; var status = context.Features.GetAnd finally a helper model to pack our exception information into.(); var error = context.Features.Get (); if (error != null) { var ex = error.Error; string exTitle = "Http 500 Internal Server Error in SomeAcme.SomeApi occured. The unhandled error is: "; string exceptionString = !env.IsProduction() ? (new ExceptionModel { Message = exTitle + ex.Message, InnerException = ex?.InnerException?.Message, StackTrace = ex?.StackTrace, OccuredAt = DateTime.Now, QueryStringOfException = status?.OriginalQueryString, RouteOfException = status?.OriginalPath }).ToString() : new ExceptionModel() { Message = exTitle + ex.Message, OccuredAt = DateTime.Now }.ToString(); try { _logger.LogError(exceptionString); } catch (Exception err) { Console.WriteLine(err); } await context.Response.WriteAsync(exceptionString, Encoding.UTF8); } }); });
using System; using Newtonsoft.Json; namespace SomeAcme.SomeApi.Models { ///The tricky bit here is to get hold of a logger inside the Startup class. You can inject ILoggerFactory for this and just do :/// Exception model for generic useful information to be returned to client caller /// public class ExceptionModel { public string Message { get; set; } public string InnerException { get; set; } public DateTime OccuredAt { get; set; } public string StackTrace { get; set; } public string RouteOfException { get; set; } public string QueryStringOfException { get; set; } public override string ToString() { return JsonConvert.SerializeObject(this); } } }
_logger = loggerFactory.CreateLoggerWhere _logger is used in the global error handler above. Now back again to the question of how to write to the event log, look at the source code for SomeController above. We inject ILogger here. Just use that instance and it offers different methods for writing to your configured logs. Since we added in the Program class event log, this happens automatically. Before you test out the code above, run the following Powershell script as administrator to get your event log source:();
New-EventLog -LogName SomeApi -SourceName SomeApiWhat I like with this approach is that if we do everything correct, the exceptions pops up inside the SomeApi source nicely and not inside the application event log (clutter IMHO).
Subscribe to:
Posts (Atom)