<?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 tutorial &#8211; ASP.NET Hosting Reviews and Guides</title>
	<atom:link href="https://topreviewhostingasp.net/tag/asp-net-tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>https://topreviewhostingasp.net</link>
	<description>ASP.NET Hosting &#124; Reviews &#124; Tips &#38; Tutorial</description>
	<lastBuildDate>Wed, 28 Apr 2021 05:35:42 +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 tutorial &#8211; ASP.NET Hosting Reviews and Guides</title>
	<link>https://topreviewhostingasp.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Know Further About ModelState in ASP.NET 5.0</title>
		<link>https://topreviewhostingasp.net/know-further-about-modelstate-in-asp-net-5-0/</link>
					<comments>https://topreviewhostingasp.net/know-further-about-modelstate-in-asp-net-5-0/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Wed, 28 Apr 2021 05:21:39 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net 5]]></category>
		<category><![CDATA[asp net 5 modelstate]]></category>
		<category><![CDATA[asp net 5 tips]]></category>
		<category><![CDATA[asp net 5 tutorial]]></category>
		<category><![CDATA[asp.net tips]]></category>
		<category><![CDATA[asp.net tutorial]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2956</guid>

					<description><![CDATA[In this post, we&#8217;re going to explain what the ModelState is, and what it is used for. We&#8217;ll also show how to use it to validate our POSTed inputs, and do simple custom validation. Here we go! What is the ModelState? In short, the ModelState is a collection of name and value pairs that are submitted to the server [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In this post, we&#8217;re going to explain what the <code>ModelState</code> is, and what it is used for. We&#8217;ll also show how to use it to validate our POSTed inputs, and do simple custom validation. Here we go!</p>



<h2 class="wp-block-heading" id="what-is-the-modelstate">What is the ModelState?</h2>



<p>In short, the <code>ModelState</code> is a collection of name and value pairs that are submitted to the server during a POST. It also contains error messages about each name-value pair, if any are found.</p>



<p><code>ModelState</code> is a property of a <code>Controller</code> instance, and can be accessed from any class that inherits from <a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controller?view=aspnetcore-5.0">Microsoft.AspNetCore.Mvc.Controller</a>.</p>



<p>The <code>ModelState</code> has two purposes: to store and submit POSTed name-value pairs, and to store the validation errors associated with each value.</p>



<p>All right, enough of the boring explanation. It&#8217;s code time!</p>



<h2 class="wp-block-heading" id="the-sample-project">The Sample Project</h2>



<p>You can use <a href="https://github.com/exceptionnotfound/ModelStateAspNet5Demo">sample project on Github</a>.</p>



<h2 class="wp-block-heading" id="setup">Setup</h2>



<p>Let&#8217;s start writing the code we need to demonstrate how the <code>ModelState</code> works in ASP.NET 5 MVC. We will begin by creating a straightforward view model, <code>AddMovieVM</code>:</p>



<pre class="wp-block-code"><code>namespace ModelStateCoreDemo.ViewModels
{
    public class AddMovieVM
    {
        public string Title { get; set; }
        public DateTime ReleaseDate { get; set; }
        public int RuntimeMinutes { get; set; }
    }
}</code></pre>



<p>We will also create a corresponding <code>Add.cshtml</code> view in the folder Views/Movie:</p>



<pre class="wp-block-code"><code>@model ModelStateCoreDemo.ViewModels.AddMovieVM

&lt;h2&gt;Add Movie&lt;/h2&gt;

&lt;form asp-action="AddPost" asp-controller="Movie" method="post"&gt;
    &lt;div&gt;
        &lt;div&gt;
            &lt;label asp-for="Title"&gt;&lt;/label&gt;
            &lt;input type="text" asp-for="Title" /&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label asp-for="Description"&gt;&lt;/label&gt;
            &lt;input type="text" asp-for="Description" /&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label asp-for="ReleaseDate"&gt;&lt;/label&gt;
            &lt;input type="date" asp-for="ReleaseDate" /&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label asp-for="RuntimeMinutes"&gt;&lt;/label&gt;
            &lt;input type="number" asp-for="RuntimeMinutes" /&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;input type="submit" value="Save" /&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/form&gt; </code></pre>



<p>Lastly, we create a <code>MovieController</code> class with two actions:</p>



<pre class="wp-block-code"><code>using Microsoft.AspNetCore.Mvc;
using ModelStateCoreDemo.ViewModels;

public class MovieController : Controller
{
    [HttpGet("movies/add")]
    public IActionResult Add()
    {
        AddMovieVM model = new AddMovieVM();
        return View(model);
    }

    [HttpPost("movies/add/post")]
    public IActionResult AddPost(AddMovieVM model)
    {
        if(!ModelState.IsValid)
        {
            return View("Add", model);
        }

        return RedirectToAction("Index");
    }
}</code></pre>



<p>When we submit our Add form to the POST action, all of the values we entered on the view will show up in the correct properties in the <code>AddMovieVM</code> instance. But how did they get there?</p>



<h2 class="wp-block-heading" id="peeking-into-the-modelstate">Peeking Into the ModelState</h2>



<p>Let&#8217;s take a peek at the rendered HTML for the Add page:</p>



<pre class="wp-block-code"><code>&lt;h2&gt;Add Movie&lt;/h2&gt;

&lt;form method="post" action="/movies/add"&gt;
    &lt;div&gt;
        &lt;div&gt;
            &lt;label for="Title"&gt;Title&lt;/label&gt;
            &lt;input type="text" 
                   id="Title" 
                   name="Title" 
                   value=""&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label for="ReleaseDate"&gt;ReleaseDate&lt;/label&gt;
            &lt;input type="date" 
                   id="ReleaseDate" 
                   name="ReleaseDate" 
                   value="0001-01-01"&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label for="RuntimeMinutes"&gt;RuntimeMinutes&lt;/label&gt;
            &lt;input type="number" 
                   id="RuntimeMinutes" 
                   name="RuntimeMinutes" 
                   value="0"&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;input type="submit" value="Save"&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/form&gt; </code></pre>



<p>When this page is POSTed to the server, all values in <code>&lt;input&gt;</code> tags will be submitted as name-value pairs.</p>



<p>At the point when ASP.NET 5 MVC receives a POST action, it takes all of the name-value pairs and adds them as individual instances of <code>ModelStateEntry</code> to an instance of <code>ModelStateDictionary</code>. Both <a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.modelbinding.modelstateentry?view=aspnetcore-5.0">ModelStateEntry</a> and <a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.modelbinding.modelstatedictionary?view=aspnetcore-5.0">ModelStateDictionary</a> have pages in Microsoft&#8217;s documentation.</p>



<p>In Visual Studio, we can use the Locals window to show what exactly this looks like:</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="907" height="486" class="wp-image-2957" src="https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_1.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_1.png 907w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_1-300x161.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_1-768x412.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_1-50x27.png 50w" sizes="(max-width: 907px) 100vw, 907px" /></figure>



<p>We can see from the <code>Values</code> property of the <code>ModelState</code> that there are three name-value pairs: one each for <code>Title</code>, <code>ReleaseDate</code>, and <code>RuntimeMinutes</code>.</p>



<p>Each of the items in the results for the <code>Values</code> is of type <code>ModelStateEntry</code>. But what exactly is this?</p>



<h2 class="wp-block-heading" id="what-s-in-the-modelstateentry">What&#8217;s In the ModelStateEntry?</h2>



<p>Here&#8217;s what those same input values look like, taken from the same debugger session.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="907" height="483" class="wp-image-2958" src="https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_2.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_2.png 907w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_2-300x160.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_2-768x409.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_2-50x27.png 50w" sizes="(max-width: 907px) 100vw, 907px" /></figure>



<p>You can see that each <code>ModelStateEntry</code> contains properties like <code>RawValue</code>, which holds the raw value that was submitted, and <code>Key</code>, which holds the name of said value. ASP.NET 5 MVC creates all of these instances for us automatically when we submit a POST action that has associated data. ASP.NET 5 MVC is therefore making what was a complicated set of data into easier-to-use instances.</p>



<p>There are two important functions of the <code>ModelState</code> that we still need to discuss: errors and validation.</p>



<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://www.asphostportal.com"><img decoding="async" width="300" height="271" class="wp-image-2953 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2021/04/ahp-banner-aspnet-mvc-01.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/04/ahp-banner-aspnet-mvc-01.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/ahp-banner-aspnet-mvc-01-50x45.png 50w" sizes="(max-width: 300px) 100vw, 300px" /></a></figure>
</div>



<h2 class="wp-block-heading" id="validation-errors-in-the-modelstate">Validation Errors in the ModelState</h2>



<p>Let&#8217;s make a quick modification to our <code>AddMovieVM</code> class so that we are now implementing validation on its fields.</p>



<pre class="wp-block-code"><code>public class AddMovieVM
{
    [Required(ErrorMessage = "The Title cannot be blank.")]
    [DisplayName("Title: ")]
    public string Title { get; set; }

    [DisplayName("Release Date: ")]
    public DateTime ReleaseDate { get; set; }

    [Required(ErrorMessage = "The Runtime Minutes cannot be blank.")]
    [Range(1, int.MaxValue, 
           ErrorMessage = "The Runtime Minutes must be greater than 0.")]
    [DisplayName("Runtime Minutes: ")]
    public int RuntimeMinutes { get; set; }
}
</code></pre>



<p>We have added validation to these fields using the <code>[Required]</code> and <code>[Range]</code> validation attributes, as well as specifying the name to use in <code>&lt;label&gt;</code> tags with the <code>[DisplayName]</code> attribute. If the <code>Title</code>, the <code>Description</code>, or the <code>RuntimeMinutes</code> field fails validation, we need to show an error message.</p>



<p>To do that, we must make some changes to our view; we will need to add a <code>&lt;span&gt;</code> tag with the property <code>asp-validation-for</code> set for each input:</p>



<pre class="wp-block-code"><code>@model ModelStateCoreDemo.ViewModels.AddMovieVM

&lt;h2&gt;Add Movie&lt;/h2&gt;

&lt;form asp-action="AddPost" asp-controller="Movie" method="post"&gt;
    &lt;div&gt;
        &lt;div&gt;
            &lt;label asp-for="Title"&gt;&lt;/label&gt;
            &lt;input type="text" asp-for="Title"/&gt;
            &lt;span asp-validation-for="Title"&gt;&lt;/span&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label asp-for="ReleaseDate"&gt;&lt;/label&gt;
            &lt;input type="date" asp-for="ReleaseDate" /&gt;
            &lt;span asp-validation-for="ReleaseDate"&gt;&lt;/span&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label asp-for="RuntimeMinutes"&gt;&lt;/label&gt;
            &lt;input type="number" asp-for="RuntimeMinutes" /&gt;
            &lt;span asp-validation-for="RuntimeMinutes"&gt;&lt;/span&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;input type="submit" value="Save"/&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/form&gt; </code></pre>



<p>The <code>asp-validation-for</code> property will render the validation errors message in the specified <code>&lt;span&gt;</code> element, with some default CSS already applied.</p>



<p>Let&#8217;s take a look at what happens to our collection of <code>ModelStateEntry</code> instances when an invalid object is submitted to the server:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="906" height="484" class="wp-image-2959" src="https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_3.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_3.png 906w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_3-300x160.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_3-768x410.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_3-50x27.png 50w" sizes="(max-width: 906px) 100vw, 906px" /></figure>



<p>Note that the <code>IsValid</code> property of the <code>ModelState</code> is now <code>false</code>, and the <code>ValidationState</code> property of the invalid <code>ModelStateEntry</code> instances is now <code>Invalid</code>.</p>



<p>When ASP.NET 5 MVC creates the model state for the submitted values, it also iterates through each property in the view model and validates said property using the attributes associated to that property. In certain cases, attributes are implicitly evaluated (in our particular case, <code>ReleaseDate</code> has an implicit <code>[Required]</code> attribute because its type is <code>DateTime</code> and therefore cannot be blank).</p>



<p>If any errors are found, they are added to the <code>Errors</code> property of each <code>ModelStateEntry</code>. There is also a property <code>ErrorCount</code> on the <code>ModelState</code> that shows all errors found during the validation. If errors exist for a given POSTed value, the <code>ValidationState</code> of that property becomes <code>Invalid</code>.</p>



<p>In this case, because at least one of the <code>ModelStateEntry</code> instances has an error, the <code>IsValid</code> property of <code>ModelState</code> is now <code>false</code>.</p>



<p>What all of this means is merely this: we are using ASP.NET 5 MVC the way it was intended to be used. The <code>ModelState</code> stores submitted values, calculates the errors associated with each, and allows our controllers to check for said errors as well as the <code>IsValid</code> flag. In many scenarios, this is all we need, and all of it happens behind the scenes!</p>



<h2 class="wp-block-heading" id="custom-validation">Custom Validation</h2>



<p>There are times when we need more complex validation than ASP.NET 5 provides natively.</p>



<p>Let&#8217;s pretend that we now need a new field, <code>Description</code>, for each movie. Let&#8217;s also pretend that in addition to not allowing <code>Description</code> to be blank, it also cannot be exactly the same as the <code>Title</code>.</p>



<p>First, we can add the <code>Description</code> field to the view model:</p>



<pre class="wp-block-code"><code>public class AddMovieVM
{
    [Required(ErrorMessage = "The Title cannot be blank.")]
    [DisplayName("Title: ")]
    public string Title { get; set; }

    [Required(ErrorMessage = "The Description cannot be blank.")]
    [DisplayName("Description: ")]
    public string Description { get; set; }

    [DisplayName("Release Date: ")]
    public DateTime ReleaseDate { get; set; }

    [Required(ErrorMessage = "The Runtime Minutes cannot be blank.")]
    [Range(1, int.MaxValue, 
           ErrorMessage = "The Runtime Minutes must be greater than 0.")]
    [DisplayName("Runtime Minutes: ")]
    public int RuntimeMinutes { get; set; }
}</code></pre>



<p>We can also add it to the view:</p>



<pre class="wp-block-code"><code>@model ModelStateCoreDemo.ViewModels.AddMovieVM

&lt;h2&gt;Add Movie&lt;/h2&gt;

&lt;form asp-action="AddPost" asp-controller="Movie" method="post"&gt;
    &lt;div&gt;
        &lt;div&gt;
            &lt;label asp-for="Title"&gt;&lt;/label&gt;
            &lt;input type="text" asp-for="Title" /&gt;
            &lt;span asp-validation-for="Title"&gt;&lt;/span&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label asp-for="Description"&gt;&lt;/label&gt;
            &lt;input type="text" asp-for="Description" /&gt;
            &lt;span asp-validation-for="Description"&gt;&lt;/span&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label asp-for="ReleaseDate"&gt;&lt;/label&gt;
            &lt;input type="date" asp-for="ReleaseDate" /&gt;
            &lt;span asp-validation-for="ReleaseDate"&gt;&lt;/span&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label asp-for="RuntimeMinutes"&gt;&lt;/label&gt;
            &lt;input type="number" asp-for="RuntimeMinutes" /&gt;
            &lt;span asp-validation-for="RuntimeMinutes"&gt;&lt;/span&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;input type="submit" value="Save" /&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/form&gt; </code></pre>



<p>When the form is POSTed, we can do custom validation in our controllers. To check that the <code>Description</code> does not exactly match the <code>Title</code>, we can modify the POST action on our <code>MovieController</code> class like so:</p>



<pre class="wp-block-code"><code>public class MovieController : Controller
{
    //... Other methods

    [HttpPost("movies/add/post")]
    public IActionResult AddPost(AddMovieVM model)
    {
        if(model.Title == model.Description)
        {
            ModelState.AddModelError("description", 
                "The Description cannot exactly match the Title.");
        }

        if(!ModelState.IsValid)
        {
            return View("Add", model);
        }

        return RedirectToAction("Index");
    }
}</code></pre>



<p>Which will show the error next to the input for <code>Description</code>:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="626" height="240" class="wp-image-2960 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_4.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_4.png 626w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_4-300x115.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2021/04/image_4-50x19.png 50w" sizes="(max-width: 626px) 100vw, 626px" /></figure>



<h2 class="wp-block-heading" id="summary">Summary</h2>



<p>In ASP.NET 5 MVC, the <code>ModelState</code> property of a controller represents the submitted values, and validation errors in those values if such errors exist, during a POST action.</p>



<p>During the POST, the values submitted can be validated, and the validation process uses attributes defined by .NET like <code>[Required]</code> and <code>[Range]</code>. We can do simple custom validation server-side by modifying our controllers.</p>



<p>On views, the <code>asp-validation-for</code> property on a <code>&lt;span&gt;</code> element will show an error message for a specific property of the view model.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/know-further-about-modelstate-in-asp-net-5-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Using ASP.NET Core to Find Controllers in Your App</title>
		<link>https://topreviewhostingasp.net/using-asp-net-core-to-find-controllers-in-your-app/</link>
					<comments>https://topreviewhostingasp.net/using-asp-net-core-to-find-controllers-in-your-app/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 16 Mar 2021 03:57:20 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net controller]]></category>
		<category><![CDATA[ASP.NET Hosting]]></category>
		<category><![CDATA[asp.net tips]]></category>
		<category><![CDATA[asp.net tutorial]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2942</guid>

					<description><![CDATA[In this post I describe application parts and how ASP.NET Core uses them to find the controllers in your app. I then show how you can retrieve the list at runtime for debugging purposes. Debugging a missing controller A while ago I was converting an ASP.NET application to ASP.NET Core. The solution had many class [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In this post I describe application parts and how ASP.NET Core uses them to find the controllers in your app. I then show how you can retrieve the list at runtime for debugging purposes.</p>



<h2 class="wp-block-heading">Debugging a missing controller</h2>



<p>A while ago I was converting an ASP.NET application to ASP.NET Core. The solution had many class library projects, where each project represented a module or vertical slice of the application. These modules contained everything for that feature: the database code, the domain, and the Web API controllers. There was then a &#8220;top level&#8221; application that referenced all these modules and served the requests.</p>



<p>As the whole solution was based on Katana/Owin and used Web API controllers exclusively, it wasn&#8217;t too hard to convert it to ASP.NET Core. But, of course, there were bugs in the conversion process. One thing that had me stumped for a while was why the controllers from some of the modules didn&#8217;t seem to be working. All of the requests to certain modules were returning 404s.</p>



<p>There were a few possibilities in my mind for what was going wrong:</p>



<ol>
<li>There was a routing issue, so requests meant for the controllers were not reaching them</li>
<li>There was a problem with the controllers themselves, meaning they were generating 404s</li>
<li>The ASP.NET Core app wasn&#8217;t aware of the controllers in the module at all.</li>
</ol>



<p>My gut feeling was the problem was either 1 or 3, but I needed a way to check. The solution I present in this post let me rule out point 3, by listing all the <code>ApplicationPart</code>s and controllers the app was aware of.</p>



<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://www.asphostportal.com"><img loading="lazy" decoding="async" width="300" height="271" class="wp-image-2584 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2018/11/ahp-banner-aspnet-01.png" alt="" 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></figure>
</div>



<h2 class="wp-block-heading">What are application parts?</h2>



<p>Application Parts allow you to share the same resources (controllers, Razor Pages etc) between multiple apps. If you&#8217;re familiar with <a href="https://docs.microsoft.com/en-us/aspnet/core/razor-pages/ui-class?view=aspnetcore-3.1&amp;tabs=visual-studio">Razor Class Libraries</a>, then think of application parts as being the abstraction behind it.</p>



<p>One application part implementation is <a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.applicationparts.assemblypart?view=aspnetcore-3.1">an <code>AssemblyPart</code></a> which is an application part associated with an assembly. This is the situation I had in the app I described previously &#8211; each of the module projects was compiled into a separate <code>Assembly</code>, and then added to the application as application parts.</p>



<p>You can add application parts in <code>ConfigureServices</code> when you configure MVC. The current assembly is added automatically, but you can add additional application parts too. The example below adds the assembly that contains <code>TestController</code> (which resides in a different project) as an application part.</p>



<pre class="wp-block-code"><code>public void ConfigureServices(IServiceCollection services)
{
    services
        .AddControllers()
        .AddApplicationPart(typeof(TestController).Assembly);
}</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>Note that in ASP.NET Core 3.x, when you compile an assembly that references ASP.NET Core, </em><a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.applicationparts.applicationpartattribute?view=aspnetcore-3.1">an assembly attribute is added to the output, <code>[ApplicationPart]</code></a><em>. ASP.NET Core 3.x apps look for this attribute on referenced assemblies and registers them as application parts automatically, so the code above isn&#8217;t necessary.</em></p>
</blockquote>



<p>We&#8217;ve covered how you register application parts, but how do we debug when things go wrong?</p>



<h2 class="wp-block-heading">Providing features with the ApplicationPartManager</h2>



<p>When you add an application part (or when ASP.NET Core adds it automatically), it&#8217;s added to the <code>ApplicationPartManager</code>. <a href="https://github.com/dotnet/aspnetcore/blob/6255c1ed960f5277d2e96ac2d0968c2c7e844ce2/src/Mvc/Mvc.Core/src/ApplicationParts/ApplicationPartManager.cs">This class</a> is responsible for keeping track of all the application parts in the app, and for populating various <em>features</em> based on the registered parts, in conjunction with registered <em>feature providers</em>.</p>



<p>There are a variety of <em>features</em> used in MVC, such as the <code>ControllerFeature</code> and <code>ViewsFeature</code> for example. <a href="https://github.com/dotnet/aspnetcore/blob/6255c1ed960f5277d2e96ac2d0968c2c7e844ce2/src/Mvc/Mvc.Core/src/Controllers/ControllerFeature.cs">The <code>ControllerFeature</code> (shown below)</a> contains a list of all the controllers available to an application, across all of the registered application parts.</p>



<pre class="wp-block-code"><code>public class ControllerFeature
{
    public IList&lt;TypeInfo&gt; Controllers { get; } = new List&lt;TypeInfo&gt;();
}</code></pre>



<p>The list of controllers is obtained <a href="https://github.com/dotnet/aspnetcore/blob/6255c1ed960f5277d2e96ac2d0968c2c7e844ce2/src/Mvc/Mvc.Core/src/Controllers/ControllerFeatureProvider.cs">by using the <code>ControllerFeatureProvider</code></a>. <a href="https://github.com/dotnet/aspnetcore/blob/6255c1ed960f5277d2e96ac2d0968c2c7e844ce2/src/Mvc/Mvc.Core/src/ApplicationParts/IApplicationFeatureProviderOfT.cs">This class implements the <code>IApplicationFeatureProvider&lt;T&gt;</code> interface</a>, which, when given a list of application parts, populates an instance of <code>ControllerFeature</code> with all the controllers it finds.</p>



<pre class="wp-block-code"><code>public class ControllerFeatureProvider : IApplicationFeatureProvider&lt;ControllerFeature&gt;
{
    public void PopulateFeature(IEnumerable&lt;ApplicationPart&gt; parts, ControllerFeature feature)
    {
        <em>// Loop through all the application parts</em>
        foreach (var part in parts.OfType&lt;IApplicationPartTypeProvider&gt;())
        {
            <em>// Loop through all the types in the application part</em>
            foreach (var type in part.Types)
            {
                <em>// If the type is a controller (and isn't already added) add it to the list</em>
                if (IsController(type) &amp;&amp; !feature.Controllers.Contains(type))
                {
                    feature.Controllers.Add(type);
                }
            }
        }
    }

    protected virtual bool IsController(TypeInfo typeInfo) =&gt; { <em>/* Elided for brevity*/</em> }
}
</code></pre>



<p>The <code>ApplicationPartManager</code> exposes <a href="https://github.com/dotnet/aspnetcore/blob/6255c1ed960f5277d2e96ac2d0968c2c7e844ce2/src/Mvc/Mvc.Core/src/ApplicationParts/ApplicationPartManager.cs#L40-L50">a <code>PopulateFeature</code> method which calls all the appropriate feature providers for a given feature</a>:</p>



<pre class="wp-block-code"><code>public class ApplicationPartManager
{
    <em>// The list of application parts</em>
    public IList&lt;ApplicationPart&gt; ApplicationParts { get; } = new List&lt;ApplicationPart&gt;();

    <em>// The list of feature providers for the various possible features</em>
    public IList&lt;IApplicationFeatureProvider&gt; FeatureProviders { get; } =
            new List&lt;IApplicationFeatureProvider&gt;();


    <em>// Populate the feature of type TFeature</em>
    public void PopulateFeature&lt;TFeature&gt;(TFeature feature)
    {
        foreach (var provider in FeatureProviders.OfType&lt;IApplicationFeatureProvider&lt;TFeature&gt;&gt;())
        {
            provider.PopulateFeature(ApplicationParts, feature);
        }
    }</code></pre>



<p>That covers all the background for <code>ApplicationPartManager</code> and features.</p>



<h2 class="wp-block-heading">Listing all the Application parts and controllers added to an application</h2>



<p>To quickly work out whether my <code>404</code> problem was due to routing or missing controllers, I needed to interrogate the <code>ApplicationPartManager</code>. If the application parts and controllers for the problematic modules were missing, then that was the problem; if they were present, then it was probably some sort of routing issue!</p>



<p>To debug the issue I wrote a quick <code>IHostedService</code> that logs the application parts added to an application, along with all of the controllers discovered.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>I used an <code>IHostedService</code> because it runs after application part discovery, and only executes once on startup.</p>
</blockquote>



<p>The example below takes an <code>ILogger</code> and the <code>ApplicationPartManager</code> as dependencies. It then lists the names of the application parts, populates an instance of the <code>ControllerFeature</code>, and lists all the controllers known to the app. These are written to a log message which can be safely inspected</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/app-parts?view=aspnetcore-3.1#display-available-features">A similar example in the documentation</a><em> exposes this information via a Controller, which seems like a bit of a bad idea to me!</em></p>
</blockquote>



<pre class="wp-block-code"><code>public class ApplicationPartsLogger : IHostedService
{
    private readonly ILogger&lt;ApplicationPartsLogger&gt; _logger;
    private readonly ApplicationPartManager _partManager;

    public ApplicationPartsLogger(ILogger&lt;ApplicationPartsLogger&gt; logger, ApplicationPartManager partManager)
    {
        _logger = logger;
        _partManager = partManager;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        <em>// Get the names of all the application parts. This is the short assembly name for AssemblyParts</em>
        var applicationParts = _partManager.ApplicationParts.Select(x =&gt; x.Name);

        <em>// Create a controller feature, and populate it from the application parts</em>
        var controllerFeature = new ControllerFeature();
        _partManager.PopulateFeature(controllerFeature);

        <em>// Get the names of all of the controllers</em>
        var controllers = controllerFeature.Controllers.Select(x =&gt; x.Name);

        <em>// Log the application parts and controllers</em>
        _logger.LogInformation("Found the following application parts: '{ApplicationParts}' with the following controllers: '{Controllers}'",
            string.Join(", ", applicationParts), string.Join(", ", controllers));

        return Task.CompletedTask;
    }

    <em>// Required by the interface</em>
    public Task StopAsync(CancellationToken cancellationToken) =&gt; Task.CompletedTask;
}</code></pre>



<p>All that remains is to register the hosted service in <code>Startup.ConfigureServices</code>:</p>



<pre class="wp-block-code"><code>public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddHostedService&lt;ApplicationPartsLogger&gt;();
}</code></pre>



<p>Below is example log message, in which an API project (<em>ApplicationPartsDebugging.Api</em>) references a class library (<em>ApplicationPartsDebugging.Controllers</em>) which contains a controller, <code>TestController</code>.</p>



<pre class="wp-block-code"><code>info: ApplicationPartsDebugging.Api.ApplicationPartsLogger[0]
      Found the following application parts: 'ApplicationPartsDebugging.Api, ApplicationPartsDebugging.Controllers' 
      with the following controllers: 'WeatherForecastController, TestController'</code></pre>



<p>Both the API app and the class library are referenced as application parts, and controllers from both application parts are available.</p>



<p>And yes, this was exactly the problem I had during my conversion, I&#8217;d failed to register one of the modules as an application part, shown by it&#8217;s absence from my log message!</p>



<h2 class="wp-block-heading" id="summary">Summary</h2>



<p>In this post I described a problem I faced when converting an application to ASP.NET Core &#8211; the controllers from a referenced project could not be found. ASP.NET Core looks for controllers, views, and other features in <em>application parts</em> that it knows about. You can add additional application parts to an ASP.NET Core manually, though ASP.NET Core 3.x will generally handle this for you automatically. To debug my problem I created an <code>ApplicationPartsLogger</code> that lists all the registered application parts for an app. This allows you to easily spot when an expected assembly is missing.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/using-asp-net-core-to-find-controllers-in-your-app/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<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>How to Detect Session Timeout and Redirect to Login Page in ASP.NET</title>
		<link>https://topreviewhostingasp.net/how-to-detect-session-timeout-and-redirect-to-login-page-in-asp-net/</link>
					<comments>https://topreviewhostingasp.net/how-to-detect-session-timeout-and-redirect-to-login-page-in-asp-net/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Thu, 10 Dec 2020 04:09:44 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp.net tips]]></category>
		<category><![CDATA[asp.net tutorial]]></category>
		<category><![CDATA[detect session asp net]]></category>
		<category><![CDATA[session asp net]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2821</guid>

					<description><![CDATA[This is example of&#160;Detecting Session Timeout and Redirect to Login Page in ASP.NET, session timeout occurs when user is idle for the time specified as in web.config file. 1st Method In web.config file, set the sessionstate mode to inproc and authentication mode to Forms I&#8217;ve created three pages in this example , one is login [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>This is example of&nbsp;Detecting Session Timeout and Redirect to Login Page in ASP.NET, session timeout occurs when user is idle for the time specified as in web.config file.</p>



<p><strong>1st Method</strong></p>



<p>In web.config file, set the sessionstate mode to inproc and authentication mode to Forms</p>



<pre class="wp-block-code"><code>&lt;system.web>
&lt;compilation debug="true"/>
&lt;authentication mode="Forms"/>
&lt;sessionState mode="InProc" cookieless="false" timeout="1">
&lt;/sessionState>
&lt;/system.web> </code></pre>



<p>I&#8217;ve created three pages in this example , one is login page , when session expires , I redirect to this page , one is navigation page where I&#8217;ll check if session is valid or not , if it is valid than only user will see this page other wise he gets redirected to login page.</p>



<p><strong>Add Global.asax class file in root of your application or website.<br>This method works only if Global.asax is present in application.</strong></p>



<p>Write below mentioned code in Page_Init event of the page where we want to check for session timeout.</p>



<p>we can also put this code in in a class and inherit all pages of application from this class acting as base class for all pages to check for session timeout.</p>



<p><strong>C# CODE</strong></p>



<pre class="wp-block-code"><code>protected void Page_Init(object sender, EventArgs e)
    {
        if (Context.Session != null)
        {
            if (Session.IsNewSession)
            {
                HttpCookie newSessionIdCookie = Request.Cookies&#91;"ASP.NET_SessionId"];
                if (newSessionIdCookie != null)
                {
                    string newSessionIdCookieValue = newSessionIdCookie.Value;
                    if (newSessionIdCookieValue != string.Empty)
                    {
                        // This means Session was timed Out and New Session was started
                        Response.Redirect("Login.aspx");
                    }
                }
            }
        }
    }</code></pre>



<p><strong>VB.NET</strong></p>



<pre class="wp-block-code"><code>Protected Sub Page_Init(sender As Object, e As EventArgs)
 If Context.Session IsNot Nothing Then
  If Session.IsNewSession Then
   Dim newSessionIdCookie As HttpCookie = Request.Cookies("ASP.NET_SessionId")
   If newSessionIdCookie IsNot Nothing Then
    Dim newSessionIdCookieValue As String = newSessionIdCookie.Value
    If newSessionIdCookieValue &lt;> String.Empty Then
     ' This means Session was timed Out and New Session was started
     Response.Redirect("Login.aspx")
    End If
   End If
  End If
 End If
End Sub</code></pre>



<p><strong>2nd Method.</strong></p>



<p><strong>Code for Default.aspx</strong></p>



<pre class="wp-block-code"><code>&lt;%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>

&lt;!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

&lt;html xmlns="http://www.w3.org/1999/xhtml" >
&lt;head runat="server">
&lt;title>Untitled Page&lt;/title>
&lt;/head>
&lt;body>
&lt;form id="form1" runat="server">
&lt;div>
&lt;asp:Button ID="btnSessionStart"
runat="server"
OnClick="btnSessionStart_Click"
Text="Start Session" />&lt;br />
&lt;br />
&lt;br />
&lt;asp:Button ID="btnCheck"
runat="server"
OnClick="btnCheck_Click"
Text="Check Session ID" />
&lt;br />
&lt;asp:TextBox ID="txtSession"
runat="server"
Width="266px">
&lt;/asp:TextBox>&lt;br />
&lt;br />
&lt;asp:Button ID="btnGO"
runat="server"
OnClick="btnGO_Click"
Text="Go to Other Page" />
&lt;br />
&lt;br />
&lt;/div>
&lt;/form>
&lt;/body>
&lt;/html></code></pre>



<p>And the code behind for this page is like</p>



<pre class="wp-block-code"><code>protected void btnSessionStart_Click
(object sender, EventArgs e)
{
Guid Session_id = Guid.NewGuid();
Session&#91;"SessionID"]
= Session_id.ToString();

}
protected void btnCheck_Click
(object sender, EventArgs e)
{
if (Session&#91;"SessionID"] != null)
txtSession.Text =
Session&#91;"SessionID"].ToString();
else
txtSession.Text =
"Session has expired";
}
protected void btnGO_Click
(object sender, EventArgs e)
{
Response.Redirect("Default2.aspx");
}</code></pre>



<p><strong>On the page where we want to check the session has timed out or not, we need to check it in the Page_Init event of the page , if session is not null than user will be able to go to the page other wise he will be redirected to login page.</strong></p>



<pre class="wp-block-code"><code>&lt;html xmlns="http://www.w3.org/1999/xhtml" >
&lt;head runat="server">
&lt;title>Untitled Page&lt;/title>
&lt;/head>
&lt;body>
&lt;form id="form1" runat="server">
&lt;div>
&lt;asp:Button ID="btnHome"
runat="server" OnClick="btnHome_Click"
Text="Home" />&lt;/div>
&lt;/form>
&lt;/body>
&lt;/html></code></pre>



<p>And the Code behind for this page is</p>



<pre class="wp-block-code"><code>protected void Page_Init(object sender, EventArgs e)
{
CheckSession();
}
protected void btnHome_Click(object sender, EventArgs e)
{
Response.Redirect("Default.aspx");
}

private void CheckSession()
{
if (Session&#91;"SessionID"] == null)
{
Response.Redirect("Login.aspx");
}

}</code></pre>



<p>If we need to check this in all the pages of application than we can create a BaseClass and write the above mentioned code of CheckSession and Page_Init part and drive all ur pages from this class by typing BaseClassName in place of System.Web.UI.Page and it will check all pages for session timeout every time page is loaded</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-detect-session-timeout-and-redirect-to-login-page-in-asp-net/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Why Your ASP.NET Site MUST Run Faster?!</title>
		<link>https://topreviewhostingasp.net/why-your-asp-net-site-must-run-faster/</link>
					<comments>https://topreviewhostingasp.net/why-your-asp-net-site-must-run-faster/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Mon, 25 Mar 2019 07:22:40 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp.net faster]]></category>
		<category><![CDATA[ASP.NET Hosting]]></category>
		<category><![CDATA[asp.net tutorial]]></category>
		<category><![CDATA[cheap ASP.NET Hosting]]></category>
		<category><![CDATA[google pageinsight]]></category>
		<category><![CDATA[pagespeed score]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2687</guid>

					<description><![CDATA[You want your ASP.NET site to load lightning-fast. And if you’re like most of us, when you think of improving your site’s page load times to get that “lightning-fast” designation, you think of your Google PageSpeed Insights score. For many website owners, it’s their white whale. Getting a perfect score on PageSpeed Insights is the impossible [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>You want your ASP.NET site to load lightning-fast. And if you’re like most of us, when you think of improving your site’s page load times to get that “lightning-fast” designation, you think of your Google PageSpeed Insights score.</p>



<p>For many website owners, it’s their white whale. Getting a perfect score on PageSpeed Insights is the impossible quest that will magically solve all of their page speed woes.</p>



<p>But is a high PageSpeed Insights score the be-all and end-all of fast page load times? Sorry, but <strong>no.</strong> If your focus is on improving your site’s page load times, <strong>finding a better ASP.NET host will often take you further.</strong></p>



<p>In this post, I’m going to run a real test to show you that high-performance hosting will do more for your page load times than endlessly striving to improve your PageSpeed Insights score.</p>



<h2 class="wp-block-heading">Google PageSpeed Insights. What is it?</h2>



<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="886" height="275" class="wp-image-2688 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreviewhostingasp-googlepageinsight.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreviewhostingasp-googlepageinsight.jpg 886w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreviewhostingasp-googlepageinsight-300x93.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreviewhostingasp-googlepageinsight-768x238.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreviewhostingasp-googlepageinsight-50x16.jpg 50w" sizes="(max-width: 886px) 100vw, 886px" /></figure>
</div>



<p>If you’re not already familiar, <a href="https://developers.google.com/speed/pagespeed/insights/" target="_blank" rel="noreferrer noopener">PageSpeed Insights</a> is a Google-offered tool that helps you both analyze and optimize your website’s performance for desktop and mobile visitors. Before I get into what exactly that entails, let’s talk about what PageSpeed Insights <strong>is not:</strong></p>



<p>It’s not a tool that gives you a real number for how long your page takes to load. You need other tools for that. Instead, PageSpeed Insights gives you a score from 0-100 based on how well your site is technically optimized, with separate scores for desktop and mobile.</p>



<p>To calculate this score, Google uses two metrics (<em>direct quote</em>):</p>



<ul>
<li><strong>time to above-the-fold load</strong>: Elapsed time from the moment a user requests a new page and to the moment the above-the-fold content is rendered by the browser.</li>
<li><strong>time to full page load</strong>: Elapsed time from the moment a user requests a new page to the moment the page is fully rendered by the browser.</li>
</ul>



<p>And while Google’s suggestions are important, they <a href="https://developers.google.com/speed/docs/insights/about" target="_blank" rel="noreferrer noopener">readily admit</a> that the test <em>“only considers the network-independent aspects of page performance”</em>. That means PageSpeed Insights <strong>does not</strong>, among other aspects, directly consider the speed of your host.</p>



<p>So while PageSpeed Insights gives you great suggestions for speeding up the technical aspects of your page, <strong>getting a perfect score on PageSpeed Insights will never be enough to completely overcome a slow host.</strong></p>



<p>In Google’s own words, the <em>“absolute performance of the page will still be dependent upon a user’s network connection.”</em></p>



<p>* <em>It should be noted that Google is also talking about a visitor’s personal Internet speed.</em></p>



<h2 class="wp-block-heading">Is it Really Important to have High PageSpeed Score?</h2>



<p>Plenty of data says that users care about how quickly your page loads <strong>in absolute terms</strong>. Akamai found that, at least for eCommerce sites, 30% of users want sites to load in under 1 second. And on mobile, 74% of users will abandon a site that takes longer than 5 seconds to load.</p>



<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="651" height="341" class="wp-image-2689 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2019/03/ecommerce-result.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2019/03/ecommerce-result.jpg 651w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/ecommerce-result-300x157.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/ecommerce-result-50x26.jpg 50w" sizes="(max-width: 651px) 100vw, 651px" /></figure>
</div>



<p>But as we learned in the previous section, PageSpeed Insights does not calculate the absolute page load time of your site.</p>



<h2 class="wp-block-heading">So, is it Important to have High PageSpeed Insights?</h2>



<p>Yes and no. A higher PageSpeed Insights score will likely improve the speed of your website. It will get you a quick<strong>er</strong> loading site.</p>



<p>But here’s the thing:</p>



<p>Your website will only ever be as fast as the hardware that’s powering it. A high-quality web host and good caching will almost always take you further than a 25-point improvement in your PageSpeed Insights score.</p>



<p>I have tested my ASP.NET site in <a href="http://www.asphostportal.com">ASPHostPortal hosting</a>, with simple ASP.NET site.</p>



<p>Using those settings, I’ll run each site through PageSpeed Insights and use Pingdom Tools (testing from San Jose) to calculate the absolute page load time for each site. I’ll use PageSeed Insights’ Desktop score for the purposes of this test.</p>



<h2 class="wp-block-heading">Testing Result &#8211; PageSpeed Insights vs Faster ASP.NET Hosting</h2>



<p>After running the tests and crunching the numbers, here are the results I came up with.</p>



<h3 class="wp-block-heading"><strong>ASPHostPortal Test 1 – Unoptimized PageSpeed Insights score:</strong></h3>



<p>My unoptimized ASPHostPortal test site had a mediocre PageSpeed Insights score of 66/100:</p>



<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="686" height="284" class="wp-image-2690 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2019/03/pageinsight-test.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2019/03/pageinsight-test.jpg 686w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/pageinsight-test-300x124.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/pageinsight-test-50x21.jpg 50w" sizes="(max-width: 686px) 100vw, 686px" /></figure>
</div>



<p>Pingdom’s calculated page load time was better than I expected, clocking in at 2.00 seconds. That’s actually not <em>horrible</em>. But remember that I’m testing on a dummy site without much content:</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="746" height="292" class="wp-image-2691" src="https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreview-score.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreview-score.jpg 746w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreview-score-300x117.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreview-score-50x20.jpg 50w" sizes="(max-width: 746px) 100vw, 746px" /></figure>



<h3 class="wp-block-heading"><strong>ASPHostPortal Test 2 – Optimized PageSpeed Insights score:</strong></h3>



<p>After making the tweaks I mentioned above, I got the PageSpeed Insights score for my ASPHostPortal test site up to 90/100. A major improvement from 66 and worthy of the coveted “green” seal of approval:</p>



<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="707" height="194" class="wp-image-2692 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2019/03/pageinsight-test2.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2019/03/pageinsight-test2.jpg 707w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/pageinsight-test2-300x82.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/pageinsight-test2-50x14.jpg 50w" sizes="(max-width: 707px) 100vw, 707px" /></figure>
</div>



<p>So what was the effect on actual page load times? A marked improvement to 947 ms.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="731" height="292" class="wp-image-2693 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreview-score-2.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreview-score-2.jpg 731w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreview-score-2-300x120.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2019/03/topreview-score-2-50x20.jpg 50w" sizes="(max-width: 731px) 100vw, 731px" /></figure>



<h2 class="wp-block-heading">Summary</h2>



<p>I don’t want you to come away from this post thinking that you should ignore Google PageSpeed Insights. The people at Google are way smarter than I am. They know what they’re doing.</p>



<p>All I’m saying is this…</p>



<p>Focus <em>most </em>on what’s actually important – <strong>absolute page load times</strong>. PageSpeed Insights is not the end of your optimization journey. Nor should it always be your primary focus.</p>



<p>When it comes to absolute page load times (the important thing!), <a href="https://topreviewhostingasp.net/asphostportal-com-asp-net-hosting-review/">switching to a faster ASP.NET host</a> and implementing good caching will have a much larger effect than trying to go from 66 to a 90 PageSpeed Insights score on sub-par hosting.</p>


]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/why-your-asp-net-site-must-run-faster/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Wiring up Ninject with ASP.NET Core 2.0</title>
		<link>https://topreviewhostingasp.net/how-to-wiring-up-ninject-with-asp-net-core-2-0/</link>
					<comments>https://topreviewhostingasp.net/how-to-wiring-up-ninject-with-asp-net-core-2-0/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 08 May 2018 07:25:35 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[ASP.NET Hosting]]></category>
		<category><![CDATA[asp.net tips]]></category>
		<category><![CDATA[asp.net tutorial]]></category>
		<category><![CDATA[ninject asp.net]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=1541</guid>

					<description><![CDATA[Ninject is a lightning-fast, ultra-lightweight dependency injector for .NET applications. It helps you split your application into a collection of loosely-coupled, highly-cohesive pieces, and then glue them back together in a flexible manner. By using Ninject to support your software&#8217;s architecture, your code will become easier to write, reuse, test, and modify. To test if the [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="http://www.ninject.org/">Ninject</a> is a lightning-fast, ultra-lightweight dependency injector for .NET applications. It helps you split your application into a collection of loosely-coupled, highly-cohesive pieces, and then glue them back together in a flexible manner. By using Ninject to support your software&#8217;s architecture, your code will become easier to write, reuse, test, and modify.</p>
<p>To test if the injector is working correctly, create a service that implements an interface</p>
<pre class="lang:default decode:true ">    public interface ITestService
    {
        string GetData();
    }

    public class TestService : ITestService
    {
        public string GetData()
        {
            return "some magic string";
        }
    }</pre>
<h4>Download the package from Nuget</h4>
<p>Using the package manager console <code>Install-Package Ninject -Version 3.3.4</code></p>
<p>Using dotnet cli <code>dotnet add package Ninject --version 3.3.4</code></p>
<h4>Add these members to <code>Startup.cs</code> class as shown below</h4>
<pre class="lang:default decode:true ">    private readonly AsyncLocal&lt;Scope&gt; scopeProvider = new AsyncLocal&lt;Scope&gt;();
    private IKernel Kernel { get; set; }

    private object Resolve(Type type) =&gt; Kernel.Get(type);
    private object RequestScope(IContext context) =&gt; scopeProvider.Value;  

    private sealed class Scope : DisposableObject { }</pre>
<h4>Add the following binding in the end of <code>ConfigureServices</code> (<code>Startup.cs</code>)</h4>
<p><code>services.AddSingleton&lt;IHttpContextAccessor, HttpContextAccessor&gt;();</code></p>
<h4>Create class <code>RequestScopingStartupFilter</code> implementing the <code>IStartupFilter</code> interface</h4>
<pre class="lang:default decode:true ">    public sealed class RequestScopingStartupFilter : IStartupFilter
    {
        private readonly Func&lt;IDisposable&gt; requestScopeProvider;

        public RequestScopingStartupFilter(Func&lt;IDisposable&gt; requestScopeProvider)
        {
            if (requestScopeProvider == null)
            {
                throw new ArgumentNullException(nameof(requestScopeProvider));
            }

            this.requestScopeProvider = requestScopeProvider;
        }

        public Action&lt;IApplicationBuilder&gt; Configure(Action&lt;IApplicationBuilder&gt; nextFilter)
        {
            return builder =&gt;
            {
                ConfigureRequestScoping(builder);

                nextFilter(builder);
            };
        }

        private void ConfigureRequestScoping(IApplicationBuilder builder)
        {
            builder.Use(async (context, next) =&gt;
            {
                using (var scope = this.requestScopeProvider())
                {
                    await next();
                }
            });
        }
    }</pre>
<h4>Create a static class <code>AspNetCoreExtensions</code> with the following extension method</h4>
<pre class="lang:default decode:true ">    using System;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.DependencyInjection;

    public static class AspNetCoreExtensions
    {
        public static void AddRequestScopingMiddleware(this IServiceCollection services, 
            Func&lt;IDisposable&gt; requestScopeProvider)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (requestScopeProvider == null)
            {
                throw new ArgumentNullException(nameof(requestScopeProvider));
            }

            services
                .AddSingleton&lt;IStartupFilter&gt;(new
                    RequestScopingStartupFilter(requestScopeProvider));
        }
    }</pre>
<h4>Configure to use the middleware in <code>ConfigureServices</code>(in the end of the method)</h4>
<p><code>services.AddRequestScopingMiddleware(() =&gt; scopeProvider.Value = new Scope());</code></p>
<h4>Create a file <code>Activators.cs</code> with the following</h4>
<pre class="lang:default decode:true ">   public sealed class DelegatingControllerActivator : IControllerActivator
        {
            private readonly Func&lt;ControllerContext, object&gt; controllerCreator;
            private readonly Action&lt;ControllerContext, object&gt; controllerReleaser;

            public DelegatingControllerActivator(Func&lt;ControllerContext, object&gt; controllerCreator,
                Action&lt;ControllerContext, object&gt; controllerReleaser = null)
            {
                this.controllerCreator = controllerCreator ?? 
                    throw new ArgumentNullException(nameof(controllerCreator));
                this.controllerReleaser = controllerReleaser ?? ((_, __) =&gt; { });
            }

            public object Create(ControllerContext context) =&gt; this.controllerCreator(context);
            public void Release(ControllerContext context, object controller) =&gt;             
                this.controllerReleaser(context, controller);
        }</pre>
<h4>Add the following extension method to <code>AspNetCoreExtensions.cs</code></h4>
<pre class="lang:default decode:true ">        public static void AddCustomControllerActivation(this IServiceCollection services,
            Func&lt;Type, object&gt; activator)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            if (activator == null) throw new ArgumentNullException(nameof(activator));

            services.AddSingleton&lt;IControllerActivator&gt;(new DelegatingControllerActivator(
                context =&gt; activator(context.ActionDescriptor.ControllerTypeInfo.AsType())));
        }</pre>
<h4>Append the following to the end of <code>ConfigureServices</code></h4>
<p><code>services.AddCustomControllerActivation(Resolve);</code></p>
<h4>Add another class to <code>Activators.cs</code></h4>
<pre class="lang:default decode:true ">        public sealed class DelegatingViewComponentActivator : IViewComponentActivator
        {
            private readonly Func&lt;Type, object&gt; viewComponentCreator;
            private readonly Action&lt;object&gt; viewComponentReleaser;

            public DelegatingViewComponentActivator(Func&lt;Type, object&gt; viewComponentCreator,
                Action&lt;object&gt; viewComponentReleaser = null)
            {
                this.viewComponentCreator = viewComponentCreator ?? 
                    throw new ArgumentNullException(nameof(viewComponentCreator));
                this.viewComponentReleaser = viewComponentReleaser ?? (_ =&gt; { });
            }

            public object Create(ViewComponentContext context) =&gt;
                this.viewComponentCreator(context.ViewComponentDescriptor.TypeInfo.AsType());

            public void Release(ViewComponentContext context, object viewComponent) =&gt;
                this.viewComponentReleaser(viewComponent);
        }</pre>
<h4>And another extension method in <code>AspNetCoreExtensions.cs</code></h4>
<pre class="lang:default decode:true ">       public static void AddCustomViewComponentActivation(this IServiceCollection services, 
            Func&lt;Type, object&gt; activator)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            if (activator == null) throw new ArgumentNullException(nameof(activator));

            services.AddSingleton&lt;IViewComponentActivator&gt;(
new DelegatingViewComponentActivator(activator));
        }</pre>
<p>then call it form <code>ConfigureServices</code> (should be the last invoked)</p>
<p>This is what <code>ConfigureServices</code> should look like now</p>
<pre class="lang:default decode:true ">        public void ConfigureServices(IServiceCollection services)
        {
            // Other configurations

            services.AddSingleton&lt;IHttpContextAccessor, HttpContextAccessor&gt;();

            services.AddRequestScopingMiddleware(() =&gt; scopeProvider.Value = new Scope());
            services.AddCustomControllerActivation(Resolve);
            services.AddCustomViewComponentActivation(Resolve);

        }</pre>
<h4>Create an <code>ApplicationBuilderExtensions.cs</code> with a static class in it</h4>
<pre class="lang:default decode:true ">    using System;
    using System.Globalization;
    using System.Linq;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc.ApplicationParts;
    using Microsoft.AspNetCore.Mvc.Controllers;
    using Microsoft.Extensions.DependencyInjection;
    using Ninject;

    public static class ApplicationBuilderExtensions
    {
        public static void BindToMethod&lt;T&gt;(this IKernel config, Func&lt;T&gt; method)
 =&gt; config.Bind&lt;T&gt;().ToMethod(c =&gt; method());

        public static Type[] GetControllerTypes(this IApplicationBuilder builder)
        {
            var manager = builder.ApplicationServices.GetRequiredService&lt;ApplicationPartManager&gt;();

            var feature = new ControllerFeature();
            manager.PopulateFeature(feature);

            return feature.Controllers.Select(t =&gt; t.AsType()).ToArray();
        }

        public static T GetRequestService&lt;T&gt;(this IApplicationBuilder builder) where T : class
        {
            if (builder == null) throw new ArgumentNullException(nameof(builder));

            return GetRequestServiceProvider(builder).GetService&lt;T&gt;();
        }

        private static IServiceProvider GetRequestServiceProvider(IApplicationBuilder builder)
        {
            var accessor = builder.ApplicationServices.GetService&lt;IHttpContextAccessor&gt;();

            if (accessor == null)
            {
                throw new InvalidOperationException(      
          typeof(IHttpContextAccessor).FullName);
            }

            var context = accessor.HttpContext;

            if (context == null)
            {
                throw new InvalidOperationException("No HttpContext.");
            }

            return context.RequestServices;
        }
    }</pre>
<p>Add the following method in <code>Startup</code> class</p>
<pre class="lang:default decode:true ">        private IKernel RegisterApplicationComponents(IApplicationBuilder app)
        {
            // IKernelConfiguration config = new KernelConfiguration();
            var kernel = new StandardKernel();

            // Register application services
            foreach (var ctrlType in app.GetControllerTypes())
            {
                kernel.Bind(ctrlType).ToSelf().InScope(RequestScope);
            }

            // This is where our bindings are configurated
             kernel.Bind&lt;ITestService&gt;().To&lt;TestService&gt;().InScope(RequestScope);            

            // Cross-wire required framework services
            kernel.BindToMethod(app.GetRequestService&lt;IViewBufferScope&gt;);

            return kernel;
        }</pre>
<p>and call it from <code>Configure</code> (in the beginning)</p>
<p><code>this.Kernel = this.RegisterApplicationComponents(app);</code></p>
<h4>Create a <code>TestController</code> to see if our DI works</h4>
<pre class="lang:default decode:true ">    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        private readonly ITestService testService;

        public ValuesController(ITestService testService)
        {
            this.testService = testService;
            this.factory = factory;
        }

        [HttpGet]
        public IActionResult Get()
        {
            var result = this.testService.GetData();

            return this.Ok(result);
        }
    }</pre>
<p>Place a breakpoint in the constructor of our <code>TestService</code> and in the <code>Get</code>action to see the magic.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-wiring-up-ninject-with-asp-net-core-2-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Automate Reload Configuration in ASP.NET Core</title>
		<link>https://topreviewhostingasp.net/automate-reload-configuration-asp-net-core/</link>
					<comments>https://topreviewhostingasp.net/automate-reload-configuration-asp-net-core/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 29 Aug 2017 04:16:48 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></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>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=758</guid>

					<description><![CDATA[In this article, I want to explore IOptionsSnapshot and show how to work with IOptionsSnapshot in ASP.NET Core 1.1. We will use the dot-net CLI to create a new project and configure it using the reload technique in combination with IOptionsSnapshot. Make sure you are using at least ASP.NET Core 1.1. Get started by creating [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>In this article, I want to explore IOptionsSnapshot and show how to work with IOptionsSnapshot in ASP.NET Core 1.1.</p>
<p>We will use the dot-net CLI to create a new project and configure it using the reload technique in combination with IOptionsSnapshot.</p>
<p>Make sure you are using at least ASP.NET Core 1.1. Get started by creating a new folder that you want to work in, opening a console there and typingdotnet new mvc and dotnet restore to get the project in a starting position. Then open up a console and type code. to start Visual Studio Code on the current level.</p>
<p>You should now see all the files and folders of your project. We can now go ahead and create a typed class which represents the configuration we want to work with. In this case, this is just a file with a name property.</p>
<pre class="lang:default decode:true  ">Config 
  └── myConfig.json 
  Controllers └── ... 
  Views └── ... 
  wwwroot └── ... ... 
  Program.cs 
  Startup.cs</pre>
<p>myConfig.json</p>
<pre class="lang:default decode:true">{
    "Person": {
        "Firstname": "John Doe"
    }
}</pre>
<p>This leads us to the class</p>
<pre class="lang:default decode:true">public class Person  
{
    public string Firstname { get; set; }
}</pre>
<pre class="lang:default decode:true">Config  
  └── myConfig.json  
  Controllers └── ...  
  Views └── ...  
  wwwroot └── ... ...  
  Program.cs  
  Startup.cs</pre>
<p>which represents our configuration in our application.</p>
<p>We have to modify our constructor of the Startup.cs file a bit to load this new file:</p>
<pre class="lang:default decode:true">public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
    Configuration = builder.Build();
}</pre>
<p>This then becomes:</p>
<pre class="lang:default decode:true">public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddJsonFile($"config/myConfig.json", optional: false, reloadOnChange: true)
        .AddEnvironmentVariables();
    Configuration = builder.Build();
}</pre>
<p>Pay attention to the realoadOnChange: true because that is what we are reaching out for.</p>
<p>So now that we loaded the file we need to add it to our configuration which is used in our app. Let&#8217;s do this by adding the statement in the ConfigureServices-Method:</p>
<pre class="lang:default decode:true">public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.Configure&lt;Person&gt;(Configuration.GetSection("Person"));
}</pre>
<p>Here we are mapping our values in JSON to a typed class called “Person.”</p>
<p>Now, this configuration is available through dependency injection and we can use it in our controllers!</p>
<pre class="lang:default decode:true">public class HomeController : Controller  
{
    private readonly Person _person;
    public HomeController(IOptionsSnapshot&lt;Person&gt; person)
    {
        _person = person.Value;
    }
}</pre>
<p>Pay attention to the “IOptionsSnapshot” we injected here which is different from the previous ASP.NET Core versions. Be sure to have the &#8220;Microsoft.Extensions.Options&#8221;: &#8220;1.1.0&#8221; package installed and that you are using ASP.NET Core 1.1. We can now inject the IOptionsSnapshot&lt;T&gt; in our controller and use its value. For testing, we save the Firstname in the ViewData displaying it afterward.</p>
<pre class="lang:default decode:true">namespace WebApplication6.Controllers
{
    public class HomeController : Controller
    {
        private readonly Person _person;
        public HomeController(IOptionsSnapshot&lt;Person&gt; person)
        {
            _person = person.Value;
        }
        public IActionResult Index()
        {
            ViewData["FirstName"] = _person.Firstname;
            return View();
        }
    }
}</pre>
<p>Index.cshtml</p>
<pre class="lang:default decode:true">&lt;h3&gt;@(ViewData["FirstName"])&lt;/h3&gt;</pre>
<p>If you now start the web application via dotnet run and you change the configuration without restarting the application, hit F5 to refresh the browser and you will see the new values.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/automate-reload-configuration-asp-net-core/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
