<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>asp.net core &#8211; ASP.NET Hosting Reviews and Guides</title>
	<atom:link href="https://topreviewhostingasp.net/tag/asp-net-core/feed/" rel="self" type="application/rss+xml" />
	<link>https://topreviewhostingasp.net</link>
	<description>Help you to find best ASP.NET Core Hosting</description>
	<lastBuildDate>Tue, 23 Feb 2021 03:17:46 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://topreviewhostingasp.net/wp-content/uploads/2017/01/cropped-trhaico-32x32.png</url>
	<title>asp.net core &#8211; ASP.NET Hosting Reviews and Guides</title>
	<link>https://topreviewhostingasp.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Using IHttpClientFactory in ASP.NET Core</title>
		<link>https://topreviewhostingasp.net/using-ihttpclientfactory-in-asp-net-core/</link>
					<comments>https://topreviewhostingasp.net/using-ihttpclientfactory-in-asp-net-core/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 23 Feb 2021 03:16:00 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp.net core]]></category>
		<category><![CDATA[asp.net core tips]]></category>
		<category><![CDATA[asp.net core tutorial]]></category>
		<category><![CDATA[asp.net tips]]></category>
		<category><![CDATA[asp.net tutorial]]></category>
		<category><![CDATA[httpclient asp net core]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2928</guid>

					<description><![CDATA[In today’s post, we will see how to create named HTTPClient requests using HTTPClientFactory in .NET Core or ASP.NET Core. Create a Named HTTPClient Create an ASP.NET Core Project Let’s look at step by step to understand and create named HTTPClient approach where we shall be creating HTTPClient request object using HTTPClientFactory. Interface IHTTPClientFactory  can be injected in Controller [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In today’s post, we will see how to create named HTTPClient requests using <strong>HTTPClientFactory </strong>in .NET Core or ASP.NET Core.</p>



<h2 class="wp-block-heading">Create a Named HTTPClient</h2>



<p><strong>Create an ASP.NET Core Project</strong></p>



<figure class="wp-block-image size-large"><img decoding="async" class="wp-image-2929" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/image_1.jpeg" alt="" /></figure>



<p>Let’s look at step by step to understand and create named HTTPClient approach where we shall be creating HTTPClient request object using HTTPClientFactory.</p>



<p>Interface <strong>IHTTPClientFactory  </strong>can be injected in Controller or any other class as needed using Constructor injection as below,</p>



<figure class="wp-block-image size-large"><img decoding="async" class="wp-image-2930" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/image_2.jpeg" alt="" /></figure>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>Add using namespace ‘System.Net.Http’ in the code to access HTTPClient and IHTTPClientFactory </em></p>
</blockquote>



<p>Please update the <strong>ConfigureServices </strong>method in Startup.cs as below,</p>



<p>Here in below example, we are creating two types of Named client,</p>



<ul>
<li><strong>AccountClient</strong> – This client is configured for AccountSpecific request and accept ‘<strong>application/json</strong>‘ as <strong>Content-type</strong></li>
<li><strong>PayBillClient</strong> – This client is configured for Payment and Bill request and accept ‘<strong>application/xml</strong>‘ as <strong>Content-type</strong>. It also configured with security using the <strong>BasicAuthentication </strong>scheme.</li>
</ul>



<pre class="wp-block-code"><code>public void ConfigureServices(IServiceCollection services)
       {
           services.AddControllers();
           services.AddHttpClient("AccountClient", c =&gt;
           {
               c.BaseAddress = new Uri(Configuration.GetValue&lt;string&gt;("AccountURL"));
               // Account API ContentType
               c.DefaultRequestHeaders.Add("Accept", "application/json");
           });
           services.AddHttpClient("PayBillClient", c =&gt;
           {
               c.BaseAddress = new Uri(Configuration.GetValue&lt;string&gt;("PayBillURL"));
               // Account API ContentType
               c.DefaultRequestHeaders.Add("Accept", "application/xml");
           });
       }</code></pre>



<p>Below is the client-side code base for named HTTPClient.</p>



<p>Here we specify the name of the HTTPClient request using an overloaded method <strong>CreateClient(“client name”)</strong>.</p>



<pre class="wp-block-code"><code>[HttpGet]
        public async Task&lt;IActionResult&gt; OnGet()
        {
            var uri = new Uri("https://localhost:44364/account");
            var client = _clientFactory.CreateClient("AccountClient");
            var response = await client.GetAsync(uri);
            if (response.IsSuccessStatusCode)
            {
                return Ok(response.Content.ReadAsStreamAsync().Result);
            }
            else
            {
                return StatusCode(500, "Somthing Went Wrong! Error Occured");
            }
        }</code></pre>



<p>Similarly, other named <strong>HTTPClient </strong>for “<strong>PayBillClient</strong>” can be created as below,</p>



<pre class="wp-block-code"><code>var client = _clientFactory.CreateClient("PayBillClient");</code></pre>



<p>As we understood above HTTPClientFactory lets you DI inject the HTTPClient objects using an explicit Dependency Injection principle(DI).</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>This technique can be used configure multiple HTTPClients request with custom configuration of </em><strong>Policy, Security </strong><em>and </em><strong>delegates </strong><em>as required.</em></p>
</blockquote>



<p>This technique lets you control the lifetime management of HTTPClient instances through the API pipeline itself.</p>



<p>With this technique, we are able to centralize multiple clients with specific configurations like using network credentials, specific headers or security tokens as needed.</p>



<p>That’s All, Happy coding !!. Please sound off your comments below.</p>



<h2 class="wp-block-heading">Summary</h2>



<p>In this article, we looked at how to use HTTPClientFactory for creating <strong>Named HTTPClient </strong>request object to invoke HTTP services in ASP.NET Core. This technique also lets you control custom clients based on the required policy and delegates.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/using-ihttpclientfactory-in-asp-net-core/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Caching Static Resources Forever with ASP.NET Core</title>
		<link>https://topreviewhostingasp.net/caching-static-resources-forever-with-asp-net-core/</link>
					<comments>https://topreviewhostingasp.net/caching-static-resources-forever-with-asp-net-core/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Thu, 18 Feb 2021 04:11:12 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp.net core]]></category>
		<category><![CDATA[asp.net core tips]]></category>
		<category><![CDATA[asp.net core tutorial]]></category>
		<category><![CDATA[caching asp net core]]></category>
		<category><![CDATA[net core]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2924</guid>

					<description><![CDATA[Caching static resources like stylesheet, JavaScript, or image files allows improving the performance of your website. On the client-side, a static file will always be loaded from the cache which reduces the number of requests to the server and so, the time to get the page and its resources. On the server-side, as they are [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Caching static resources like stylesheet, JavaScript, or image files allows improving the performance of your website. On the client-side, a static file will always be loaded from the cache which reduces the number of requests to the server and so, the time to get the page and its resources. On the server-side, as they are fewer requests, the server can handle more clients without upgrading the hardware.</p>



<p>While caching is a great thing, you must ensure the client is always running the latest version of the application. I mean, when you deploy the next version of the website, you don&#8217;t want the client to use an obsolete cached version of a file.</p>



<h2 class="wp-block-heading">Versioned URL (Cache buster)</h2>



<p>To ensure the user always uses the latest version of a file, we must have a unique URL per version of a file. There are many strategies:</p>



<ul>
<li>Use the query string: <code>https://sample.com/file.js?v=123</code></li>
<li>Rename the file: <code>https://sample.com/file.123.js</code></li>
<li>Create a directory: <code>https://sample.com/123/file.js</code></li>
</ul>



<p>ASP.NET Core provides a mechanism using a <code>TagHelper</code> to append the version with the query string. It supports the most common HTML tags that target a static resource: <code>script</code>, <code>link</code> and <code>img</code>. All you have to do is append <code>asp-append-version="true"</code> to the tag:</p>



<pre class="wp-block-code"><code>&lt;link rel="stylesheet" href="~/css/site.css" asp-append-version="true" /&gt;
&lt;script src="~/js/site.js" asp-append-version="true"&gt;&lt;/script&gt;
&lt;img src="~/images/banner1.svg" asp-append-version="true" /&gt;</code></pre>



<p>This will produce:</p>



<pre class="wp-block-code"><code>&lt;link rel="stylesheet" href="/css/site.css?v=1wp5zz4e-mOPFx4X2O8seW_DmUtePn5xFJk1vB7JKRc" /&gt;
&lt;script src="/js/site.js?v=EWaMeWsJBYWmL2g_KkgXZQ5nPe-a3Ichp0LEgzXczKo"&gt;&lt;/script&gt;
&lt;img src="/images/banner1.svg?v=GaE_EmkeBf-yBbrJ26lpkGd4jkOSh1eVKJaNOw9I4uk" /&gt;</code></pre>



<p>The version is the SHA256 of the file encoded in base64. Of course, the hash is computed only once per file and stored in an <code>IMemoryCache</code>.</p>



<p>The URL of files are now unique and will change when the file change, so we can add a cache header to the response to indicate the client that the file can be stored in cache forever.</p>



<h2 class="wp-block-heading">Response headers</h2>



<p>To indicate the browser to store the file in its cache, we must send the <code>Cache-control</code> header and the <code>Expires</code> header for <code>HTTP/1.0</code> compatibility. To add these headers, we use the <code>OnPrepareResponse</code> callback of the <code>StaticFilesOptions</code>. Let&#8217;s modify the <code>Startup.cs</code> file:</p>



<pre class="wp-block-code"><code>public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseStaticFiles(new StaticFileOptions
    {
        OnPrepareResponse = context =&gt;
        {
            // Cache static file for 1 year
            if (!string.IsNullOrEmpty(context.Context.Request.Query["v"]))
            {
                context.Context.Response.Headers.Add("cache-control", new[] { "public,max-age=31536000" });
                context.Context.Response.Headers.Add("Expires", new[] { DateTime.UtcNow.AddYears(1).ToString("R") }); // Format RFC1123
            }
        }
    });

    app.UseMvc(routes =&gt;
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}</code></pre>



<p>You can check the headers are sent by using the Developer Console:</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="773" height="275" class="wp-image-2925" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/developerconsole.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/developerconsole.png 773w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/developerconsole-300x107.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/developerconsole-768x273.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/developerconsole-50x18.png 50w" sizes="(max-width: 773px) 100vw, 773px" /></figure>



<h2 class="wp-block-heading" id="conclusion-60e67e">Conclusion</h2>



<p>Using HTTP caching is important for performance reasons (client and server sides). With ASP.NET Core, you can take advantage of the provided <code>TagHelper</code>s to generate a versioned URL, and change the default configuration of the <code>StaticFilesMiddleware</code> to add the <code>Cache-control</code> header for these URLs.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/caching-static-resources-forever-with-asp-net-core/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Run MySQL Connector in ASP.NET Core</title>
		<link>https://topreviewhostingasp.net/how-to-run-mysql-connector-in-asp-net-core/</link>
					<comments>https://topreviewhostingasp.net/how-to-run-mysql-connector-in-asp-net-core/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Thu, 11 Feb 2021 03:49:22 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net core mysql]]></category>
		<category><![CDATA[asp.net core]]></category>
		<category><![CDATA[asp.net core tutorial]]></category>
		<category><![CDATA[mysql connector]]></category>
		<category><![CDATA[mysql connector tips]]></category>
		<category><![CDATA[mysql connector tutorial]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2907</guid>

					<description><![CDATA[This tutorial shows how to use MySQL database with MySQL Connector in Asp.net Core. Before we start it, please make sure you have installed MySQL 5.7, .NET Core, Visual Studio, and also Sakila sample database. Let&#8217;s Get Started 1. The first step is to create ASP.NET Core Web Application and you can name it. For [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>This tutorial shows how to use MySQL database with MySQL Connector in Asp.net Core.</p>



<p>Before we start it, please make sure you have installed MySQL 5.7, <a href="https://dotnet.microsoft.com/download" target="_blank" rel="noreferrer noopener">.NET Core</a>, Visual Studio, and also <a href="https://dev.mysql.com/doc/sakila/en/sakila-installation.html" target="_blank" rel="noreferrer noopener">Sakila sample database</a>.</p>



<h2 class="wp-block-heading">Let&#8217;s Get Started</h2>



<p>1. The first step is to create ASP.NET Core Web Application and you can name it. For example, we use MvcSakilaCore.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="955" height="582" class="wp-image-2908" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_010.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_010.png 955w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_010-300x183.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_010-768x468.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_010-50x30.png 50w" sizes="(max-width: 955px) 100vw, 955px" /></figure>



<p>2. Select Web Application template and No Authentication.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="800" height="620" class="wp-image-2909" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_020.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_020.png 800w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_020-300x233.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_020-768x595.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_020-50x39.png 50w" sizes="(max-width: 800px) 100vw, 800px" /></figure>



<p>3. You will see the project below:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="768" height="416" class="wp-image-2910" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_030-768x416-1.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_030-768x416-1.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_030-768x416-1-300x163.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_030-768x416-1-50x27.png 50w" sizes="(max-width: 768px) 100vw, 768px" /></figure>



<p>4. Press F5 to run the application:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="768" height="409" class="wp-image-2911" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_040-768x409-1.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_040-768x409-1.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_040-768x409-1-300x160.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_040-768x409-1-50x27.png 50w" sizes="(max-width: 768px) 100vw, 768px" /></figure>



<p>5. Create a new folder named &#8220;Models&#8221; where it will store the database access:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="768" height="416" class="wp-image-2912" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_030-768x416-2.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_030-768x416-2.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_030-768x416-2-300x163.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_030-768x416-2-50x27.png 50w" sizes="(max-width: 768px) 100vw, 768px" /></figure>



<p>6. Installing MySQL Connector/NET Core Package</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="768" height="447" class="wp-image-2913" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/nuget-install.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/nuget-install.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/nuget-install-300x175.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/nuget-install-50x29.png 50w" sizes="(max-width: 768px) 100vw, 768px" /></figure>



<p>7. Add Connection string like below</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="678" height="98" class="wp-image-2914" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/connection-string.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/connection-string.png 678w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/connection-string-300x43.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/connection-string-50x7.png 50w" sizes="(max-width: 678px) 100vw, 678px" /></figure>



<p>8. Adding data modal classes.</p>



<p>For this example a Film class will be used. It contains the database fields as properties we want to show in our application.</p>



<pre class="wp-block-code"><code>using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MvcSakilaCore.Models
{
  public class Film
  {
    private SakilaContext context;

    public int FilmId { get; set; }

    public string Title { get; set; }

    public string Description { get; set; }

    public int ReleaseYear { get; set; }

    public int Length { get; set; }

    public string Rating { get; set; }
  }
}</code></pre>



<p>Create a new SakilaContext class that will contains the connections and Sakila database entities:</p>



<pre class="wp-block-code"><code>using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace MvcSakilaCore.Models
{
  public class SakilaContext
  {
    public string ConnectionString { get; set; }

    public SakilaContext(string connectionString)
    {
      this.ConnectionString = connectionString;
    }

    private MySqlConnection GetConnection()
    {
      return new MySqlConnection(ConnectionString);
    }

    public List&lt;Film&gt; GetAllFilms()
    {
      List&lt;Film&gt; list = new List&lt;Film&gt;();

      using (MySqlConnection conn = GetConnection())
      {
        conn.Open();
        MySqlCommand cmd = new MySqlCommand("SELECT * FROM film", conn);
        using (MySqlDataReader reader = cmd.ExecuteReader())
        {
          while (reader.Read())
          {
            list.Add(new Film()
            {
              FilmId = reader.GetInt32("film_id"),
              Title = reader.GetString("title"),
              Description = reader.GetString("description"),
              ReleaseYear = reader.GetInt32("release_year"),
              Length = reader.GetInt32("length"),
              Rating = reader.GetString("rating")
            });
          }
        }
      }

      return list;
    }
  }
}</code></pre>



<p>In order to be able to use our SakilaContext it’s required to register the instance as a service in our application. To do this add the code line in the Startup.cs file:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="998" height="630" class="wp-image-2915" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_3.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_3.png 998w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_3-300x189.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_3-768x485.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_3-50x32.png 50w" sizes="(max-width: 998px) 100vw, 998px" /></figure>



<p>9. Adding Film Controller</p>



<p>In Solution Explorer, right-click Controllers &gt; Add &gt; New Item… &gt; MVC Controller Class. Name the controller <strong>FilmsController</strong>:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="955" height="582" class="wp-image-2916" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-controller.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-controller.png 955w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-controller-300x183.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-controller-768x468.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-controller-50x30.png 50w" sizes="(max-width: 955px) 100vw, 955px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="768" height="416" class="wp-image-2917" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-controller-2.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-controller-2.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-controller-2-300x163.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-controller-2-50x27.png 50w" sizes="(max-width: 768px) 100vw, 768px" /></figure>



<p>Change the FilmsController code to this:</p>



<pre class="wp-block-code"><code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MvcSakilaCore.Models;

// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860

namespace MvcSakilaCore.Controllers
{
  public class FilmsController : Controller
  {
    // GET: /&lt;controller&gt;/
    public IActionResult Index()
    {
      SakilaContext context = HttpContext.RequestServices.GetService(typeof(MvcSakilaCore.Models.SakilaContext)) as SakilaContext;

      return View(context.GetAllFilms());
    }
  }
}</code></pre>



<p>10. Creating the Films View</p>



<p>Start creating the Films folder under Views:</p>



<p>In Solution Explorer, right click Views &gt; Films &gt; Add &gt; New Item… &gt; ASP.NET &gt; MVC View Page</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="955" height="582" class="wp-image-2918" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-view.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-view.png 955w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-view-300x183.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-view-768x468.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/film-view-50x30.png 50w" sizes="(max-width: 955px) 100vw, 955px" /></figure>



<p>Add the following code into the new Index.cshtml view file:</p>



<pre class="wp-block-code"><code>@model IEnumerable&lt;MvcSakilaCore.Models.Film&gt;
@{
  ViewBag.Title = "Films";
}
&lt;h2&gt;Films&lt;/h2&gt;
&lt;table class="table"&gt;
  &lt;tr&gt;
    &lt;th&gt;Film ID&lt;/th&gt;
    &lt;th&gt;Title&lt;/th&gt;
    &lt;th&gt;Description&lt;/th&gt;
    &lt;th&gt;Release Year&lt;/th&gt;
    &lt;th&gt;Length&lt;/th&gt;
    &lt;th&gt;Rating&lt;/th&gt;
  &lt;/tr&gt;
  @foreach (var item in Model)
  {
    &lt;tr&gt;
      &lt;td&gt;
        @Html.DisplayFor(modelItem =&gt; item.FilmId)
      &lt;/td&gt;
      &lt;td&gt;
        @Html.DisplayFor(modelItem =&gt; item.Title)
      &lt;/td&gt;
      &lt;td&gt;
        @Html.DisplayFor(modelItem =&gt; item.Description)
      &lt;/td&gt;
      &lt;td&gt;
        @Html.DisplayFor(modelItem =&gt; item.ReleaseYear)
      &lt;/td&gt;
      &lt;td&gt;
        @Html.DisplayFor(modelItem =&gt; item.Length)
      &lt;/td&gt;
      &lt;td&gt;
        @Html.DisplayFor(modelItem =&gt; item.Rating)
      &lt;/td&gt;
    &lt;/tr&gt;
  }
&lt;/table&gt;</code></pre>



<p>Before run the application, add the Films path to the running url.</p>



<p>In Solution Explorer, right click MvcSakilaCore &gt; Properties &gt; Debug &gt; Launch URL &gt; Films:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="998" height="630" class="wp-image-2919" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_4.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_4.png 998w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_4-300x189.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_4-768x485.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_4-50x32.png 50w" sizes="(max-width: 998px) 100vw, 998px" /></figure>



<p>Run the application (press F5) and the Films list should be displayed:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="768" height="373" class="wp-image-2920" src="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_5.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_5.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_5-300x146.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/02/cnet_aspnetcore_5-50x24.png 50w" sizes="(max-width: 768px) 100vw, 768px" /></figure>



<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-run-mysql-connector-in-asp-net-core/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Customize ASP.NET Core Default UI</title>
		<link>https://topreviewhostingasp.net/how-to-customize-asp-net-core-default-ui/</link>
					<comments>https://topreviewhostingasp.net/how-to-customize-asp-net-core-default-ui/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 17 Nov 2020 06:07:05 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net core 3.1]]></category>
		<category><![CDATA[asp net core 3.1 tips]]></category>
		<category><![CDATA[asp.net core]]></category>
		<category><![CDATA[asp.net core tips]]></category>
		<category><![CDATA[asp.net core tutorial]]></category>
		<category><![CDATA[dotnet core]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2792</guid>

					<description><![CDATA[ASP.NET Core Identity includes a default UI as a Razor library that enables you to quickly add users to an application, without having to build all the UI yourself. The downside is that if you want to customise any of the pages associated with the default UI, then you end up taking ownership of all [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>ASP.NET Core Identity includes a default UI as a Razor library that enables you to quickly add users to an application, without having to build all the UI yourself. The downside is that if you want to customise any of the pages associated with the default UI, then you end up taking ownership of all the logic too. Even if all you want to do is add a CSS class to an element, you&#8217;re stuck maintaining the underlying page handler logic too.</p>



<p>In this post I show how you can replace the Razor views for the default UI, without taking ownership of the business logic stored in the Razor Page <code>PageModel</code> code-behind files. I show how you can use the ASP.NET Core Identity scaffolder to generate the replacement Razor Pages initially, but customise these to use the <em>existing</em>, default, PageModels.</p>



<h2 class="wp-block-heading">ASP.NET Core Identity</h2>



<p>ASP.NET Core Identity is a series of services that provide functionality for managing and signing in users. You can use the Identity services to (among other things):</p>



<p>ASP.NET Core Identity is a series of services that provide functionality for managing and signing in users. You can use the Identity services to (among other things):</p>



<ul>
<li>Create users, and provide sign-in functionality</li>
<li>Secure passwords using best practice, strong, hashing algorithms</li>
<li><a href="https://docs.microsoft.com/en-gb/aspnet/core/security/authentication/accconfirm?view=aspnetcore-3.1#require-email-confirmation">Generate short-lived tokens for email confirmation</a> or <a href="https://docs.microsoft.com/en-us/aspnet/core/security/authentication/mfa?view=aspnetcore-3.1">multi-factor authentication</a>,</li>
<li>Enable <a href="https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity-configuration?view=aspnetcore-3.1#lockout">auto-lockout</a> of users to prevent brute-force attacks.</li>
<li><a href="https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/?view=aspnetcore-3.1">Allow logging in with third-party providers</a> like Google and Facebook.</li>
</ul>



<p>The Identity services provide APIs for achieving all these things, but you still have to arrange them all in the right order. You also have to write the UI that users use to interact with the services. Obviously, that&#8217;s a <em>huge</em> investment, and is working with sensitive data, so you have to be very careful not to introduce any security holes.</p>



<p>Prior to ASP.NET Core 2.1, your best bet for implementing this was to use the UI generated from the Visual Studio templates. Unfortunately, using templates means that your UI is fine initially, but you then have a <em>lot</em> of code to maintain. If a bug is found in the templates, you have to go and update it yourself.</p>



<p>Luckily, ASP.NET Core 2.1 introduced a default UI Razor Class Library that meant you could benefit from the same UI, without having dozens of Razor Pages in your application to maintain. If a bug is found in the UI, the NuGet package can be updated, and you seamlessly get the bug fix, and all is great.</p>



<h2 class="wp-block-heading" id="customising-the-default-ui">Customising the default UI</h2>



<p>Of course, using the default UI means: you have to use the default UI. I think it&#8217;s generally unlikely that users will want to use the default UI in its entirety, unless you&#8217;re building internal apps only, or creating a &#8220;throwaway&#8221; app. For a start, the login and register pages include references to developer documentation that most people will want to remove:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="617" class="wp-image-2806" src="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_1-3-1024x617.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_1-3-1024x617.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_1-3-300x181.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_1-3-768x463.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_1-3-1536x926.png 1536w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_1-3-2048x1234.png 2048w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_1-3-50x30.png 50w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Even though the UI is contained in a Razor Class Library, you can &#8220;overwrite&#8221; individual pages, by placing your own Razor Pages in a &#8220;magic&#8221; location in your project. For example, to override the register page, you can create a Razor Page at <em>Areas/Identity/Pages/Register.cshtml</em>:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="708" class="wp-image-2794" src="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_2-1-1024x708.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_2-1-1024x708.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_2-1-300x207.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_2-1-768x531.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_2-1-50x35.png 50w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_2-1.png 1247w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>A valid concern would be &#8220;how do I know which pages I can override?&#8221;. Luckily there&#8217;s a .NET Core tool you can use to scaffold pages from Identity in the correct locations, along with supporting files.</p>



<h2 class="wp-block-heading" id="scaffolding-identity-files-with-the-net-cli">Scaffolding Identity files with the .NET CLI</h2>



<p><a href="https://docs.microsoft.com/aspnet/core/security/authentication/scaffold-identity">The documentation for scaffolding Identity pages is excellent</a>, so I&#8217;ll just run through the basics with the .NET CLI here. You can also use Visual Studio, but be sure to follow steps 1-3 below, otherwise you get weird random errors when running the scaffolder.<br /><br />1. Add all the required packages to your application. If you&#8217;re already using EF Core in your app, then you may already have some of these, but make sure they&#8217;re all there, as missing packages can cause frustrating errors locally</p>



<pre class="wp-block-code"><code>dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.AspNetCore.Identity.UI
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>Also make sure that the installed package versions match your project version, for example .NET Core 3.1 projects should use packages starting 3.1.x.</em></p>
</blockquote>



<p>2. Confirm your project builds without errors. If it doesn&#8217;t you&#8217;ll get errors when scaffolding files.</p>



<p>3. Install the code generator tool globally using <code>dotnet tool install -g dotnet-aspnet-codegenerator</code>.</p>



<p>4. Run <code>dotnet aspnet-codegenerator identity -lf</code> from the <em>project</em> folder (not the solution folder), to see the list of files you can scaffold:</p>



<pre class="wp-block-code"><code>&gt;  dotnet aspnet-codegenerator identity -lf
Building project ...
Finding the generator 'identity'...
Running the generator 'identity'...
File List:
Account._StatusMessage
Account.AccessDenied
Account.ConfirmEmail
Account.ConfirmEmailChange
Account.ExternalLogin
Account.ForgotPassword
Account.ForgotPasswordConfirmation
Account.Lockout
... 25 more not shown!</code></pre>



<p>In this case, I&#8217;m going to scaffold the Account.Register page, and remove the external login provider section completely.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>You can create a Razor Pages app using the default UI by running </em><code>dotnet new webapp -au Individual -uld</code></p>
</blockquote>



<p>If you&#8217;re scaffolding into a project that&#8217;s configured to use the default UI, you will already have an EF Core <code>IdentityDbContext</code> in your application. Pass the fully namespaced name of the context in the following command, using the <code>-dc</code> switch, when scaffolding your files:</p>



<pre class="wp-block-code"><code>dotnet aspnet-codegenerator identity -dc TestApp.Data.ApplicationDbContext --files "Account.Register"
</code></pre>



<p>After running this command, you&#8217;ll find a bunch more files in the <em>Areas/Identity</em> folder:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="584" class="wp-image-2807" src="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_3-3-1024x584.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_3-3-1024x584.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_3-3-300x171.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_3-3-768x438.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_3-3-1536x877.png 1536w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_3-3-2048x1169.png 2048w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_3-3-50x29.png 50w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>The generated pages override the equivalents in the default UI package, so any changes you make to <em>Register.cshtml</em> will be reflected in your app. For example, I can delete the external login provider section entirely:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="617" class="wp-image-2808" src="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_4-3-1024x617.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_4-3-1024x617.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_4-3-300x181.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_4-3-768x463.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_4-3-1536x926.png 1536w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_4-3-2048x1234.png 2048w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_4-3-50x30.png 50w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="remove-your-liabilities-deleting-the-scaffolded-pagemodel">Remove your liabilities &#8211; deleting the scaffolded PageModel</h2>



<p>I don&#8217;t want that code, so I&#8217;m just going to delete it! As I&#8217;m only going to make changes to the Razor views, I can delete the following files:</p>



<ul>
<li><em>Areas/Identity/Pages/Account/Register.cshtml.cs</em> — this is the <code>PageModel</code> implementation I don&#8217;t want to have to maintain</li>
<li><em>Areas/Identity/Pages/Account/ViewImports.cshtml</em> — No longer necessary, as there&#8217;s nothing in the namespace it specifies now</li>
<li><em>Areas/Identity/Pages/_ValidationScriptsPartial.cshtml</em> — A duplicate of the version included in the default UI. No need to override it</li>
<li><em>Areas/Identity/Pages/IdentityHostingStartup.cs</em> — Doesn&#8217;t actually configure anything, so can be deleted</li>
</ul>



<p>Additionally, you can update <em>Areas/Identity/Pages/ViewImports.cshtml</em> to remove the project-specific namespaces, to leave just the following:</p>



<pre class="wp-block-code"><code>@using Microsoft.AspNetCore.Identity
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers</code></pre>



<p>At this point, your app won&#8217;t compile. The <em>Register.cshtml</em> page will complain that you&#8217;ve specified a now non-existent <code>RegisterModel</code> as the <code>PageModel</code> for the Razor Page:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="152" class="wp-image-2804" src="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_5-2-1024x152.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_5-2-1024x152.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_5-2-300x44.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_5-2-768x114.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_5-2-1536x228.png 1536w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_5-2-2048x303.png 2048w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_5-2-50x7.png 50w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>The final step is to update the <code>@page</code> directive to point to the <em>original</em> <code>RegisterModel</code> that&#8217;s included with the default Identity UI, referenced in full in the example below:</p>



<pre class="wp-block-code"><code>@page
@model Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.RegisterModel
@{
    ViewData["Title"] = "Register";
}</code></pre>



<p>This is the magic step. Your application will now compile, use your custom Razor views, but use the <em>original</em> Razor Pages <code>PageModel</code>s that are part of the default UI! That&#8217;s much less code to maintain, and less chance to screw something up in your Identity pages</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="561" class="wp-image-2805" src="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_6-2-1024x561.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_6-2-1024x561.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_6-2-300x164.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_6-2-768x421.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_6-2-1536x842.png 1536w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_6-2-50x27.png 50w, https://topreviewhostingasp.net/wp-content/uploads/2020/11/image_6-2.png 1597w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="what-are-the-downsides-">What are the downsides?</h2>



<p>So what are the downsides of this approach? The only one I can really think of is that you&#8217;re very tightly tied to the <code>PageModel</code>s in the original Identity UI, so you have to be sure that any updates that are made to the Identity UI are reflected in your Razor Page templates as appropriate. The big advantage is that if the default UI package is updated and it doesn&#8217;t make any breaking changes to the Razor templates, then you get the updates with no friction at all.</p>



<p>Another danger is that the inability to customise the <code>PageModel</code> <em>may</em> encourage you to do slightly janky things like <code>@inject</code>-ing services into the Razor views that shouldn&#8217;t be there, and adding additional logic into the Razor views. I&#8217;m not suggesting you should do this. If you _do_ need to change the behaviour of the page handlers, then you should just go ahead and take ownership of that code. The point is that this technique is useful when you <em>don&#8217;t</em> need to change the page handler logic.</p>



<h2 class="wp-block-heading" id="summary">Summary</h2>



<p>In this post I gave some background on ASP.NET Core Identity and the default UI Razor Class Library that provides over 30 Razor Pages &#8220;for free&#8221;. I then showed how you could use the scaffolder tool to override one of these pages when you want to change the Razor template.</p>



<p>The downside of this default approach is that you now have to maintain the page handlers for the scaffolded pages. That&#8217;s 100s of lines of code per page that you must keep up to date when a new package version is released.</p>



<p>I showed how you can avoid that burden by deleting the scaffolded <code>PageModel</code> file, and point your Razor template to the <em>original</em> <code>PageModel</code> that comes as part of the default UI. This lets you update your Razor templates without having to take ownership of the page handler logic, potentially giving you the best of both worlds.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-customize-asp-net-core-default-ui/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Run .NET Core Generic as Windows Service</title>
		<link>https://topreviewhostingasp.net/how-to-run-net-core-generic-as-windows-service/</link>
					<comments>https://topreviewhostingasp.net/how-to-run-net-core-generic-as-windows-service/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 29 Oct 2019 04:41:34 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net core windows service]]></category>
		<category><![CDATA[asp.net core]]></category>
		<category><![CDATA[asp.net core tips]]></category>
		<category><![CDATA[asp.net core tutorial]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2769</guid>

					<description><![CDATA[Net Core 2.2 provides Web Host for hosting web applications and Generic Host that is suitable for hosting a wider array of host apps. In the .Net Core 3 Generic Host will replace Web Host.  Generic Host will be suitable for hosting any kind of app including web applications. I looked at many examples but found that none showed [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Net Core 2.2 provides <a href="https://topreviewhostingasp.net/best-asp-net-core-3-hosting/">Web Host</a> for hosting web applications and <a href="https://docs.microsoft.com/en-au/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.2" target="_blank" rel="noreferrer noopener">Generic Host</a> that is suitable for hosting a wider array of host apps. In the .Net Core 3 Generic Host will replace Web Host.  Generic Host will be suitable for hosting any kind of app including web applications.</p>



<p>I looked at many examples but found that none showed the complete implementation of the Generic Host that is implemented to run as a console, Linux daemon, and Windows Service all in one application.</p>



<p>Here we will be looking at extending sample_service_hosting app to run it as a console app, windows service, or Linux daemon as well as making it self installable windows service.</p>



<p>.Net Core provides <em>IHostBuilder</em> interface to configure and create host builder. In case of a console app, host builder will run <em>await RunConsoleAsync()</em> function. To host and run our Generic Host as Windows Service we will need to use <em>IApplicationLifetime</em> to register Start and Stop events.</p>



<p>For hosting our Generic Host in Linux daemon we are going to inject <em>IApplicationLifetime</em> into main service and register and handle Start and Stop events.</p>



<p>There are several ways we could go to extend it to run as Windows Service, console app and Linux daemon. One way is to have a separate .Net Core project that will host our sample generic host service for each case or allow the program to accept command line variables that specify how to run the program. We will implement the command line arguments.</p>



<p><strong>Command-line options:</strong></p>



<ul>
<li>-i    Install as Windows Service</li>
<li>-u  Uninstall Windows Service</li>
<li>-console Run as a console app</li>
<li>-daemon Run as Linux daemon service</li>
<li>-h  Show command line switch help</li>
</ul>



<h2 class="wp-block-heading">Let’s make Argument Parser</h2>



<p>In order to parse the arguments passed to the application, we will implement an argument parser class, which will return <em>HostAction</em> enum that specifies how the application is going to start. The application will accept only one argument on its input. If more than one argument supplied or it is an invalid argument, it will show usage message. If no arguments supplied it will try to run as Windows Service.</p>



<h3 class="wp-block-heading">HostAction enum</h3>



<pre class="wp-block-code"><code>namespace VSC
{
    public enum HostAction
    {
        ShowUsage,
        InstallWinService,
        UninstallWinService,
        RunWinService,
        WinServiceStop,
        RunConsole,
        RunLinuxDaemon
    }
}</code></pre>



<h3 class="wp-block-heading">Argument Parser class – ArgsParser</h3>



<pre class="wp-block-code"><code>namespace VSC
{
    internal class ArgsParser
    {
        private string[] _args = null;
        public ArgsParser(string[] args)
        {
            _args = args;
        }

        public HostAction GetHostAction()
        {
            HostAction action = HostAction.ShowUsage;

            if(_args == null || _args.Length == 0)
            {
                action = HostAction.RunWinService;
            }
            else if(_args.Length &gt; 1)
            {
                action = HostAction.ShowUsage;
            }
            else
            {
                string argument = _args[0];

                if(argument == "-i")    // install
                {
                    action = HostAction.InstallWinService;
                }
                else if(argument == "-u")   // uninstall
                {
                    action = HostAction.UninstallWinService;
                }
                else if(argument == "-console")
                {
                    action = HostAction.RunConsole;
                }
                else if (argument == "-daemon")
                {
                    action = HostAction.RunLinuxDaemon;
                }
            }

            return action;
        }
    }
}</code></pre>



<h2 class="wp-block-heading">Let’s make HostedService class</h2>



<p>At the moment sample_service_hosting app creates host builder by calling <em>CreateHostBuilder()</em> from the Main function. We need to introduce a class that will perform an action depending on what HostAction returned by ArgsParser. We will call it <em>HostedService</em> class. It will have an async Run function that will start different action.</p>



<p>For now let’s implement run as a console, run as Linux daemon and show usage actions. Function <em>CreateHostBuilder()</em> will be moved from Program.cs to <em>HostedService</em> class.</p>



<h3 class="wp-block-heading">HostedService class</h3>



<pre class="wp-block-code"><code>using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NLog.Extensions.Hosting;

namespace VSC
{
    internal class HostedService
    {
        private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();

        private ArgsParser _argsParser = null;

        public HostedService(ArgsParser argsParser)
        {
            _argsParser = argsParser;
        }

        public async Task Run(string[] args)
        {
            if (_argsParser != null)
            {
                var builder = this.CreateHostBuilder(args);
                
                if(builder == null) return;

                switch (_argsParser.GetHostAction())
                {
                    case HostAction.InstallWinService:
                    {
                        
                    }
                    break;
                    case HostAction.UninstallWinService:
                    {
                        
                    }
                    break;
                    case HostAction.RunWinService:
                    {
                        
                    }
                    break;
                    case HostAction.RunConsole:
                    {
                        try
                        {
                            await builder.RunConsoleAsync();
                        }
                        catch(Exception ex)
                        {
                            _logger.Error("Could not run as console app. " + ex.Message);
                            ShowUsage();
                        }
                    }
                    break;
                    case HostAction.RunLinuxDaemon:
                    {
                        try
                        {
                            await builder.Build().RunAsync();
                        }
                        catch(Exception ex)
                        {
                            _logger.Error("Could not start as Linux daemon service. " + ex.Message);
                            ShowUsage();
                        }
                    }
                    break;
                    default:
                    {
                        ShowUsage();
                    }
                    break;
                } 
            }   
        }

        private void ShowUsage()
        {   
            Console.WriteLine("Options:\n"
                        + "  'no options'\tStart Windows Service\n"
                        + "  -i\t\tInstall as Windows Service\n"
                        + "  -u\t\tUninstall Windows Service\n"
                        + "  -console\tRun as console app\n"
                        + "  -daemon\t Run as Linux daemon service\n"
                        + "  -h\t\tShow command line switch help\n");
        }
        private IHostBuilder CreateHostBuilder(string[] args)
        {
            try
            {
                var builder = new HostBuilder()
                    .UseNLog()
                    .ConfigureAppConfiguration((hostingContext, config) =&gt;
                    {
                        config.SetBasePath(Directory.GetCurrentDirectory());
                        config.AddJsonFile("appsettings.json", optional: true);
                        config.AddJsonFile(
                            $"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", 
                            optional: true);
                        config.AddCommandLine(args);
                    })
                    .ConfigureServices((hostContext, services) =&gt;
                    {
                        services.AddHostedService&lt;Services.SampleService&gt;();
                        services.Configure&lt;HostOptions&gt;(option =&gt;
                        {
                            option.ShutdownTimeout = System.TimeSpan.FromSeconds(20);
                        });
                    })
                    .ConfigureLogging((hostingContext, logging) =&gt; 
                    {
                        logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                        logging.AddConsole();
                    });

                return builder;
            }
            catch { }

            return null;
        }
    }
}</code></pre>



<p>In Program.cs we change code as follows.</p>



<h3 class="wp-block-heading">Program.cs</h3>



<pre class="wp-block-code"><code>using System.Threading.Tasks;

namespace VSC
{
    class Program
    {   
        static async Task Main(string[] args)
        {
            ArgsParser argsParser = new ArgsParser(args);

            HostedService service = new HostedService(argsParser);
            await service.Run(args);
        }
    }
}</code></pre>



<h2 class="wp-block-heading">Let’s Make it self installable Windows Service</h2>



<p>Now we got to the point of making our sample app to run as Windows Service. As Software Developer we always try to make the life of our users easier. If the app will be able to self install/uninstall as windows service our users will be much happier than trying to do that themselves.</p>



<p>We will start in the external process <em>sc.exe</em> service controller tool with parameters to install/uninstall/stop service. Example:<ins></ins></p>



<ul>
<li>sc.exe create “service_name” displayname= “service_name” binpath= “path to exe file”</li>
<li>sc.exe delete “service_name”</li>
<li>sc.exe stop “service_name”</li>
</ul>



<p><em>WinServiceInstaller</em> class will be responsible for running an external process and notifying of the progress. We will use <em>WinService</em> class to handle Start, Stop events and use extension functions to inject our WinService class into our Generic Host Builder.</p>



<h3 class="wp-block-heading">WinService class</h3>



<pre class="wp-block-code"><code>using System;
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;

namespace VSC
{
    public class WinService : ServiceBase, IHostLifetime
    {
        public static string WinServiceName = "Default Service Name";
        private readonly TaskCompletionSource&lt;object&gt; _delayStart = new TaskCompletionSource&lt;object&gt;();

        private IApplicationLifetime ApplicationLifetime { get; }

        public WinService(IApplicationLifetime applicationLifetime)
        {
            this.ServiceName = WinServiceName;

            ApplicationLifetime = applicationLifetime ?? throw new ArgumentNullException(nameof(applicationLifetime));
        }        

        public void Start()
        {
            try
            {
                Run(this); // This blocks until the service is stopped.
                _delayStart.TrySetException(new InvalidOperationException("Stopped without starting"));
            }
            catch (Exception ex)
            {
                _delayStart.TrySetException(ex);
            }

            this.OnStart(null);
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            Stop();
            return Task.CompletedTask;
        }

        public Task WaitForStartAsync(CancellationToken cancellationToken)
        {
            cancellationToken.Register(() =&gt; _delayStart.TrySetCanceled());
            ApplicationLifetime.ApplicationStopping.Register(Stop);

            new Thread(Start).Start(); // Otherwise this would block and prevent IHost.StartAsync from finishing.
            return _delayStart.Task;
        }

        protected override void OnStart(string[] args)
        {
            _delayStart.TrySetResult(null);
            base.OnStart(args);
        }

        protected override void OnStop()
        {
            ApplicationLifetime.StopApplication();
            base.OnStop();
        }
    }
}</code></pre>



<h3 class="wp-block-heading">WinServiceInstaller class</h3>



<pre class="wp-block-code"><code>using System.Diagnostics;

namespace VSC
{
    public static class WinServiceInstaller
    {
        private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();

        public static string APP_EXECUTABLE_PATH = string.Empty;
        private const string ServiceControllerEXE = "sc.exe";

        public delegate void WinServiceStatusHandler (string status);
        public static event WinServiceStatusHandler WinServiceStatus;

        public static void Uninstall(string serviceName)
        {
            Stop(serviceName); // stop service before uninstall

            RaiseWinServiceStatus("Uninstall Service");

            RunProcess(string.Format("delete \"{0}\"", serviceName));
        }

        private static void Stop(string serviceName)
        {
            RaiseWinServiceStatus("Stopping Service");

            RunProcess(string.Format("stop \"{0}\"", serviceName));            
        }

        public static void Install(string serviceName)
        {
            if(!string.IsNullOrEmpty(APP_EXECUTABLE_PATH))
            {
                RaiseWinServiceStatus("Install Service");

                string processArguments = string.Format("create \"{0}\" displayname= \"{1}\" binpath= \"{2}\"", serviceName, serviceName, APP_EXECUTABLE_PATH);
                
                RunProcess(processArguments);
            }
            else
            {
                _logger.Error("Cannot install service. Path to exe cannot be empty.");
            }
        }

        private static void RaiseWinServiceStatus(string status)
        {
            if(WinServiceStatus != null)
            {
                WinServiceStatus(status);
            }
        }

        private static void RunProcess(string arguments)
        {
            _logger.Trace("Arguments: " + arguments);

            var process = new Process();
            var processInfo = new ProcessStartInfo();
            processInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            processInfo.FileName = ServiceControllerEXE;
            processInfo.Arguments = arguments;
            process.StartInfo = processInfo;
            process.Start();
            process.WaitForExit();
        }
    }
}</code></pre>



<h3 class="wp-block-heading">WinServiceExtensions static class</h3>



<pre class="wp-block-code"><code>using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace VSC
{
    public static class WinServiceExtensions
    {
        internal static IHostBuilder UseServiceBaseLifetime(this IHostBuilder hostBuilder)
        {
            return hostBuilder.ConfigureServices((hostContext, services) =&gt; services.AddSingleton&lt;IHostLifetime, WinService&gt;());
        }

        public static Task RunAsWindowsServiceAsync(this IHostBuilder hostBuilder, CancellationToken cancellationToken = default)
        {
            return hostBuilder.UseServiceBaseLifetime().Build().RunAsync(cancellationToken);
        }
    }
}</code></pre>



<p>We need to add to our project package reference <em>System.ServiceProcess.ServiceController</em> in order to compile <em>WinService</em> class.</p>



<pre class="wp-block-code"><code>dotnet add package System.ServiceProcess.ServiceController</code></pre>



<p>Now in <em>HostedService</em> Run function, we can implement remaining switch cases that will Install, Uninstall and Run our app as windows service.</p>



<pre class="wp-block-code"><code>internal class HostedService
{
    ...

    public async Task Run(string[] args)
    {
        if (_argsParser != null)
        {
            var builder = this.CreateHostBuilder(args);
                
            if(builder == null) return;

            WinServiceInstaller.APP_EXECUTABLE_PATH = Utility.GetExecutingAssemblyLocation().Remove(Utility.GetExecutingAssemblyLocation().Length - 4) + ".exe";
                
            switch (_argsParser.GetHostAction())
            {
                case HostAction.InstallWinService:
                {
                    WinServiceInstaller.Install(WinService.WinServiceName);
                }
                break;
                case HostAction.UninstallWinService:
                {
                    WinServiceInstaller.Uninstall(WinService.WinServiceName);
                }
                break;
                case HostAction.RunWinService:
                {
                    try
                    {
                        await builder.RunAsWindowsServiceAsync();
                    }
                    catch(Exception ex)
                    {
                        _logger.Error("Could not start as windows service. " + ex.Message);
                        ShowUsage();
                    }
                }
                break;

    ...
}</code></pre>



<p>You may have noticed that APP_EXECUTABLE_PATH is set by calling utility function <em>GetExecutingAssemblyLocation</em> in Utility class.</p>



<h3 class="wp-block-heading">Utility static class</h3>



<pre class="wp-block-code"><code>namespace VSC
{
    public static class Utility
    {
        public static string GetExecutingAssemblyLocation()
        {
            return System.Reflection.Assembly.GetExecutingAssembly().Location;
        }
    }
}</code></pre>



<h2 class="wp-block-heading">Let’s update the Main function</h2>



<p>As the final step, we will update our Program.cs and add the logger to print status of our Windows Service. At the end before closing application, we also need to Flush logger and shut it down to release resource when our app will run as Linux daemon.</p>



<h3 class="wp-block-heading">Program.cs</h3>



<pre class="wp-block-code"><code>using System;
using System.Threading.Tasks;
using NLog;
using System.Reflection;

namespace VSC
{
    class Program
    {   
        private static Logger _logger = NLog.LogManager.GetCurrentClassLogger();

        static async Task Main(string[] args)
        {
            ArgsParser argsParser = new ArgsParser(args);

            WinService.WinServiceName = "The Sample Service Host";
            WinServiceInstaller.WinServiceStatus += new WinServiceInstaller.WinServiceStatusHandler(PrintWinServiceStatus);

            _logger.Info("Version: " + Assembly.GetEntryAssembly().GetName().Version.ToString());

            HostedService service = new HostedService(argsParser);
            await service.Run(args);

            _logger.Info("Shutting down logger...");
            // Flush buffered log entries before program exit; then shutdown the logger before program exit.
            LogManager.Flush(TimeSpan.FromSeconds(15));
            LogManager.Shutdown();
        }

        private static void PrintWinServiceStatus(string status)
        {
            _logger.Info(status);
        }
    }
}</code></pre>



<h2 class="wp-block-heading">Summary</h2>



<p>Today we extended sample_service_hosting app with the ability to run as windows service and self install/uninstall itself to make it easier to deploy as windows service. We could go down the path of implementing separate projects: one for a console app, one for Linux daemon, one for windows service and one common project with our SampleService Host. We managed to do it all in one project with the use of ArgsParser class and extension functions to inject our Host into <em>WinService</em>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-run-net-core-generic-as-windows-service/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Top 13 ASP.NET Core Features that You MUST Try</title>
		<link>https://topreviewhostingasp.net/13-asp-net-core-features/</link>
					<comments>https://topreviewhostingasp.net/13-asp-net-core-features/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Wed, 09 Jan 2019 04:11:33 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp.net core]]></category>
		<category><![CDATA[asp.net core tips]]></category>
		<category><![CDATA[asp.net core tutorial]]></category>
		<category><![CDATA[ASP.NET Hosting]]></category>
		<category><![CDATA[cheap ASP.NET Hosting]]></category>
		<category><![CDATA[development asp.net core]]></category>
		<category><![CDATA[reason to use asp.net]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2641</guid>

					<description><![CDATA[ASP.NET is one of the most successful web application development frameworks by Microsoft. With every update, new and extended features are added that help developers deploy highly scalable and high-performance web applications. When coupled with application monitoring and other performance tools, such as a profiler, ASP.NET becomes a powerful solution for building incredible apps. Within the framework itself, there [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>ASP.NET is one of the most successful web application development frameworks by Microsoft. With every update, new and extended features are added that help developers deploy highly scalable and high-performance web applications.</p>
<p>When coupled with application monitoring and other performance tools, such as a profiler, ASP.NET becomes a powerful solution for building incredible apps.</p>
<p>Within the framework itself, there are myriad features to help you overcome common development challenges, do more with your apps, and boost performance.</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-2642" src="https://topreviewhostingasp.net/wp-content/uploads/2019/01/asp-net-core.png" alt="" width="288" height="175" srcset="https://topreviewhostingasp.net/wp-content/uploads/2019/01/asp-net-core.png 288w, https://topreviewhostingasp.net/wp-content/uploads/2019/01/asp-net-core-50x30.png 50w" sizes="(max-width: 288px) 100vw, 288px" /></p>
<h2>13 features to build better applications with ASP.NET Core</h2>
<h3>1. Cross-platform &amp; container support</h3>
<p>With the introduction of .NET Core, you can now create ASP.NET applications and deploy them to <strong>Windows, Linux, and macOS</strong>. Microsoft and the community have put a huge effort into making Linux a first-class citizen for running ASP.NET.</p>
<p>Containers are eating the clouds these days. Docker, Kuberenetes and other technologies are all the rage. ASP.NET Core allows developers to utilize all of these new technologies. Microsoft Azure even has support for deploying your application to containers and Kubernetes.</p>
<h3>2. High performance</h3>
<p>Some say that performance is a critical feature of your software. I tend to agree! With the introduction of ASP.NET Core and the Kestrel web server, ASP.NET is touted as one of the fastest web application frameworks available. <a href="https://www.techempower.com/benchmarks/" target="_blank" rel="noopener noreferrer">TechEmpower</a> has some cool benchmarks you can check out.</p>
<p>The technology that powered the ASP.NET integrated pipeline and IIS was roughly 15 years old. It did everything and carried a lot of baggage with it. The new Kestrel web server was redesigned from the ground up to take advantage of asynchronous programming models, be much more lightweight, and fast!</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-2643" src="https://topreviewhostingasp.net/wp-content/uploads/2019/01/kestrel.png" alt="" width="1501" height="875" srcset="https://topreviewhostingasp.net/wp-content/uploads/2019/01/kestrel.png 1501w, https://topreviewhostingasp.net/wp-content/uploads/2019/01/kestrel-300x175.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2019/01/kestrel-768x448.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2019/01/kestrel-1024x597.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2019/01/kestrel-50x29.png 50w" sizes="(max-width: 1501px) 100vw, 1501px" /></p>
<h3>3. Asynchronous via async/await</h3>
<p>ASP.NET has excellent support for utilizing asynchronous programming patterns. Async is now implemented in all common .NET Framework classes and most third-party libraries. Most modern applications spend most of their time and CPU cycles waiting for database queries, web service calls, and other I/O operations to complete.</p>
<p>One of the reasons ASP.NET Core is faster is its extensive use of asynchronous patterns within the new MVC and Kestrel frameworks.</p>
<pre class="prettyprint prettyprinted"><span class="com">//mark the method as async</span>
<span class="kwd">public</span> <span class="kwd">async</span> <span class="typ">Task</span> <span class="typ">GetGWB</span><span class="pun">()</span>
<span class="pun">{</span>
    <span class="typ">HttpClient</span><span class="pln"> hc </span><span class="pun">=</span> <span class="kwd">new</span> <span class="typ">HttpClient</span><span class="pun">();</span>
    <span class="com">//await keyword handles all the complexity of async threading and callbacks</span>
    <span class="kwd">await</span><span class="pln"> hc</span><span class="pun">.</span><span class="typ">GetAsync</span><span class="pun">(</span><span class="str">"http://geekswithblogs.net/Default.aspx"</span><span class="pun">);</span>
    <span class="kwd">return</span> <span class="kwd">true</span><span class="pun">;</span>
<span class="pun">}</span></pre>
<h3><a href="http://www.asphostportal.com"><img loading="lazy" decoding="async" class="size-full wp-image-2584 alignleft" src="https://topreviewhostingasp.net/wp-content/uploads/2018/11/ahp-banner-aspnet-01.png" alt="" width="300" height="271" srcset="https://topreviewhostingasp.net/wp-content/uploads/2018/11/ahp-banner-aspnet-01.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2018/11/ahp-banner-aspnet-01-50x45.png 50w" sizes="(max-width: 300px) 100vw, 300px" /></a>4. Unified MVC &amp; Web API frameworks</h3>
<p>Before ASP.NET Core, developers were most commonly using the MVC and Web API frameworks. MVC was tailored to creating web applications that served up HTML. Web API was designed to create RESTful services using JSON or XML.</p>
<p>With ASP.NET Core, MVC and Web API have been merged together. There was always a lot of overlap with the two frameworks. MVC could always return JSON data instead of HTML. Combining them was a good move and simplifies development.</p>
<p>With ASP.NET Core we also have the new Razor Pages. They extend the MVC framework to allow encapsulating the controller and model aspects of a page together with two-way binding. They are sort of a replacement for WebForms while using the familiar Razor syntax.</p>
<h3>5. Multiple environments and development mode</h3>
<p>One of my favorite features is the new environment feature. It allows you to easily differentiate parts of your code for their behavior in development, staging, production, etc. There was no standard way to do this before ASP.NET Core.</p>
<p>Environments are perfect for using different CSS or Javascript files. Use your CDN in production, but local files during development. This is a snippet out of my Razor layout view.</p>
<pre class="prettyprint prettyprinted">    <span class="tag">&lt;environment</span> <span class="atn">names</span><span class="pun">=</span><span class="atv">"Development"</span><span class="tag">&gt;</span>
        <span class="tag">&lt;script</span> <span class="atn">src</span><span class="pun">=</span><span class="atv">"~/lib/jquery/dist/jquery.js"</span><span class="tag">&gt;&lt;/script&gt;</span>
        <span class="tag">&lt;script</span> <span class="atn">src</span><span class="pun">=</span><span class="atv">"~/lib/bootstrap/dist/js/bootstrap.js"</span><span class="tag">&gt;&lt;/script&gt;</span>
        <span class="tag">&lt;script</span> <span class="atn">src</span><span class="pun">=</span><span class="atv">"~/js/site.js"</span> <span class="atn">asp-append-version</span><span class="pun">=</span><span class="atv">"true"</span><span class="tag">&gt;&lt;/script&gt;</span>
    <span class="tag">&lt;/environment&gt;</span>
    <span class="tag">&lt;environment</span> <span class="atn">names</span><span class="pun">=</span><span class="atv">"Staging,Production"</span><span class="tag">&gt;</span>
        <span class="tag">&lt;script</span> <span class="atn">src</span><span class="pun">=</span><span class="atv">"https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"</span>
                <span class="atn">asp-fallback-src</span><span class="pun">=</span><span class="atv">"~/lib/jquery/dist/jquery.min.js"</span>
                <span class="atn">asp-fallback-test</span><span class="pun">=</span><span class="atv">"window.jQuery"</span>
                <span class="atn">crossorigin</span><span class="pun">=</span><span class="atv">"anonymous"</span>
                <span class="atn">integrity</span><span class="pun">=</span><span class="atv">"sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk"</span><span class="tag">&gt;</span>
        <span class="tag">&lt;/script&gt;</span>
        <span class="tag">&lt;script</span> <span class="atn">src</span><span class="pun">=</span><span class="atv">"https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"</span>
                <span class="atn">asp-fallback-src</span><span class="pun">=</span><span class="atv">"~/lib/bootstrap/dist/js/bootstrap.min.js"</span>
                <span class="atn">asp-fallback-test</span><span class="pun">=</span><span class="atv">"window.jQuery &amp;&amp; window.jQuery.fn &amp;&amp; window.jQuery.fn.modal"</span>
                <span class="atn">crossorigin</span><span class="pun">=</span><span class="atv">"anonymous"</span>
                <span class="atn">integrity</span><span class="pun">=</span><span class="atv">"sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"</span><span class="tag">&gt;</span>
        <span class="tag">&lt;/script&gt;</span>
        <span class="tag">&lt;script</span> <span class="atn">src</span><span class="pun">=</span><span class="atv">"~/js/site.min.js"</span> <span class="atn">asp-append-version</span><span class="pun">=</span><span class="atv">"true"</span><span class="tag">&gt;&lt;/script&gt;</span>
    <span class="tag">&lt;/environment&gt;</span></pre>
<h3>6. Dependency Injection</h3>
<p>One of the great new features of ASP.NET Core is built in dependency injection. It is heavily used within ASP.NET MVC itself. It is the preferred way that things like logging contexts, database contexts, and other things are passed into your MVC controllers.</p>
<pre class="prettyprint prettyprinted"><span class="kwd">public</span> <span class="kwd">class</span> <span class="typ">PaymentService</span><span class="pun">:</span> <span class="typ">IPaymentService</span>
<span class="pun">{</span>
  <span class="kwd">public</span> <span class="typ">ILogger</span> <span class="typ">Logger</span> <span class="pun">{</span> <span class="kwd">get</span><span class="pun">;</span> <span class="pun">}</span>

  <span class="com">//automatically passes the logger factory in to the constructor via dependency injection</span>
  <span class="kwd">public</span> <span class="typ">PaymentService</span><span class="pun">(</span><span class="typ">ILoggerFactory</span><span class="pln"> loggerFactory</span><span class="pun">)</span>
  <span class="pun">{</span>
    <span class="typ">Logger</span> <span class="pun">=</span><span class="pln"> loggerFactory</span><span class="pun">?.</span><span class="typ">CreateLogger</span><span class="pun">();</span>
    <span class="kwd">if</span><span class="pun">(</span><span class="typ">Logger</span> <span class="pun">==</span> <span class="kwd">null</span><span class="pun">)</span>
    <span class="pun">{</span>
      <span class="kwd">throw</span> <span class="kwd">new</span> <span class="typ">ArgumentNullException</span><span class="pun">(</span><span class="pln">nameof</span><span class="pun">(</span><span class="pln">loggerFactory</span><span class="pun">));</span>
    <span class="pun">}</span>
    <span class="typ">Logger</span><span class="pun">.</span><span class="typ">LogInformation</span><span class="pun">(</span><span class="str">"PaymentService created"</span><span class="pun">);</span>
  <span class="pun">}</span>
<span class="pun">}</span></pre>
<h3>7. WebSockets &amp; SignalR</h3>
<p>ASP.NET has first class support for <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/websockets" target="_blank" rel="noopener noreferrer">WebSockets</a>. This can be used to persist long running connections and communicate back and forth with the browser. SignalR is a full framework that is also available that makes it easy handle common scenarios.</p>
<h3>8. Cross-Site Request Forgery (CSRF) Protection</h3>
<p>Security is important. It is also one of those things that can be a lot of work to prevent certain types of attacks. CSRF is in referencing to hijacking users authenticated session to perform an action that they did not initiate.</p>
<p>For example, let’s pretend that you log in to your bank account and then navigate to a different website. If that other website could do a POST to your bank website to transfer funds, that would be a bad thing. It could potentially do that if your online session on the banking website is valid and the bank does not properly validate requests.</p>
<p>ASP.NET has a good framework that is available to prevent these types of attacks. It generates anti-forgery tokens.</p>
<h3>9. “Self hosted” Web Applications</h3>
<p>Sometimes you need to make a web application that will be deployed on to a desktop and not a server running IIS. Our free ASP.NET profiler, Prefix, is a perfect example of this. Its front end is all HTML that is loaded from an ASP.NET application running as a Windows Service.</p>
<p>You can create a self-hosted ASP.NET web application several different ways. In .NET 4.5 you could accomplish it by using Owin, Nancy, or WCF. For Prefix, we use ASP.NET Web API with Owin.</p>
<p>With ASP.NET Core, you can also use the standard Kestrel web server. One of the great advantages of .NET Core is that your web application is essentially a console application. IIS just sits in front of it as a reverse proxy. This means that you can also deploy your app only with kestrel for non-server based use cases, like Prefix.</p>
<h3>10. Action Filters</h3>
<p>One of the great features of ASP.NET is the support for extensible filters. This allows you to implement functionality that can be applied to an entire controller or action without modifying the action itself.</p>
<p>Filters are used to specify caching, error handling, authorization, or any custom logic you would like to implement.</p>
<pre class="prettyprint prettyprinted"><span class="kwd">using</span> <span class="typ">System</span><span class="pun">;</span>
<span class="kwd">using</span> <span class="typ">System</span><span class="pun">.</span><span class="typ">Web</span><span class="pun">.</span><span class="typ">Mvc</span><span class="pun">;</span>

<span class="kwd">namespace</span> <span class="typ">MvcApplication1</span><span class="pun">.</span><span class="typ">Controllers</span>
<span class="pun">{</span><span class="pln">
     </span><span class="kwd">public</span> <span class="kwd">class</span> <span class="typ">DataController</span> <span class="pun">:</span> <span class="typ">Controller</span><span class="pln">
     </span><span class="pun">{</span><span class="pln">
          </span><span class="pun">[</span><span class="typ">OutputCache</span><span class="pun">(</span><span class="typ">Duration</span><span class="pun">=</span><span class="lit">10</span><span class="pun">)]</span><span class="pln">
          </span><span class="kwd">public</span> <span class="kwd">string</span> <span class="typ">Index</span><span class="pun">()</span><span class="pln">
          </span><span class="pun">{</span><span class="pln">
               </span><span class="kwd">return</span> <span class="typ">DateTime</span><span class="pun">.</span><span class="typ">Now</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">(</span><span class="str">"T"</span><span class="pun">);</span><span class="pln">
          </span><span class="pun">}</span><span class="pln">
     </span><span class="pun">}</span>
<span class="pun">}</span></pre>
<h3>11. Extensible Output Caching</h3>
<p>This feature allows ASP.NET to cache the output generated by a page and serve this cached content for future requests. It stores the data that is not updated frequently and outputs that specific data from a cached location.</p>
<p>ASP.NET makes it easy to specify how long any request should be cached via common HTTP headers. It also has support for caching output within the memory on your web server itself. You can even use <a href="https://docs.microsoft.com/en-us/azure/redis-cache/cache-aspnet-output-cache-provider" target="_blank" rel="noopener noreferrer">Redis</a> or other providers to handle your output caching.</p>
<h3>12. Globalization and Localization</h3>
<p>ASP.NET makes it easy to localize dates, numbers, and the text within your web application. If you want your application to be used across the globe, localization will be very important to you.</p>
<p>ASP.NET enables customizing your application for multiple languages via resource files. These resource files are considered as the central repository where all texts are kept, and web pages can read this resource file and get labels populated. There are two types of resources:</p>
<ul>
<li>Local Resources – specific for a page (i.e., there will be local resource file for every page)</li>
<li>Global Resources – common for the whole website (i.e., one resource file accessed by all pages)</li>
</ul>
<h3>13. Swagger OpenAPI</h3>
<p>If you are creating API applications, you want to make sure you are using <a href="https://swagger.io/" target="_blank" rel="noopener noreferrer">Swagger</a>. It makes it easy to document and test your APIs.</p>
<p>ASP.NET has historically provided built-in functionality that is pretty similar for SOAP web services created with WCF. If you are using Web API or MVC for RESTful APIs, you definitely want to use Swagger.</p>
<h2>Conclusion</h2>
<p>ASP.NET Core has been a nice upgrade over previous versions. In this article, we highlighted some of the key features you should be aware of. Some are new, some are just key features of ASP.NET that have existed for a while.</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/13-asp-net-core-features/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Learn How to Create ASP.NET Core using Kendo UI from AngularJS</title>
		<link>https://topreviewhostingasp.net/learn-create-asp-net-core-using-kendo/</link>
					<comments>https://topreviewhostingasp.net/learn-create-asp-net-core-using-kendo/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 28 Nov 2017 04:37:20 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[angularjs]]></category>
		<category><![CDATA[angularjs tips]]></category>
		<category><![CDATA[asp.net core]]></category>
		<category><![CDATA[asp.net core tips]]></category>
		<category><![CDATA[asp.net core tutorial]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=854</guid>

					<description><![CDATA[Using cutting edge technology means overcoming that initial learning curve. Many times, we would like to just jump in and get started without starting from scratch. But as we all know the best meals are the ones that are well prepared, and rushing into things too quickly ends up making someone sick or leaving an [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Using cutting edge technology means overcoming that initial learning curve. Many times, we would like to just jump in and get started without starting from scratch. But as we all know the best meals are the ones that are well prepared, and rushing into things too quickly ends up making someone sick or leaving an entire meal in the trash.</p>
<p>In this article, we&#8217;ll find a happy medium—we&#8217;ll look at how to get started with Angular using ASP.NET Core by following a simple recipe with clearly defined ingredients. We&#8217;ll start by walking through all of the ingredients necessary to make a successful project. Next we&#8217;ll follow the recipe, learning where each ingredient fits. Finally, the application will be fully baked and ready to serve with all of its cutting edge goodness.</p>
<h2><strong>The Ingredients</strong></h2>
<p>Prepping the ingredients is the most important part of any recipe. Let&#8217;s look at what we&#8217;ll need to be successful and why each item is important to our project.</p>
<h3><strong>ASP.NET Core</strong></h3>
<p>ASP.NET Core 1.1 is a next generation architecture for building scale-able .NET web applications that run on any platform. Web API was consolidated with MVC in ASP.NET Core, making it a great platform to host endpoints for our application&#8217;s data.</p>
<p>ASP.NET Core will act as the server component for the application. The responsibility of ASP.NET Core is to power core business logic, interact with a database and provide application services like: email, authentication, and SMS to name a few.</p>
<h3><strong>Node Package Manager (npm)</strong></h3>
<p>Many of the ingredients for this application will come from the JavaScript community. The dependencies needed for frontend development are all easily managed through npm either from the Command Line Interface (CLI) or <a href="http://developer.telerik.com/featured/npm-for-the-visual-studio-developer/">from within Visual Studio</a>.</p>
<h3><strong>Angular, TypeScript &amp; Webpack</strong></h3>
<p>ASP.NET Core is capable of generating HTML for the client-side of the application on its own, but with the addition of Angular we can do so much more. Angular allows us to build rich interactive client-side applications using a component based architecture.</p>
<p>Using Angular requires some additional tooling since it relies heavily on TypeScript. To support Angular, we&#8217;ll be using Webpack to compile TypeScript, as well as to bundle and minify static resources.</p>
<h3><strong>dotnet CLI</strong></h3>
<p>Typically one would expect to use Visual Studio&#8217;s File &gt; New project template to begin a new project. However, because of the cross platform nature of ASP.NET Core development we&#8217;ll be using the dotnet CLI, a command line tool used to generate .NET project templates. Since the command line is ubiquitous, it suits ASP.NET Core development because it can be used anywhere.</p>
<h3><strong>Kendo UI for Angular</strong></h3>
<p>Like any great chef would tell you, presentation matters. We&#8217;ll use <a href="https://www.telerik.com/kendo-angular-ui/">Kendo UI for Angular</a> to finish out the look of the application. With beautiful UI controls, Kendo UI for Angular delivers high performance Angular UI components without any jQuery dependencies.</p>
<h2><strong>Prep Work</strong></h2>
<p>Let&#8217;s begin by putting all of our ingredients in place. Some quick prep work can make sure that we stay clear of any hangups. This is critical, as the last thing you want to do is waste hours of precious time troubleshooting problems that have already been addressed by using newer versions.</p>
<p>Before beginning your next project, make sure the following tools are installed and you&#8217;re running the latest bits. You can find everything you&#8217;ll need below:</p>
<ul>
<li><a href="https://www.microsoft.com/net/core#windowsvs2017">NET Core installers</a></li>
<li>
<pre class="lang:default decode:true">npm-$ npm install npm@latest -g</pre>
</li>
</ul>
<h2><strong>The Recipe</strong></h2>
<p>We&#8217;ll start by installing the Microsoft ASP.NET Core JavaScript Services. JavaScript Services is a set of technologies for ASP.NET Core developers built by the ASP.NET team. It provides infrastructure that you&#8217;ll find useful if you use Angular/React/Knockout/etc. on the client, if you build your client-side resources using Webpack, or if you otherwise want to execute JavaScript on the server at runtime. We&#8217;ll be using a JavaScript Services project template installed by the dotnet CLI. The template will take care of the Angular, TypeScript and Webpack dependencies for us.</p>
<p>From the command line install the JavaScript Services templates:</p>
<pre class="lang:default decode:true">dotnet new --install Microsoft.AspNetCore.SpaTemplates::*</pre>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-855" src="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_1.png" alt="" width="560" height="333" srcset="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_1.png 560w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_1-300x178.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_1-360x213.png 360w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_1-50x30.png 50w" sizes="(max-width: 560px) 100vw, 560px" /></p>
<p>Next, run the dotnet new angular command—using the angular parameter will specify the Angular template. The template will create a fully functioning starting point for your new application. Once the template has run, the dependencies will need to be restored by running dotnet restore. Once the dependencies are restored you can start up your new ASP.NET Core Single Page from within Visual Studio, or from the command line by calling dotnet run.</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-856" src="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_2.png" alt="" width="561" height="331" srcset="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_2.png 561w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_2-300x177.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_2-360x213.png 360w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_2-50x30.png 50w" sizes="(max-width: 561px) 100vw, 561px" /></p>
<p>Navigating to the app in our browser shows us the template in action.</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-857" src="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_3.png" alt="" width="559" height="331" srcset="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_3.png 559w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_3-300x178.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_3-360x213.png 360w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_3-50x30.png 50w" sizes="(max-width: 559px) 100vw, 559px" /></p>
<h3><strong>The Template</strong></h3>
<p>The JavaScript services template is pre-configured with Angular, TypeScript and Webpack. The application back-end is powered by ASP.NET Core, with Angular taking almost all responsibilities for the client-side. You&#8217;ll notice very little in the way of Views or .cshtml.</p>
<p>The client-side application source files are found in the ClientApp directory. Each folder under ClientApp contains the parts to a single component, a template (.html), component logic written in TypeScript (.ts), and optionally component styles (.css). These files will be compiled by Webpack prior to run-time. Webpack configuration files are included in the template. These configuration files define compilation, bundling and deployment to wwwroot.</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone wp-image-858" src="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_4.png" alt="" width="271" height="667" srcset="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_4.png 560w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_4-122x300.png 122w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_4-416x1024.png 416w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_4-20x50.png 20w" sizes="(max-width: 271px) 100vw, 271px" /></p>
<p>In ClientApp a few sample components demonstrate how to use Angular. The counter is a component that shows how to wire up a button that increments a counter. Also included is a fetch-data component, this component shows how to consume data from an API endpoint.</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-859" src="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_5.png" alt="" width="560" height="313" srcset="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_5.png 560w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_5-300x168.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_5-50x28.png 50w" sizes="(max-width: 560px) 100vw, 560px" /></p>
<h3><strong>Time to Bake</strong></h3>
<p>With the project scaffolding ready let&#8217;s modify some components. Working with components will get us familiar with the app&#8217;s structure and work-flow of the tooling. We&#8217;ll add robust UI components using Kendo UI for Angular to the existing app components.</p>
<p>First, Kendo UI works best with the latest version of Angular, so let&#8217;s update our Angular references:</p>
<pre class="lang:default decode:true">npm install --save @angular/animations@latest @angular/common@latest @angular/compiler@latest 
@angular/core@latest @angular/forms@latest @angular/http @angular/platform-browser@latest 
@angular/platform-browser-dynamic@latest @angular/platform-server@latest @angular/router@latest</pre>
<p>Next, we&#8217;ll add the Kendo UI dependencies to the project. Kendo UI for Angular is packaged and distributed as a set of discrete, scoped npm packages, which are available from <a href="https://www.npmjs.com/search?q=scope:progress&amp;page=1&amp;ranking=optimal">npm</a>.</p>
<p>It&#8217;s time to add Kendo UI components to the project. We&#8217;ll add the Kendo UI Button and Grid components from the command line using npm.</p>
<pre class="lang:default decode:true">npm install --save @progress/kendo-angular-buttons @progress/kendo-angular-l10n @angular/animations</pre>
<pre class="lang:default decode:true">npm install --save @progress/kendo-angular-grid @progress/kendo-angular-dropdowns @progress/kendo-angular-
inputs @progress/kendo-angular-dateinputs @progress/kendo-data-query @progress/kendo-angular-intl 
@progress/kendo-angular-l10n @progress/kendo-drawing @progress/kendo-angular-excel-export 
@angular/animations</pre>
<p>Next we&#8217;ll import the component directives into our source code. Because Kendo UI for Angular uses Ahead-of-Time Compilation (AoT), we&#8217;ll declare the modules in the app&#8217;s shared module. Open ClientApp/App/app.module.shared.ts and add the following declarations:</p>
<pre class="lang:default decode:true">...;
import { ButtonsModule } from '@progress/kendo-angular-buttons';
import { GridModule } from '@progress/kendo-angular-grid'; 

imports: [     
     ButtonsModule,
     GridModule, ...,</pre>
<p>Kendo UI just wouldn&#8217;t be complete without some nice styling. Let&#8217;s add the default Kendo UI theme to our project via npm.</p>
<pre class="lang:default decode:true">npm install -S @progress/kendo-theme-default@2.38.1</pre>
<p>The npm package deploys to our node_modules folder, however we&#8217;ll need the CSS file referenced in our project. To do this we&#8217;ll add a reference in webpack.vendor.config.js to the CSS that our app requires. Webpack is pre-configured to bundle CSS files into a single vendor.css file which is output to the wwwroot folder for deployment.</p>
<pre class="lang:default decode:true">entry: { vendor: [ ..., '@progress/kendo-theme-default/dist/all.css',</pre>
<p>Once the reference is added, we&#8217;ll need to run Webpack to rebuild vendor.css.</p>
<p>In package.json we&#8217;ll add the Webpack command for rebuilding vendor dependencies for the application.</p>
<pre class="lang:default decode:true">"scripts": {
  "test": "karma start ClientApp/test/karma.conf.js",
  "webpack:vendor": "webpack --config webpack.config.vendor.js",
  ...</pre>
<p>To run the script from npm execute npm run webpack:vendor from the command line.</p>
<p>Now that Kendo UI for Angular is installed, let&#8217;s replace a few components that are part of the samples. One of benefits of Kendo UI is that a single theme controls the style of all Kendo UI components, even simple controls like the button. Let&#8217;s modify the sample to use a Kendo UI button.</p>
<p>In ClientApp/app/components/counter/counter.component.html you&#8217;ll find a button that increments a counter. Replace the standard button with a Kendo UI Button.</p>
<pre class="lang:default decode:true">&lt;button kendoButton (click)="incrementCounter()" [primary]="true"&gt;Increment KUI&lt;/button&gt;</pre>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-860" src="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_6.png" alt="" width="560" height="330" srcset="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_6.png 560w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_6-300x177.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_6-360x213.png 360w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_6-50x29.png 50w" sizes="(max-width: 560px) 100vw, 560px" /></p>
<p>Next, we&#8217;ll modify the fetch-data sample by utilizing the Kendo UI grid. Since Kendo UI has robust data binding capabilities this will be an easy task. In ClientApp/app/components/fetchdata/fetchdata.component.html a table has been explicitly defined using Angular templates.</p>
<pre class="lang:default decode:true">&lt;table class='table' *ngIf="forecasts"&gt;
  &lt;thead&gt;
    &lt;tr&gt;
       &lt;th&gt;Date&lt;/th&gt;
       &lt;th&gt;Temp. (C)&lt;/th&gt;
       &lt;th&gt;Temp. (F)&lt;/th&gt;
       &lt;th&gt;Summary&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt; 

  &lt;tr *ngFor="let forecast of forecasts"&gt;
    &lt;td&gt;{{ forecast.dateFormatted }}&lt;/td&gt;
    &lt;td&gt;{{ forecast.temperatureC }}&lt;/td&gt;
    &lt;td&gt;{{ forecast.temperatureF }}&lt;/td&gt;
    &lt;td&gt;{{ forecast.summary }}&lt;/td&gt;
  &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;</pre>
<p>We can replace the entire template with a single kendo-grid component. At the absolute minimum we can bind the data property and the grid will generate the columns and headings.</p>
<pre class="lang:default decode:true">&lt;kendo-grid [data]="forecasts"&gt;&lt;/kendo-grid&gt;</pre>
<p>To further enhance the UI we can customize each column.</p>
<pre class="lang:default decode:true">&lt;kendo-grid [data]="forecasts"&gt;
  &lt;kendo-grid-column field="dateFormatted" title="Date"&gt;&lt;/kendo-grid-column&gt;
  &lt;kendo-grid-column field="temperatureC" title="Temp. (C)"width="150"&gt;&lt;/kendo-grid-column&gt;
  &lt;kendo-grid-column field="temperatureF" title="Temp. (F)"width="150"&gt;
  &lt;/kendo-grid-column&gt; &lt;kendo-grid-column field="summary"title="Summary"&gt;&lt;/kendo-grid-column&gt;
&lt;/kendo-grid&gt;</pre>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-861" src="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_7.png" alt="" width="560" height="265" srcset="https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_7.png 560w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_7-300x142.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2017/11/image_7-50x24.png 50w" sizes="(max-width: 560px) 100vw, 560px" /></p>
<h2><strong>Time To Serve</strong></h2>
<p>The ASP.NET Core JavaScript Services dotnet CLI template, combined with Kendo UI for Angular, provide a solid platform for dishing out modern web applications. Using the JavaScript Services generator makes short work of starting a new Angular project. It comes with everything needed for client and server side development and excellent samples to get you started. The growing library of <a href="https://www.telerik.com/kendo-angular-ui/components/">Kendo UI for Angular components</a> with world class features like data binding, internationalization and themes make a full course meal ready to serve. The completed starter project can be viewed on GitHub. Please remember this app requires the scoped Progress NPM registry to restore dependencies.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/learn-create-asp-net-core-using-kendo/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>What Changed on ASP.NET Core Logging?</title>
		<link>https://topreviewhostingasp.net/changed-asp-net-core-logging/</link>
					<comments>https://topreviewhostingasp.net/changed-asp-net-core-logging/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 08 Aug 2017 03:46:58 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp.net core]]></category>
		<category><![CDATA[asp.net core logging]]></category>
		<category><![CDATA[asp.net core tips]]></category>
		<category><![CDATA[asp.net core tutorial]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=722</guid>

					<description><![CDATA[If you are getting started with ASP.NET Core, you are probably wondering what has changed with logging. In short, the answer is both nothing and everything. The common logging libraries you have always used with .NET still work. Microsoft does provide its own interface for logging with .NET Core and it uses it for .NET [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>If you are getting started with ASP.NET Core, you are probably wondering what has changed with logging. In short, the answer is both nothing and everything. The common logging libraries you have always used with .NET still work. Microsoft does provide its own interface for logging with .NET Core and it uses it for .NET internals.</p>
<p>In this article, we will discuss using traditional .NET logging frameworks and some new changes in ASP.NET Core and .NET Core.</p>
<h2><strong>Third Party Logging Libraries for ASP.NET Core</strong></h2>
<p>The three most popular libraries for logging support .NET Core. If you are converting your application from ASP.NET to Core, you won’t have to make any code changes. Just upgrade to the latest NuGet packages. Although you may want to move your logging config to its own file since your web.config will now be gone in favor of the new appsetting.json.</p>
<h3><strong>Log4net</strong></h3>
<p>When .NET Core 1.0 launched, log4net had not been ported to support .NET Core (it has since). Their long delay in support for .NET Core is just one example of where log4net has been slow to keep up with new trends and features in logging frameworks. It may be the most popular framework, but NLog and Serilog are on the leading edge.</p>
<h3><strong>NLog</strong></h3>
<p>NLog has quickly become the second most popular framework for .NET logging. They had support for .NET Core when v1.0 came out and continue to rapidly add new features. NLog even works across Xamarin, Mono, and other runtimes. NLog is a safe bet if you are thinking about selecting a new logging framework for ASP.NET Core.</p>
<h3><strong>Serilog</strong></h3>
<p>Serilog was created to bring more structure to logging variables and objects. It has become very popular and continues to grow. It supports all the common logging features you would support, like configurable output targets and is much more modern than log4net.</p>
<h2><strong>Built-in ASP.NET Core Logging</strong></h2>
<p>ASP.NET Core now has a built-in logging framework that you can use. It is not as feature-rich as third party libraries. Let me give you a quick and dirty tour of the new ILoggerFactory that is built into .NET Core.</p>
<p>If you have created a brand new ASP.NET Core web application, you have likely seen these loggerFactory lines of code in your Startup class.</p>
<pre class="lang:default decode:true">public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

{

                loggerFactory.AddConsole(Configuration.GetSection("Logging"));

                loggerFactory.AddDebug();

                //removed the rest of the lines

}</pre>
<p>You will also find some logging settings in the default appsettings.json.</p>
<pre class="lang:default decode:true ">{

  "Logging": {

    "IncludeScopes": false,

    "LogLevel": {

      "Default": "Debug",

      "System": "Information",

      "Microsoft": "Information"

    }

  }

}</pre>
<p>If you run the default app, you can see it write out some details in the debug window in Visual Studio that shows when MVC actions happen and how long they take.</p>
<pre class="lang:default decode:true">Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request starting HTTP/1.1 GET http://localhost:29564/

Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executing action method ASPNetCore.Controllers.HomeController.Index (CoreSharedLib) with arguments () - ModelState is Valid

Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewResultExecutor: Information: Executing ViewResult, running view at path /Views/Home/Index.cshtml.

Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action ASPNetCore.Controllers.HomeController.Index (CoreSharedLib) in 26.8787ms

Microsoft.AspNetCore.Hosting.Internal.WebHost: Information: Request finished in 60.9946ms 200 text/html; charset=utf-8</pre>
<p><strong>Disabling or Reducing the Built-in .NET Core Logging Messages</strong></p>
<p>If you want to disable these built-in messages all together, you can simply remove the AddConsole() and AddDebug() methods. If you want to reduce how much they log then you can adjust their log levels.</p>
<p>For AddConsole() you will notice that you can pass into it Configuration.GetSection(“Logging”) which pulls the log levels from your appsettings.json configuration, or other custom providers you may be using. By setting a log level to “None” it will disable it. Just above is an example of an appsettings.json that I am referring to here.</p>
<p>AddDebug(), for some reason, does not support the same configuration-based initialization. You can instead specify a log level in your code directly, which I guess is fine since debug is really just meant for use in development and wouldn’t need to be configured differently in QA or production.</p>
<p>These log levels are all supported: None, Trace, Debug, Information, Warning, Error, Critical.</p>
<h3><strong>How to Redirect Internal .NET Core Logging to NLog or Serilog</strong></h3>
<p>You don’t have to use the built-in logging. You can – and I would probably recommend this – use NLog, Serilog, or log4net. If you want to capture the internal logging coming from .NET Core and send it to your separate logging framework, you can. You just have to configure it!</p>
<p>For NLog/Serilog, all you have to do is add one line of code in your Startup Configure() method. This adds a special logging provider for NLog/Serilog that redirects the messages.</p>
<pre class="lang:default decode:true">loggerFactory.AddNLog();

or

loggerFactory.AddSerilog();</pre>
<p><strong>Using the New ILogger and ILoggerFactory in Your Code</strong></p>
<p>Being able to see all of the .NET Core internal logging is cool, but what about my own logging?</p>
<p>One of the big additions to .NET Core is <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection">built-in dependency injection</a>. You can use the ILoggerFactory via dependency injection in your own code as shown below.</p>
<pre class="lang:default decode:true">public class HomeController : Controller

 {

        ILoggerFactory _loggerFactory;

 

        public HomeController(ILoggerFactory loggerFactory)

        {

            _loggerFactory = loggerFactory;

        }

        

        public string Ping()

        {

            var logger = _loggerFactory.CreateLogger("LoggerCategory");

            logger.LogInformation("Calling the ping action");

 

            return "pong";

        }

}</pre>
<p>Now, when I execute this code I see similar logging as I showed before, but I also see my extra logging line.</p>
<pre class="lang:default decode:true ">LoggerCategory: Information: Calling the ping action</pre>
<p>So, you can see how easy it is to use the new built-in ASP.NET Core logging via ILoggerFactory and dependency injection.</p>
<p>The new logging API currently supports the following built-in providers:</p>
<ul>
<li>Console</li>
<li>Debug</li>
<li>EventSource</li>
<li>EventLog</li>
<li>TraceSource</li>
<li>Azure App Service</li>
</ul>
<p>So if you have followed along this far, I’m sure you are wondering about how to make the built-in logging write to a file on disk. You have to use a 3rd party extension to do it.</p>
<h3><strong>How to Enable ASP.NET Core Logging to a File</strong></h3>
<p>Since .NET Core does not support logging to file directly, you will want to use an extension from NLog or Serilog that can route .NET Core logging to those libraries. Then you can take full advantage of their features. I am going to assume that they left a File writer option out because of the complexity it creates. It opens up a huge set of requirements around max file sizes, rolling files, deleting files, file writing performance, etc.</p>
<p>Read more: <a href="https://github.com/NLog/NLog.Extensions.Logging">NLog Extensions</a></p>
<p>Read more: <a href="https://github.com/serilog/serilog-extensions-logging-file">Serilog.Extensions.Logging.File</a></p>
<p>Using Serilog as an example, all you have to do is install their Extensions NuGet package and, with one line of code, do an AddFile in your Startup class. Now you have a log file on disk!</p>
<pre class="lang:default decode:true ">public void Configure(IApplicationBuilder app,

                          IHostingEnvironment env,

                          ILoggerFactory loggerFactory)

{

        loggerFactory.AddFile("Logs/mylog-{Date}.txt");

        //other code removed for example

}</pre>
<h3><strong>Limitations of ASP.NET Core Logging Configuration</strong></h3>
<p>The built-in logging doesn’t provide much for configuration. All you can do is configure the logging level (Debug, Warning, Error, etc) by logging category name.</p>
<h2><strong>Viewing Your Application Errors and Logs</strong></h2>
<h3><strong>How to View Your Logs While Writing and Testing Code</strong></h3>
<p>You can use Prefix, Stackify’s free ASP.NET Profiler, to view all of your logging statements during development. Prefix can show you all of your logs, errors, SQL queries, HTTP calls, and much more.</p>
<p style="text-align: center;"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-723" src="https://topreviewhostingasp.net/wp-content/uploads/2017/08/image_1.png" alt="" width="1187" height="697" srcset="https://topreviewhostingasp.net/wp-content/uploads/2017/08/image_1.png 1187w, https://topreviewhostingasp.net/wp-content/uploads/2017/08/image_1-300x176.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2017/08/image_1-768x451.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2017/08/image_1-1024x601.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2017/08/image_1-50x29.png 50w" sizes="(max-width: 1187px) 100vw, 1187px" /></p>
<h3><strong>How to View Your Logs in QA or Production</strong></h3>
<p>If you only send your logging to a file on disk, it can be pretty hard to get a lot of use out of them once you deploy your app to a server somewhere. You really need to centralize your logs with a log management system. This gives you the ability to do full-text searching across all of your logs for all applications and servers from one place.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/changed-asp-net-core-logging/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
