AspNetCore Kestrel: change your application port using a configuration file

AspNetCore Kestrel: change your application port using a configuration file

Modern AspNetCore applications use the built-in web server kestrel,this server is usually bound to the localhost address using the ports 5000 and 5001 for http and https.

But what if you want to run 2 applications in the same server? then you have a problem because if you use the default ports one of the applications will not start correctly.

This can easily be solved by changing the default ports in your WebHostBuilder as shown below

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
   .ConfigureWebHostDefaults(webBuilder => {
       webBuilder.UseUrls("http://0.0.0.0:8016");
       webBuilder.UseStartup<Startup>();
   });

The problem with the example above is that the URLs are hardcoded, so here is a better solution

public static IHostBuilder CreateHostBuilder(string[] args) =>
  Host.CreateDefaultBuilder(args)
  .ConfigureWebHostDefaults(webBuilder => {
      var config = new ConfigurationBuilder()
      .SetBasePath(Directory.GetCurrentDirectory())
      .AddJsonFile("hosting.json", optional: true)
      .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
      .AddCommandLine(args)
      .AddEnvironmentVariables()
      .Build();

      webBuilder.UseUrls(config["server.urls"]);
      webBuilder.UseStartup<Startup>();
  });

the example above uses a configuration builder to merge the appsettings.json and the hosting.json in a single configuration object, then with use the value of the property “server.urls” as base URL/port for our application

Here is the content of the hosting.json file

{
    "server.urls": "http://0.0.0.0:8016" 
}

 

 

 

Blazor: Use tag helpers to include java scripts and CSS in your html header

Blazor: Use tag helpers to include java scripts and CSS in your html header

Sometime we want to reuse our Blazor components in another apps, the best way to do this is to create a razor library, this process of create a razor library is not different from create a normal class library to share code. There is only one exception, razor components might need to reference JavaScript or CSS files. This problem can be easily solve in 2 steps as shown below.

1) Create a class that inherits from TagHelperComponent,,this class should include the tags that you want to include in the html header section of your app

using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace MyBlazorApp
{
  [HtmlTargetElement("head")]
  public class MyTagHelper: TagHelperComponent
  {
    private string Tags= 
@"
        <!-- ZXingBlazor -->
        <script src=""_content/ZXingBlazor/lib/barcodereader/zxing.js""></script>
        <script src = ""_content/ZXingBlazor/lib/barcodereader/barcode.js"" ></ script >
        < !--ZXingBlazor-- >
        < !--Signature Pad  -->
        <script src = ""_content/Mobsites.Blazor.SignaturePad/bundle.js"" ></ script >
        < link href=""_content/Mobsites.Blazor.SignaturePad/bundle.css"" rel=""stylesheet"" />
        < link href=""_content/Ultra.PropertyEditors.Module.Blazor/js/signaturepropertyeditor.js""/>
        <!-- Signature Pad  -->
        <!-- HTML Editor  -->
        <link href = ""//cdn.quilljs.com/1.3.6/quill.snow.css"" rel=""stylesheet"">
        <link href = ""//cdn.quilljs.com/1.3.6/quill.bubble.css"" rel=""stylesheet"">
        <script src = ""https://cdn.quilljs.com/1.3.6/quill.js"" ></ script >
        <script src=""_content/Blazored.TextEditor/quill-blot-formatter.min.js""></script>
        <script src = ""_content/Blazored.TextEditor/Blazored-BlazorQuill.js"" ></ script >
        < !--HTML Editor  -->
";
    public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
      if (string.Equals(context.TagName, "head", StringComparison.OrdinalIgnoreCase))
      {
        output.PostContent.AppendHtml(Tags).AppendLine();
      }
      return Task.CompletedTask;
    }
  }
}

*Note: to reference JavaScript or CSS from any razor library you can use the following syntax,please notice the doble quotes.

<script src=""_content/MyAssemblyName/PathToMyJavaScript/MyJavaScriptFile.js""></script>

 

2) Create an extension method in the “Microsoft.Extensions.DependencyInjection” namespace so you can easily add your tag helper to the service collection

 

using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Extensions.DependencyInjection
{
  public static class StartupExtensions
  {
    public static IServiceCollection AddMyHtmlTags(this IServiceCollection services)
    {
      services.AddTransient<ITagHelperComponent, MyTagHelper>();
      return services;
    }
  }
}

 

Here is an example on how to use your new extension in your startup class

 public void ConfigureServices(IServiceCollection services
 {
   services.AddMyHtmlTags();
 }

 

Log XPO queries in a Netcore app (3,5,6)

Log XPO queries in a Netcore app (3,5,6)

The LogLevel section in the appsettings.json file does not affect the .NET Framework tracing mechanism, which is used by XPO to log the queries, still we have a few work arounds for a Netcore app

  1. We can implement our own logger as shown here https://docs.devexpress.com/XPO/403928/best-practices/how-to-log-sql-queries#xpo-logger-net
  2. We can set the value of the logging switch by reflection using the following snippet
private static void EnableXpoDebugLog()
{
    FieldInfo xpoSwitchF = typeof(ConnectionProviderSql).GetField("xpoSwitch", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
    TraceSwitch xpoSwitch = (TraceSwitch)xpoSwitchF.GetValue(null);
    xpoSwitch.Level = TraceLevel.Info;
}

I actually use the second work around in my own projects.

If you want to learn more about the logging mechanism of XPO you can take a look to the following articles

https://supportcenter.devexpress.com/ticket/details/t1033081/how-to-log-the-sql-queries-made-by-xpo-in-net-5-applications

https://supportcenter.devexpress.com/ticket/details/t913939/enable-logging-in-xaf-blazor