<?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 tips &#8211; ASP.NET Hosting Reviews and Guides</title>
	<atom:link href="https://topreviewhostingasp.net/tag/asp-net-tips-2/feed/" rel="self" type="application/rss+xml" />
	<link>https://topreviewhostingasp.net</link>
	<description>ASP.NET Hosting &#124; Reviews &#124; Tips &#38; Tutorial</description>
	<lastBuildDate>Fri, 12 Jul 2024 05:15:16 +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 tips &#8211; ASP.NET Hosting Reviews and Guides</title>
	<link>https://topreviewhostingasp.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Why ASP.NET Website Eat High CPU Usage?</title>
		<link>https://topreviewhostingasp.net/why-asp-net-website-eat-high-cpu-usage/</link>
					<comments>https://topreviewhostingasp.net/why-asp-net-website-eat-high-cpu-usage/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Fri, 12 Jul 2024 05:15:16 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net tips]]></category>
		<category><![CDATA[asp net tutorial]]></category>
		<category><![CDATA[asp net website]]></category>
		<category><![CDATA[fix high cpu usage]]></category>
		<category><![CDATA[high cpu usage]]></category>
		<category><![CDATA[iis worker service]]></category>
		<category><![CDATA[reason high cpu usage]]></category>
		<category><![CDATA[website]]></category>
		<category><![CDATA[www service]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3856</guid>

					<description><![CDATA[Do you experience poor IIS performance? Does w3wp.exe use a lot of CPU power? How can the high CPU usage of the IIS Worker Process be troubleshooted? We&#8217;ll go over some strategies in this post to figure out why your ASP.NET web applications are using a lot of CPU power. There are numerous reasons why [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Do you experience poor IIS performance? Does w3wp.exe use a lot of CPU power? How can the high CPU usage of the IIS Worker Process be troubleshooted?</p>
<p>We&#8217;ll go over some strategies in this post to figure out why your ASP.NET web applications are using a lot of CPU power.</p>
<p>There are numerous reasons why w3wp.exe, your IIS worker process, might be consuming a lot of CPU power. We&#8217;ll go over some of the most common causes and how to fix issues with IIS performance.</p>
<p>In order to troubleshoot the IIS worker process, you should first see which web requests are currently executing with IIS and see if that helps you identify the problem.</p>
<h2 class="wp-block-heading">How to See Active Internet Requests in IIS</h2>
<p>Identifying the web requests that are presently being executed ought to be among your initial priorities. This could assist you in determining which particular URL is the source of the issue.</p>
<p>It&#8217;s possible that you will identify one of the URLs that is notorious for taking a very long time or causing high CPU problems.</p>
<p>On the other hand, this might also display a number of pending web requests rather than taking you straight to the source.</p>
<h3 class="wp-block-heading">Via the IIS User Interface</h3>
<p>Viewing the active worker processes is possible through the IIS management console. You can see which IIS application pool is using a lot of CPU time as well as the web requests that are presently active.</p>
<p><img fetchpriority="high" decoding="async" class="size-full wp-image-3857 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/07/worker-process.jpg" alt="" width="894" height="354" srcset="https://topreviewhostingasp.net/wp-content/uploads/2024/07/worker-process.jpg 894w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/worker-process-300x119.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/worker-process-768x304.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/worker-process-50x20.jpg 50w" sizes="(max-width: 894px) 100vw, 894px" /></p>
<p>You can view the IIS worker processes that are currently active by choosing &#8220;Worker Processes&#8221; from the main IIS menu.</p>
<p><img decoding="async" class="size-full wp-image-3858 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/07/iis-worker-process.png" alt="" width="1024" height="194" srcset="https://topreviewhostingasp.net/wp-content/uploads/2024/07/iis-worker-process.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/iis-worker-process-300x57.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/iis-worker-process-768x146.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/iis-worker-process-50x9.png 50w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>
<p>A worker process&#8217;s executing requests can all be seen by double-clicking on it.</p>
<p>A sample from one of our servers is provided here. As you can see, every request is presently executing a different HTTP module and is situated in a different section of the ASP.NET pipeline.</p>
<p><img decoding="async" class="size-full wp-image-3859 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/07/iis-worker-2.png" alt="" width="1024" height="342" srcset="https://topreviewhostingasp.net/wp-content/uploads/2024/07/iis-worker-2.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/iis-worker-2-300x100.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/iis-worker-2-768x257.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/iis-worker-2-50x17.png 50w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>
<h3 class="wp-block-heading">Via Command Line</h3>
<p>The currently active web requests is just one of the many uses for the <strong>appcmd.exe</strong> utility.</p>
<pre class="wp-block-preformatted">C:\Windows\System32\inetsrv&gt;appcmd list requests
REQUEST "f20000048000021c" (url:GET /nopcommerce, time:6312 msec, client:localhost, stage:BeginRequest, module:IIS Web Core)</pre>
<h3 class="wp-block-heading">Understanding The Results &amp; Things to Look For</h3>
<p>Using the command line or IIS user interface, you can see which web requests are active at any given time. It returns the same data in either case.</p>
<ul>
<li>URL: the complete URL that was being executed.</li>
<li>Time: the total amount of time, in milliseconds, the web request has been executing.</li>
<li>Client: the address of the user that initiated the request.</li>
<li>Stage: the stage of the IIS pipeline that the request is currently in.</li>
<li>Module: the ASP.NET module that is currently executing.</li>
</ul>
<h3 class="wp-block-heading">When reviewing the requests, there are a few things you should be aware of.</h3>
<ul>
<li>Does each request point to the same URL? It&#8217;s possible that the issue originated from that URL.</li>
<li>Do a lot of requests originate from the same customer? Maybe a particular user is overloading your web server with requests.</li>
<li>Do all of the requests remain in the same module or stage? Requests hanging at that particular IIS pipeline stage might be the cause of the issue.</li>
</ul>
<h2 class="wp-block-heading">6 Typical Reasons and Solutions for IIS Worker Process High CPU</h2>
<p>There are numerous reasons why the CPU usage of the IIS Worker Process, w3wp.exe, may be high. I&#8217;ll be discussing six prevalent causes in this post:</p>
<h3 class="wp-block-heading"> 1. High Error Rates Within Your ASP.NET Web Application</h3>
<p>It&#8217;s possible that your application has application errors and you are unaware of them. Your users may receive an error message of some kind when there are certain errors. There could be more mistakes made without anyone noticing.</p>
<p>Make sure to check any application performance management or error monitoring tools you use for high error rates.</p>
<p>You can check Windows Event Viewer, IIS Logs, and other places for application error rates and actual errors.</p>
<h4 class="wp-block-heading">Windows Performance Counters for Error Rates</h4>
<p>I would advise looking over two particular performance counters for high error rates. By adding the counters to the chart view and launching Performance Monitor in Windows, you can verify these.</p>
<ul>
<li><strong>.NET CLR Exceptions -&gt; # of Exceps Thrown / sec</strong>: Examine this to determine whether your application is throwing a lot of exceptions. Your application may contain numerous hidden errors that could seriously impair performance.Though some exceptions cannot be avoided, they are still undesirable.</li>
<li><strong>W3SVC_W3WP -&gt; % 500 HTTP Response Sent</strong>: A 500 status code indicates an internal server error for any requests. Ensure that this percentage is extremely low. It ought to be between 0% and 1%.</li>
</ul>
<h3 class="wp-block-heading">2. Growing Web Traffic Resulting in High CPU IIS Worker Process</h3>
<p>An increase in web traffic is one of the easiest explanations for the high CPU usage of w3wp.exe. However, it can be challenging to determine whether traffic has increased if you don&#8217;t have a baseline for your typical volume of traffic.</p>
<p>Make sure to check your application monitoring tool to see if the traffic levels have changed, if you are using one.</p>
<p><a href="https://www.asphostportal.com" target="_blank" rel="noopener"><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> You could try determining whether traffic levels have changed using your IIS log files if you have no other way to know.</p>
<p>To query them, use <a href="http://lizard-labs.com/log_parser_lizard.aspx" target="_blank" rel="noopener">Log Parser Lizard</a> or VisualLogParser.</p>
<p>To view the current traffic rates in real time, there are additional Windows performance counters for Requests / Sec and Requests Current.</p>
<h4 class="wp-block-heading">Possible Reasons for Higher Web Traffic</h4>
<p>If traffic is increasing, consider whether it should be. Consider the following when considering elevated traffic levels:</p>
<ul>
<li>Client or user: Is there a notable increase in traffic coming from a particular user, client, or source? It&#8217;s possible that something isn&#8217;t accessing your website properly. Perhaps you should block a particular IP address.</li>
<li>Bots: It might be a bot, much like a particular user generating a lot of traffic. Examine the user agents in your IIS logs that are being used to visit your website.</li>
<li>Oprah effect: Has anyone mentioned your products, including Oprah? Have you recently gone viral? It&#8217;s great to receive a lot of attention, but you might have to increase your capacity to manage it.</li>
</ul>
<p>You might need to scale out (add more servers) or scale up (get a bigger server) if your website is seeing a lot more traffic.</p>
<p>But traffic might not be the issue if your website receives a small number of requests every second.</p>
<p>Ten to thirty requests are made per second by many ASP.NET applications. On the other hand, I have also observed light web requests making more than 100 requests per second on busy apps.</p>
<p>There is a wide range in both the amount of traffic and CPU usage between different web apps. Everything depends on your particular application.</p>
<h4 class="wp-block-heading">How to Spot Pricey Online Requests</h4>
<div class="wp-block-image"><img loading="lazy" decoding="async" class="size-full wp-image-3860 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/07/log-request.png" alt="" width="970" height="370" srcset="https://topreviewhostingasp.net/wp-content/uploads/2024/07/log-request.png 970w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/log-request-300x114.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/log-request-768x293.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/log-request-50x19.png 50w" sizes="(max-width: 970px) 100vw, 970px" /></div>
<div>You can monitor the overall performance of your application over time by using an APM solution like Retrace. Additionally, it can inform you of the precise web requests that take the longest.</p>
<p>APM tools analyze your application&#8217;s performance right down to the code level using methods such as.NET profilers and other data collection techniques.</p>
<p>You might be able to pinpoint the source of your high CPU usage problem or pinpoint areas of your application that need performance optimization by determining which web requests are consuming the longest.</p></div>
<div>
<h3 class="wp-block-heading">3. Problems With Application Dependencies</h3>
<p><img loading="lazy" decoding="async" class="size-full wp-image-3861 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/07/dependencies.png" alt="" width="849" height="432" srcset="https://topreviewhostingasp.net/wp-content/uploads/2024/07/dependencies.png 849w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/dependencies-300x153.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/dependencies-768x391.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/dependencies-50x25.png 50w" sizes="(max-width: 849px) 100vw, 849px" /></p>
<p>Web apps of today make extensive use of a wide range of external dependencies and services. SQL, NoSQL, caching, queuing, and numerous external HTTP web services are among them.</p>
<p>Any application dependency that slows down can lead to issues with your application&#8217;s performance.Slow SQL queries and issues with external HTTP web services are the most frequent issues.</p>
<p>Retrace or another APM tool is needed to track your application&#8217;s performance to this extent. Retrace monitors your application&#8217;s performance right down to the code level. It can assist you in rapidly determining web service calls, slow SQL queries, and much more.</p>
<h3 class="wp-block-heading">4. Garbage Collection</h3>
</div>
<p><a href="https://msdn.microsoft.com/en-us/library/0xy59wtx(v=vs.110).aspx" target="_blank" rel="noopener">Garbage collection</a> is used by Microsoft.NET to control memory allocation and release.</p>
<p>The allocation and cleanup of application memory may result in a significant amount of garbage collection activity, depending on the functionality of your application. Garbage collection issues arise, for instance, when numerous large string variables are used on a large object heap.</p>
<p>Use this Windows Performance Counter to see whether garbage collection is interfering with your application.</p>
<p><strong>.NET CLR Memory -&gt; % Time in GC:</strong> This counter shows the percentage of time that is spent on garbage collection by your application. Should this figure significantly rise above 5–10%, you should look into memory usage in more detail.</p>
<p>Garbage collection also has two modes. You may need to enable <a href="https://msdn.microsoft.com/en-us/library/cc165011(v=office.11).aspx">server mode</a>, which is not the default.</p>
<h3 class="wp-block-heading">5. The ASP.NET Pipeline is blocking and hanging requests.</h3>
<div class="wp-block-image wp-image-10177 size-full">An <a href="https://msdn.microsoft.com/en-us/library/bb470252.aspx" target="_blank" rel="noopener">ASP.NET request&#8217;s lifecycle</a> consists of numerous steps. This covers fundamental actions such as initiating the request, authenticating, granting access, determining the appropriate HTTP handler, and concluding the request. Numerous standard and bespoke HTTP modules could be used in this context.</p>
<p>I started by showing you how to view the web requests that are presently running.</p></div>
<div class="wp-block-image wp-image-10177 size-full"><img loading="lazy" decoding="async" class="size-full wp-image-3862 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/07/asp-net-lifecycle.png" alt="" width="288" height="358" srcset="https://topreviewhostingasp.net/wp-content/uploads/2024/07/asp-net-lifecycle.png 288w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/asp-net-lifecycle-241x300.png 241w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/asp-net-lifecycle-40x50.png 40w" sizes="(max-width: 288px) 100vw, 288px" /><br />
I would advise checking to see if all of the requests appear to be hanging on a single HTTP module if you are experiencing performance issues.</p>
<p>Both managed.NET code and native code can be used in HTTP modules. These could be common.NET modules like SessionStateModule or FormsAuthentication. A lot of apps also make use of proprietary or third-party HTTP modules.</p></div>
<div>
<h4 class="wp-block-heading">Are You Using Sessions?</h4>
<p>The majority of people are unaware of how much ASP.NET sessions slow down system performance.</p>
<p>They cause your IIS worker process to retrieve your session object upon page load, lock it, and then release it upon request completion.</p>
<p><strong>Sessions can create a bottleneck in your application by causing locking. </strong></p>
<p>Your application&#8217;s performance will be affected by any performance lags if you are using a session provider like SQL or Redis.</p>
<h3 class="wp-block-heading">6. Ineffective.NET Code That Requires Optimization</h3>
<p>It may be necessary to go deeper into the code to make changes if none of the other common causes were the issue. To find out which methods are being called in your code and how long they take, you will need to use.NET code profilers.</p>
<p>You can find particularly slow methods in your code with the aid of profilers.</p>
<p>Be advised that <strong>profilers do increase your application&#8217;s overhead</strong>. The performance of your application will deteriorate and profiling will be extremely slow if your application is already running at a high CPU usage rate (90+%).</p>
<p>Depending on the degree of detail you are profiling and the CPU usage prior to starting the profiling, this could render your application unusable.</p>
<h2>Conclusion</h2>
<p>It is hoped that you are reading this in an effort to learn how to perform better. I hope you&#8217;re rushing and your server isn&#8217;t running at 100%!</p>
<p>We spend a lot of time working on and considering application performance issues as an APM solution provider. We hope that the IIS Worker Process (w3wp.exe) troubleshooting guide has been useful.</p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/why-asp-net-website-eat-high-cpu-usage/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Fix Server Error in Application ASP.NET</title>
		<link>https://topreviewhostingasp.net/how-to-fix-server-error-in-application-asp-net/</link>
					<comments>https://topreviewhostingasp.net/how-to-fix-server-error-in-application-asp-net/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Wed, 03 Jan 2024 04:17:09 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net error]]></category>
		<category><![CDATA[asp net issue]]></category>
		<category><![CDATA[asp net tips]]></category>
		<category><![CDATA[asp net tutorial]]></category>
		<category><![CDATA[server error in application]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3833</guid>

					<description><![CDATA[When working on an ASP.NET application, you frequently run into the error &#8220;Server Error in &#8216;/&#8217; Application.&#8221; This generic error happens when an ASP.NET application&#8217;s code throws an unhandled exception. Resolution The following actions can be taken to fix the Server Error in &#8216;/&#8217; Application error: Examine the error message. Usually, the error message will [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>When working on an ASP.NET application, you frequently run into the error &#8220;Server Error in &#8216;/&#8217; Application.&#8221; This generic error happens when an ASP.NET application&#8217;s code throws an unhandled exception.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-3834 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/01/server-error-in-application.png" alt="" width="613" height="412" /></p>
<h2 class="wp-block-heading">Resolution</h2>
<p>The following actions can be taken to fix the Server Error in &#8216;/&#8217; Application error:</p>
<p>Examine the error message. Usually, the error message will include some details about what went wrong.</p>
<p>Investigate and explore the stack trace. Stack trace aids in identifying the error and its location.</p>
<p>Enable detailed error messages: By default, ASP.NET is configured to display generic error messages. You can enable detailed error messages by modifying the web.config file. Find the &lt;system.web&gt; section in the file and set the customErrors mode to “Off” like this: This will display detailed error messages that can help you identify the problem</p>
<pre class="wp-block-code"><code>&lt;configuration&gt;
  &lt;system.web&gt;
    &lt;customErrors mode="Off" /&gt;
  &lt;/system.web&gt;</code></pre>
<p>Check your code for any logical or syntactic mistakes that might be the source of the issue.</p>
<p>Look through the web server&#8217;s error logs. Server logs typically contain more details to address Server Error in &#8216;/&#8217; Application error. A lot of information about the error&#8217;s location and description can be found in error logs. They will be simpler to fix.</p>
<p>Rebuild and redeploy your application: Rebuild and redeploy your application to the web server after making any modifications.</p>
<p>In the event that your application makes use of a database, confirm that the database is reachable and that the connection string is accurate.</p>
<p>You can fix the Server Error in &#8216;/&#8217; Application error in your ASP.NET MVC application by following the above steps.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-fix-server-error-in-application-asp-net/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Fix 405 Method Not Allowed ASP.NET Core</title>
		<link>https://topreviewhostingasp.net/how-to-fix-405-method-not-allowed-asp-net-core/</link>
					<comments>https://topreviewhostingasp.net/how-to-fix-405-method-not-allowed-asp-net-core/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Fri, 15 Dec 2023 07:44:39 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[405 method not allowed]]></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[fix 405 method not allowed]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3831</guid>

					<description><![CDATA[While there were many advantages to switching from the classic ASP.NET to ASP.NET Core, there were also some new difficulties for developers. Among these difficulties, sending PUT or DELETE requests to an ASP.NET Core application hosted on IIS and receiving a &#8220;405 Method Not Allowed&#8221; error can be very frustrating. We will delve deeply into [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>While there were many advantages to switching from the classic ASP.NET to ASP.NET Core, there were also some new difficulties for developers. Among these difficulties, sending PUT or DELETE requests to an ASP.NET Core application hosted on IIS and receiving a &#8220;405 Method Not Allowed&#8221; error can be very frustrating. We will delve deeply into the causes of this error and provide a solution in this article.</p>
<h2 class="heading1">Understanding the Error 405</h2>
<p>Understanding the general meaning of the &#8220;405 Method Not Allowed&#8221; error is essential before delving into the details of the ASP.NET Core scenario. The error is an HTTP response status code that says that although the target resource for the specified URI does support the request method, the web server has acknowledged it.</p>
<h2>Common Reasons for ASP.NET Core on IIS Error 405</h2>
<ul>
<li><strong>WebDAV Module</strong>: The WebDAV module is usually to blame when <a href="https://topreviewhostingasp.net/how-to-host-asp-net-core-website-with-asphostportal/" target="_blank" rel="noopener">hosting ASP.NET Core applications on IIS</a>. Using both PUT and DELETE requests, this module is intended for online authoring. Applications that depend on these techniques may be affected if it is not configured properly.</li>
<li><strong>Missing or Incorrect Verb Handlers</strong>: Verb handlers are used by IIS to handle requests. You&#8217;ll see a 405 error if these handlers aren&#8217;t set up properly for PUT or DELETE.</li>
</ul>
<h2 class="heading1">Solution</h2>
<p>If your application does not require WebDAV, you can resolve many issues by simply disabling the WebDAV module. Add the following code to your <strong>web.config</strong> file:</p>
<pre>&lt;system.webServer&gt;
    &lt;modules runAllManagedModulesForAllRequests="false"&gt;
        &lt;remove name="WebDAVModule"/&gt;
    &lt;/modules&gt;
    &lt;handlers&gt;
        &lt;remove name="WebDAV" /&gt;
    &lt;/handlers&gt;
&lt;/system.webServer&gt;</pre>
<h2 class="heading1">Additional Tips</h2>
<ul>
<li><strong>Enable Detailed Error Messages</strong>: Be sure your IIS server is set up to display comprehensive error messages in order to gain a better understanding of the underlying cause. This will give additional background information and might even identify the offending module or handler.</li>
<li><strong>Logging</strong>: Include logging in your application for ASP.NET Core. Comprehensive logs that can provide insights into potential problems can be captured by programs like Serilog or the integrated ILogger.</li>
<li><strong>Check Route Configurations</strong>: Make sure the methods you&#8217;re attempting to invoke are supported by your ASP.NET Core routing configurations.</li>
</ul>
<h2 class="heading1">Conclusion</h2>
<p>With the correct knowledge of its causes and the appropriate resources at your disposal, the &#8220;<strong>405 Method Not Allowed</strong>&#8221; error in an ASP.NET Core application hosted on IIS can be overcome. Never forget that every application is different, so before making any changes to infrastructure or configurations, make sure you test everything thoroughly.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-fix-405-method-not-allowed-asp-net-core/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Make .NET Logs More Efficient</title>
		<link>https://topreviewhostingasp.net/how-to-make-net-logs-more-efficient/</link>
					<comments>https://topreviewhostingasp.net/how-to-make-net-logs-more-efficient/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Mon, 04 Sep 2023 09:22:44 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net core]]></category>
		<category><![CDATA[asp net core efficient]]></category>
		<category><![CDATA[asp net core logs]]></category>
		<category><![CDATA[asp net core tips]]></category>
		<category><![CDATA[asp net tips]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3720</guid>

					<description><![CDATA[Logs are a crucial component of contemporary applications and require special consideration. This is especially true when it comes to web development with ASP.NET Core, where there are practically endless integration possibilities between microservices and APIs, and where keeping track of these connections can be very difficult. When I was looking at some code, I [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Logs are a crucial component of contemporary applications and require special consideration. This is especially true when it comes to web development with ASP.NET Core, where there are practically endless integration possibilities between microservices and APIs, and where keeping track of these connections can be very difficult.</p>
<p>When I was looking at some code, I noticed that the logs were always there, but when I looked closer, I realized that they were frequently irrelevant because they contained little to no significant information. Particularly when there is a problem in the production environment, we often let details that can make a big difference escape due to lack of time, distraction, or ignorance.</p>
<p>In this article, we&#8217;ll go over some crucial issues relating to logs and how to use them efficiently while adhering to best practices and making sure they&#8217;re pertinent for upcoming data analysis.</p>
<h2 id="log-levels-and-.net-logging">1. Log Levels and .NET Logging</h2>
<p>The logging severity levels are defined by the C# Enum named LogLevel in the.NET context. The Assembly contains extension methods that provide log level indication. Microsoft.Extensions.Logging.Abstractions.</p>
<p>The table of log levels in.NET Core is shown below.</p>
<table class="telerik-reTable-4">
<thead>
<tr class="telerik-reTableHeaderRow-4">
<th class="telerik-reTableHeaderEvenCol-4"><strong>Log Level</strong></th>
<th class="telerik-reTableHeaderOddCol-4"><strong>Severity</strong></th>
<th class="telerik-reTableHeaderEvenCol-4"><strong>Extension Method</strong></th>
<th class="telerik-reTableHeaderOddCol-4"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr class="telerik-reTableOddRow-4">
<td class="telerik-reTableEvenCol-4">Trace</td>
<td class="telerik-reTableOddCol-4">0</td>
<td class="telerik-reTableEvenCol-4">LogTrace()</td>
<td class="telerik-reTableOddCol-4">Logs that contain the most detailed messages. These messages may contain sensitive application data. These messages are disabled by default and should never be enabled in a production environment.</td>
</tr>
<tr class="telerik-reTableEvenRow-4">
<td class="telerik-reTableEvenCol-4">Debug</td>
<td class="telerik-reTableOddCol-4">1</td>
<td class="telerik-reTableEvenCol-4">LogDebug()</td>
<td class="telerik-reTableOddCol-4">Logs that are used for interactive investigation during development. These logs should primarily contain information useful for debugging and have no long-term value.</td>
</tr>
<tr class="telerik-reTableOddRow-4">
<td class="telerik-reTableEvenCol-4">Information</td>
<td class="telerik-reTableOddCol-4">2</td>
<td class="telerik-reTableEvenCol-4">LogInformation()</td>
<td class="telerik-reTableOddCol-4">Logs that track the general flow of the application. These logs should have long-term value.</td>
</tr>
<tr class="telerik-reTableEvenRow-4">
<td class="telerik-reTableEvenCol-4">Warning</td>
<td class="telerik-reTableOddCol-4">3</td>
<td class="telerik-reTableEvenCol-4">LogWarning()</td>
<td class="telerik-reTableOddCol-4">Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the application execution to stop.</td>
</tr>
<tr class="telerik-reTableOddRow-4">
<td class="telerik-reTableEvenCol-4">Error</td>
<td class="telerik-reTableOddCol-4">4</td>
<td class="telerik-reTableEvenCol-4">LogError()</td>
<td class="telerik-reTableOddCol-4">Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a failure in the current activity, not an application-wide failure.</td>
</tr>
<tr class="telerik-reTableEvenRow-4">
<td class="telerik-reTableEvenCol-4">Critical</td>
<td class="telerik-reTableOddCol-4">5</td>
<td class="telerik-reTableEvenCol-4">LogCritical()</td>
<td class="telerik-reTableOddCol-4">Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires immediate attention.</td>
</tr>
<tr class="telerik-reTableOddRow-4">
<td class="telerik-reTableEvenCol-4">None</td>
<td class="telerik-reTableOddCol-4">6</td>
<td class="telerik-reTableEvenCol-4">None</td>
<td class="telerik-reTableOddCol-4">Not used for writing log messages. Specifies that a logging category should not write any messages.</td>
</tr>
</tbody>
</table>
<p>These are the log levels, and you should use them in the appropriate situations. For each level, there are some real-world examples below.</p>
<h3 id="usage-examples-for-each-level">Usage Examples for Each Level</h3>
<pre>public class LogService
{
    private readonly ILogger&lt;LogService&gt; _logger;

    public LogService(ILogger&lt;LogService&gt; logger)
    {
        _logger = logger;
    }

    public void ProccessLog()
    {
        var user = new User("John Smith", "smith@mail.com", "Kulas Light", null, null);

        //Trace
        _logger.LogTrace("Processing request from the user: {Name} - {ProccessLog}", user.Name, nameof(ProccessLog));


        //Debug
        var zipcodeDefault = "92998-3874";
        if (user.Zipcode == zipcodeDefault)
            _logger.LogDebug("The zip code is default for the user: {Name} - {ProccessLog}", user.Name, nameof(ProccessLog));


        //Information
        _logger.LogInformation("Starting execution... - {ProccessLog}", nameof(ProccessLog));


        //Warning
        if (string.IsNullOrEmpty(user.Zipcode))
            _logger.LogWarning("The zip code is null or empty for the user: {Name} - {ProccessLog}", user.Name, nameof(ProccessLog));


        //Error
        try
        {
            var zipcodeBase = "92998-3874";
            var result = false;

            if (user.Zipcode == zipcodeBase)
                result = true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex.Message, "Error while processing request from the user: {Name} the zipcode is null or empty. - {ProccessLog}", user.Name, nameof(ProccessLog));
        }


        //Critical
        try
        {
            var userPhone = user.Phone;
        }
        catch (Exception ex)
        {
            _logger.LogCritical(ex.Message, "The phone number is null or empty for the user: {Name}. Please contact immediately the support team! - {ProccessLog}", user.Name, nameof(ProccessLog));
            throw;
        }


        //None
        //Not used for writing log messages
    }
}</pre>
<h2 id="logging-frameworks-or-libraries">2. Logging Frameworks or Libraries</h2>
<p>The functions in Microsoft Logging Assembly can be used on any system, no matter how big or small, and they satisfy the fundamental requirements for logging. However, some situations call for more customizable logs and detailed logs. The development community is aware of and accepts libraries as being helpful in these situations.</p>
<p>Here are some usage examples for Serilog, one of the more well-known libraries.</p>
<h3 id="serilog">Serilog</h3>
<p>The log library that has been downloaded most frequently from the NuGet website is <a href="https://serilog.net/" target="_blank" rel="noopener">Serilog</a>. <a href="https://www.nuget.org/packages/serilog/" target="_blank" rel="noopener">Serilog NuGe</a>t is where you can find it.</p>
<p>Serilog offers diagnostic logging for files, consoles, and a variety of other locations, just like other libraries. It is simple to configure and has a wide range of features for contemporary applications.</p>
<p>Below, a real-world application of its use will be shown along with some of Serilog&#8217;s numerous customization options.</p>
<p><strong>Practical Example</strong></p>
<p>1. Create a new console app with .NET 6.</p>
<p>You can do this through Visual Studio 2022 or via the console with the following command:</p>
<div>
<p><code>dotnet new console --framework net6.0</code></p>
</div>
<div>
<p>2. Install the following libraries in the latest stable version:</p>
<ul>
<li>Serilog</li>
<li>Serilog.Expressions</li>
<li>Serilog.Formatting.Compact</li>
<li>Serilog.Sinks.Console</li>
<li>Serilog.Sinks.File</li>
</ul>
<p>3. Create a class called Offer and paste this code in it:</p>
</div>
<div class="code-toolbar">
<pre class="language-csharp" tabindex="0"><code class="prism language-csharp"><span class="token keyword">public</span> <span class="token keyword">record</span> <span class="token class-name">Offer</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> Id<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> ProductId<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> Description<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">decimal</span></span> Value<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">decimal</span></span> Quantity<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</div>
<div>4. Replace the Program class code with the code below:</div>
<pre>using Serilog;
using Serilog.Templates;

ExecuteLogs();

void ExecuteLogs()
{
    LogToConsole();
    LogToFile();
}

void LogToConsole()
{
    var offer = FillOffer();

    Log.Logger = new LoggerConfiguration()
     .Enrich.WithProperty("offerId", offer.Id)
     .Enrich.WithProperty("productId", offer.ProductId)
     .Enrich.WithProperty("quantity", offer.Quantity)
     .WriteTo.Console(new ExpressionTemplate("{ {@t, @mt, @l: if @l = 'Information' then undefined() else @l, @x, ..@p} }\n"))
     .CreateLogger();

    Log.Information("Information about the Offer");
}

void LogToFile()
{
    var offer = FillOffer();

    Log.Logger = new LoggerConfiguration()
     .Enrich.WithProperty("offerId", offer.Id)
     .Enrich.WithProperty("productId", offer.ProductId)
     .Enrich.WithProperty("quantity", offer.Quantity)
     .WriteTo.File(new ExpressionTemplate(
         "{ {@t, @mt, @l: if @l = 'Information' then undefined() else @l, @x, ..@p} }\n"),
            "Logs\\log.txt",
                 rollingInterval: RollingInterval.Day)
     .CreateLogger();

    Log.Information("Information about the Offer");
}

Offer FillOffer() =&gt;
        new Offer(5488, 100808, "Book", 109, 3);</pre>
<div>5. Execute the app</div>
<div></div>
<div>If you followed the steps above, you will see the following result in the application console:</div>
<div></div>
<div>
<p><code>{"@t":"2021-11-19T18:53:57.9627579-03:00","@mt":"Information about the Offer","offerId":5488,"productId":100808,"quantity": 3}</code></p>
</div>
<p>And in the folder: “\bin\Debug\net6.0\Logs” is the created file. Inside it will be the same data that was displayed in the console.</p>
<p>In this example we created two methods:</p>
<ul>
<li>“LogToConsole()” – It creates an object called “Offer,” then uses a new instance of “LoggerConfiguration” and adds the properties values to logging with the method “Enrich.WithProperty.” Then the method “WriteTo.Console” displays the data logging in the console, and makes the configuration of the template through the class “ExpressionTemplate.”</li>
<li>“LogToFile()” – It does the same as the previous method, but uses the “WriteTo.File” method to create a “Logs” folder if it doesn’t exist, and inside it a text file that will store the log data. The “rollingInterval” rule determines the interval in which a new file will be created—in this example, one day—that is, the logs will be written to the same file until the day ends, and then a new file will be created.</li>
</ul>
<p>Serilog was only briefly used in this demonstration, but it has a lot of useful features. Explore them at your leisure.</p>
<h2 id="best-practices-and-recommendations">3. Best Practices and Recommendations</h2>
<h3 id="structured-logs">Structured Logs</h3>
<p>When an application uses the Microsoft Logging Assembly or more sophisticated filtering to look for logs, the creation of structured logs is advised. The log recording mechanism needs to receive the string containing the placeholders and their values separately, so it is necessary.</p>
<p>Here&#8217;s an illustration of a structured log:</p>
<p><code>_logger.LogWarning( "The zip code is null or empty for the user: {Name}", user.Name;</code></p>
<p>String interpolation is a viable option, but you should make sure the registration service is set up to still have access to the message template and property values after the replacement.</p>
<p>An illustration of a structured log using string interpolation can be found below:</p>
<p><code>_logger.LogWarning( $"The zip code is null or empty for the user: {user.Name}";</code></p>
<h3 id="enable-only-appropriate-logs-in-production">Enable Only Appropriate Logs in Production</h3>
<p>You should take into account the actual requirements for using each of the log levels before publishing something in the production environment. For instance, excessively detailed logs may cause the server to become overloaded or the system to operate slowly.</p>
<p>So, before publishing anything, it&#8217;s a good idea to review all the logs and keep only the ones that are pertinent and won&#8217;t cause any sort of overhead. In a production setting, trace and debug logs must be disabled.</p>
<h3 id="using-a-third-party-logging-library">Using a Third-Party Logging Library</h3>
<p>Always ask the client you&#8217;re working with if they use a third-party library and what it is before beginning a new project because you don&#8217;t want to waste your time on something that won&#8217;t be put into production because it uses private property.</p>
<h3 id="logging-sensitive-information">Logging Sensitive Information</h3>
<p>Never include private or delicate data in production logs, such as user-related information like passwords or credit card numbers, or any data pertaining to something that cannot be made public. Additionally to being accessible to anyone with access to logged data, this information typically lacks any encryption, making it vulnerable to disclosure in the event that a hacker attack is made against the system.</p>
<h3 id="writing-relevant-log-messages">Writing Relevant Log Messages</h3>
<p>The presence of a log message at a crucial point in the code does not guarantee that the system is ready for a thorough analysis, as its use would be unnecessary if the message didn&#8217;t make much sense in that situation.</p>
<p>Therefore, when writing log messages, consider what would be the most crucial data for a later analysis of the execution. For instance, always include the message produced by the &#8220;Catch&#8221; method in messages inside exception blocks.</p>
<p>Utilizing the name of the method used when writing the log is another suggestion that can be seen in the example below. In the example below, we are using the command &#8220;nameof(ProccessLog)&#8221; to record the name of the method that is responsible for execution.</p>
<pre>public void ProccessLog()
{
        try
        {
        //execution...
        }
        catch (Exception ex)
        {
 //The exception message "ex.Message" is being used in the log

            _logger.LogError(ex.Message, "Error while processing request from the user: {Name} the zipcode is null or empty. - {ProccessLog}", user.Name, nameof(ProccessLog));
        }
}</pre>
<h2 id="conclusion">Conclusion</h2>
<p>We discussed some helpful writing techniques for effective logs in C# and.NET in this article. There are no hard-and-fast guidelines for writing logs; it all depends on the environment in which you are developing. Nevertheless, if you follow these suggestions, your code will undoubtedly get much better.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-make-net-logs-more-efficient/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Fix 401 Error ASP.NET Website?</title>
		<link>https://topreviewhostingasp.net/how-to-fix-401-error/</link>
					<comments>https://topreviewhostingasp.net/how-to-fix-401-error/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Wed, 30 Aug 2023 06:21:01 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[401 error]]></category>
		<category><![CDATA[asp net error]]></category>
		<category><![CDATA[asp net tips]]></category>
		<category><![CDATA[asp net tutorial]]></category>
		<category><![CDATA[how to fix 401 error]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3697</guid>

					<description><![CDATA[It can be very frustrating to receive a 401 error on your WordPress website. Reloading the page could occasionally be helpful. Consequently, what does a 401 Hypertext Transfer Protocol (HTTP) response code mean? This error may be brought on by a browser issue, but in a few uncommon circumstances, it might also be a server-side [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>It can be very frustrating to receive a 401 error on your WordPress website. Reloading the page could occasionally be helpful.</p>
<p>Consequently, what does a 401 Hypertext Transfer Protocol (HTTP) response code mean?</p>
<p>This error may be brought on by a browser issue, but in a few uncommon circumstances, it might also be a server-side issue.</p>
<p>The good news is that 401 error codes are frequently simple to resolve. In fact, if you can locate the error&#8217;s cause, you might be able to resolve the issue on your own.</p>
<p>Learn the reasons why 401 errors occur as well as how to fix and avoid them by reading on.</p>
<h2 id="h-what-is-a-401-error">What is a 401 error?</h2>
<p><img loading="lazy" decoding="async" class="size-full wp-image-3698 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/401-error.webp" alt="" width="518" height="304" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/401-error.webp 518w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/401-error-300x176.webp 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/401-error-50x29.webp 50w" sizes="(max-width: 518px) 100vw, 518px" /></p>
<p>This error message may appear when you try to access a website using an invalid URL, a username or password that isn&#8217;t correct, or an out-of-date browser cache.</p>
<p>Most of the time, repairing client-side errors can quickly fix the problem. In other instances, the problem might be server-side, where the web server denies a client&#8217;s attempts to access a requested resource even though those attempts are legitimate.</p>
<p>This could be the result of willful modifications a user made to the server or an unintentional error during the authentication process.</p>
<p>When you run into this issue, an error message will appear in your browser. The 401 error appears under various titles on various platforms. Examples of what you might see are as follows:</p>
<ul>
<li>401 authorization required.</li>
<li>401 unauthorized error.</li>
<li>Error 401 unauthorized.</li>
<li>HTTP error 401 – unauthorized.</li>
<li>HTTP 401.</li>
<li>Access denied.</li>
</ul>
<p>Here, the error code itself—not the text variations around it—is what matters most. No matter what your browser shows you, the error code lets you know what the issue is. It&#8217;s also essential to finding a solution.</p>
<h2>Typical reasons for 401 errors on ASP.NET websites</h2>
<p><img loading="lazy" decoding="async" class="wp-image-3699 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-min-scaled.jpg" alt="" width="564" height="376" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-min-scaled.jpg 2560w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-min-300x200.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-min-1024x683.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-min-768x512.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-min-1536x1024.jpg 1536w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-min-2048x1365.jpg 2048w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-min-50x33.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-min-750x500.jpg 750w" sizes="(max-width: 564px) 100vw, 564px" /></p>
<p>Let&#8217;s take a closer look at the possible causes of the 401 error code on your ASP.NET website before discussing possible fixes.</p>
<h3>1. Incorrect URLs</h3>
<p>Typos happen to everyone occasionally. Incorrectly entering a URL (Uniform Resource Locator) can result in issues ranging from 401 errors to misdirection.</p>
<p>How about if the URL is accurate? You might be trying to access an old page that has been moved or deleted.</p>
<p>In either scenario, the client tries to access the resource you want via an illegal or invalid path, and the server may reject your request.</p>
<h3>2. Expired cache and cookies</h3>
<p>Cookies &#8220;remember&#8221; your device and browser by &#8220;remembering&#8221; the <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies" target="_blank" rel="noopener">HTTP cookies</a> that your browser uses to store browser data in your memory. A quick browsing experience depends on cookies and the browser cache.</p>
<p>Today&#8217;s cookies also save your level of authentication. As a result, you won&#8217;t need to log in each time you access a website or social media platform. Browser cookies make sure the server sends you information based on your authorization level while keeping your online session active.</p>
<p>You might get a 401 Unauthorized error due to improper authentication if your cookies expire or if your cache is corrupted or cleared.</p>
<h3>3. Firewall and plugin configurations</h3>
<p>Instances of trying to access specific pages may result in 401 errors if you&#8217;ve recently installed a firewall or new plugin on your ASP.NET website.</p>
<p>For instance, even if you have administrator access, some security tools may completely take over your website and limit access to particular pages.</p>
<p>Any login attempts might be interpreted as malicious activity by the tools because it runs diagnostics on your website to improve it. This might result in a 401 error page appearing on your website.</p>
<h3>4. Protected URLs</h3>
<p>At the server level, access to particular URLs may be strictly controlled or managed. These restricted resources are only accessible to authorized personnel. In this situation, accessing the URL from an unauthorized web browser might result in a 401 error.</p>
<h2 id="h-troubleshooting-401-errors">Troubleshooting 401 errors</h2>
<p><img loading="lazy" decoding="async" class="wp-image-3700 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min.jpg" alt="" width="514" height="514" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min.jpg 2000w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min-300x300.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min-1024x1024.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min-150x150.jpg 150w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min-768x768.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min-1536x1536.jpg 1536w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min-50x50.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min-70x70.jpg 70w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min-127x127.jpg 127w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min-476x476.jpg 476w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/website-error-2-min-125x125.jpg 125w" sizes="(max-width: 514px) 100vw, 514px" /></p>
<p>A 401 error is frequently a client-side rather than a server-side problem, as we have already discussed. As a result, fixing it is frequently simple. Here are some options you could try:</p>
<h3>1. Verify the URL</h3>
<p>Verifying that the URL being used is valid or correct is one of the simplest solutions for a 401 error. Servers reject attempts to access a website from invalid or incorrect URLs in order to secure it.</p>
<p>Be sure to spell check the URL first. Verify that your target URL contains the proper extension, hyphens, and special characters. You should now be able to access the website without any issues if everything looks good.</p>
<p>Check to see if the page address has changed since your last access if you are still receiving a 401 error. It could have been relocated or removed. Find the page you want to access by going back to the homepage. This is a common way to discover the correct link.</p>
<h3>2. Check your login credentials</h3>
<p>You should also double-check your login information. This error can appear on a page when you try to access a website with an incorrect username or password. Make sure your authentication credentials are up to date and that you are using the username and password appropriately.</p>
<p>You can try to reset or recover the password if you&#8217;ve forgotten it.</p>
<h3>3. Clear and reload the browser cache and cookies</h3>
<p>The majority of contemporary browsers, as was mentioned above, save your authentication status in cookies and the website&#8217;s cache. In this manner, you can always continue where you left off.</p>
<p>Since most page files are temporarily stored in your device&#8217;s memory to maintain the status of your logins, the cache also aids in accelerating browsing.</p>
<p><img loading="lazy" decoding="async" class="wp-image-3701 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/clear-data.png" alt="" width="546" height="497" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/clear-data.png 1508w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/clear-data-300x273.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/clear-data-1024x932.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/clear-data-768x699.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/clear-data-50x45.png 50w" sizes="(max-width: 546px) 100vw, 546px" /></p>
<p>A 401 error is frequently generated when trying to access a web app with expired cookies.</p>
<p>Clearing all cookies from the problematic website and refreshing the page are simple fixes for this. You can also reload the page and clear your browsing history. This might entail starting a fresh session.</p>
<p>You can also delete all cache files and make room for new files and logins by clearing the cache. Often, doing so resolves 401 unauthorized access errors.</p>
<p>Depending on your browser, there are different ways to clear cookies.</p>
<h3>4. Check for DNS changes</h3>
<p>Changes to your domain name server (DNS) can result in 401 errors, although they are less common than other issues. Your device typically has DNS records to aid in matching URLs to IP addresses.</p>
<p>You might need to flush your DNS cache if it contains outdated or invalid URLs and IP addresses.</p>
<p>Using the command line, you can force your device to refresh and authenticate the URLs as well as clear the DNS cache.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-3702 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/flushdns.jpg" alt="" width="574" height="251" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/flushdns.jpg 574w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/flushdns-300x131.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/flushdns-50x22.jpg 50w" sizes="(max-width: 574px) 100vw, 574px" /></p>
<p>Run the <strong>ipconfig/flushdns</strong> command from the Windows command prompt. Windows will indicate that the DNS cache has been flushed by displaying a message.</p>
<p>Run the Mac&#8217;s <strong>sudo killall -HUP mDNSResponder</strong> command.</p>
<h3>5. Disable passwords on pages</h3>
<p>It may be possible to fix this error code by disabling password protection on some of your website&#8217;s pages.</p>
<h3>6. Check the WWW-Authenticate header response</h3>
<p>It could be a more serious server-side issue if none of these troubleshooting techniques worked.</p>
<p>Check the WWW-Authenticate header on your website as the next step. Access to administrators is necessary for this.</p>
<p>A WWW-Authenticate header field with at least one challenge is sent to the target resource when a server generates a 401 response. A browser must frequently pass this header&#8217;s fixed authentication process in order to access the desired page.</p>
<p>You can find the issue and resolve it by comprehending the response and the needed authentication strategy.</p>
<p>To access the WWW-Authenticate header:</p>
<ol>
<li>Open the problematic page in your browser. If you’re using Google Chrome, right-click the page and select <strong>inspect. </strong>Click <strong>Shift + Control + C</strong> to open the browser console on Firefox.</li>
<li>Select the entry with the 401 error message under the <strong>network </strong>tab.</li>
<li>Click the <strong>headers</strong><strong> </strong>tab. Under the WWW-Authenticate entry in the <strong>response </strong><strong>headers</strong><strong> </strong>section, find the server’s authentication method that allows access to the webpage.</li>
</ol>
<p>Once you&#8217;ve accessed this page, you can identify the error and learn how to fix the authentication issue.</p>
<h3>7. Contact your host</h3>
<p>If you&#8217;ve tried everything but it hasn&#8217;t worked, you can ask your hosting company for assistance. The technical support staff of your host can investigate your website and assist you in troubleshooting 401 and other HTTP errors.</p>
<h2>Conclusion</h2>
<p>Although a 401 HTTP response code can be inconvenient, once you comprehend how it functions, you can fix the problem on your own.</p>
<p>You might be using an incorrect URL or login information; you can fix those problems from your browser. You might also need to log back into your website after clearing the cache, cookies, and history from your browser. Try the more involved steps on this list if these don&#8217;t resolve the issue.</p>
<p>Looking for reliable ASP.NET hosting partner? Check out these <a href="https://topreviewhostingasp.net/best-cheap-asp-net-core-hosting/" target="_blank" rel="noopener">best ASP.NET hosting provider</a> that help your website work faster and secure!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-fix-401-error/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Build Multilingual Applications in ASP.NET Core</title>
		<link>https://topreviewhostingasp.net/how-to-build-multilingual-applications-in-asp-net-core/</link>
					<comments>https://topreviewhostingasp.net/how-to-build-multilingual-applications-in-asp-net-core/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Fri, 04 Aug 2023 08:19:48 +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[localization asp net core]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3656</guid>

					<description><![CDATA[Every website owner wants to reach a larger audience. We typically create web applications that support multiple languages and deliver localized content according to user region and culture to realize this dream. With its extensive support for localization and globalization, ASP.NET Core has a number of built-in features that make it simple for developers to [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Every website owner wants to reach a larger audience. We typically create web applications that support multiple languages and deliver localized content according to user region and culture to realize this dream. With its extensive support for localization and globalization, ASP.NET Core has a number of built-in features that make it simple for developers to create web applications that support multiple languages. I&#8217;ll walk you through a few of the common features you can use to deliver localized content in accordance with user preference in this tutorial.</p>



<h2 class="wp-block-heading">Configuring Localization in ASP.NET Core</h2>



<p>The RequestLocalizationMiddleware middleware must be configured in order to configure localization in ASP.NET Core, which uses middleware to configure the majority of its cross-cutting features. Based on the data sent by the client, this middleware enables the automatic setting of the culture for HTTP requests.</p>



<p>Create a new ASP.NET Core MVC Web Application called AspNetCoreLocalizationDemo in Visual Studio 2019 by clicking the &#8220;New&#8221; button. Open the Startup.cs file and call the AddLocalization method to configure the localization middleware. The localization services are added to the services container by the AddLocalization method. The relative path under the application root where the resource files are located is specified by the ResourcePath property.</p>



<pre class="wp-block-code"><code>services.AddLocalization(options =&gt;
{
    options.ResourcesPath = "Resources";
});</code></pre>



<p>Additionally, the AddViewLocalization method, which we will use later in this tutorial, adds support for localized view files.</p>



<pre class="wp-block-code"><code>services.AddControllersWithViews()
    .AddViewLocalization();</code></pre>



<p>Note that the AddDataAnnotationsLocalization method in ASP.NET Core also adds support for localized DataAnnotations.</p>



<p>Next, we must decide which cultures our application will support and which one will serve as the default culture. Let&#8217;s configure these three cultures as follows since I want to support the French, German, and English languages in this tutorial:</p>



<pre class="wp-block-code"><code>services.Configure&lt;RequestLocalizationOptions&gt;(options =&gt;
{
    options.DefaultRequestCulture = new RequestCulture("en-US");
 
    var cultures = new CultureInfo[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("de-DE"),
        new CultureInfo("fr-FR")
    };
 
    options.SupportedCultures = cultures;
    options.SupportedUICultures = cultures;
});</code></pre>



<p>Following is the complete code of the <strong>ConfigureServices </strong>method.</p>



<pre class="wp-block-code"><code>public void ConfigureServices(IServiceCollection services)
{
    services.AddLocalization(options =&gt;
    {
        options.ResourcesPath = "Resources";
    });
 
    services.AddControllersWithViews()
        .AddViewLocalization();
 
    services.Configure&lt;RequestLocalizationOptions&gt;(options =&gt;
    {
        options.DefaultRequestCulture = new RequestCulture("en-US");
 
        var cultures = new CultureInfo[]
        {
            new CultureInfo("en-US"),
            new CultureInfo("de-DE"),
            new CultureInfo("fr-FR")
        };
 
        options.SupportedCultures = cultures;
        options.SupportedUICultures = cultures;
    });
}</code></pre>



<p>The localization middleware must be enabled using the UseRequestLocalization method as the last configuration step.</p>



<pre class="wp-block-code"><code>app.UseRequestLocalization();</code></pre>



<p>The RequestLocalizationOptions object we configured above is initialized by the UseRequestLocalization method. RequestCultureProvider is a concept in the RequestLocalizationOptions that decides the culture information in each request. We will cover these providers in greater detail later in this tutorial. The RequestLocalizationOptions class configures the QueryStringRequestCultureProvider, CookieRequestCultureProvider, and AcceptLanguageHeaderRequestCultureProviders as default providers. The list of RequestCultureProvider is enumerated when requests arrive at the server, and the first provider that can successfully identify the request culture is used. The DefaultRequestCulture property setting will be used in the event that none of the providers are able to identify the request culture.</p>



<pre class="wp-block-code"><code>options.DefaultRequestCulture = new RequestCulture("en-US");</code></pre>



<p>The foundational localization settings for our application are now set up. The location and naming guidelines for the resource files must be chosen next.</p>



<h2 class="wp-block-heading">Resource Files Naming Conventions and Location</h2>



<p>We can separate the localizable resources, such as strings, icons, images, etc., from the source code by using a resource (.resx) file. We typically include information about the culture in the file name when creating resource files for various languages and cultures. For instance, the file name for a resource file to store resources in English would be MyResourceFile.en.resx. The file name will be MyResourceFile.en-US.resx if you want to make a separate resource file for US English. You can right-click on the folder where you want to create the resource file and select Add &gt; New Item from the menu in Visual Studio to create a new resource file.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="941" height="653" class="wp-image-3657" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/add-asp-net-core.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/add-asp-net-core.png 941w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/add-asp-net-core-300x208.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/add-asp-net-core-768x533.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/add-asp-net-core-50x35.png 50w" sizes="(max-width: 941px) 100vw, 941px" /></figure></div>


<p>The full type name of the class is used by ASP.NET Core localization to find the resource files in the project. For instance, the resource file name would be as follows if we were to create French language resources for the HomeController of our AspNetCoreLocalizationDemo application.</p>



<pre class="wp-block-code"><code>AspNetCoreLocalizationDemo.Controllers.HomeController.fr-FR.resx</code></pre>



<p>Another strategy is to save the resource file next to the HomeController class with the name HomeController.fr-FR.resx. The English, French, and German resource files that were created alongside the HomeController class are displayed in the following screenshot.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="338" height="491" class="wp-image-3658" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller.png 338w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-207x300.png 207w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-34x50.png 34w" sizes="(max-width: 338px) 100vw, 338px" /></figure></div>


<p>Please be aware that the ResourcesPath property has been set as follows in the Startup.cs file&#8217;s ConfigureServices method:</p>



<pre class="wp-block-code"><code>options.ResourcesPath = "Resources";</code></pre>



<p>It implies that we can now create the Resources folder and place all resource files in it in the project root folder. The resource files can also be organized using nested folders with the same naming patterns. For instance, we could make a Controllers folder inside the Resources folder and move the three HomeController-related resource files there.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="310" height="462" class="wp-image-3659" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/resource-files.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/resource-files.png 310w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/resource-files-201x300.png 201w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/resource-files-34x50.png 34w" sizes="(max-width: 310px) 100vw, 310px" /></figure></div>


<p>Depending on how you want to organize your resource files, you can either use the dot naming convention or copy the file path. If you want to mimic the path, your resource file will be located at Resources/Controllers/HomeController.en-US.resx, whereas if you want to use the dot naming convention, you will name your file as Resources/Controllers.HomeController.en-US.resx.</p>



<p>Let&#8217;s add some string resources to the three resource files by opening them all. The two English language string resources added to the HomeController.en-US.resx resource file are shown in the following screenshot.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="583" height="217" class="wp-image-3660" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-2.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-2.png 583w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-2-300x112.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-2-50x19.png 50w" sizes="(max-width: 583px) 100vw, 583px" /></figure></div>


<p>The following screenshot shows the two French language string resources added in HomeController.fr-FR.resx resource file.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" class="wp-image-3661" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-3.png" alt="" width="584" height="173" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-3.png 584w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-3-300x89.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-3-50x15.png 50w" sizes="(max-width: 584px) 100vw, 584px" /></figure></div>


<p>The following screenshot shows the two English language string resources added in HomeController.de-DE.resx resource file.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="589" height="185" class="wp-image-3662" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-4.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-4.png 589w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-4-300x94.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-4-50x16.png 50w" sizes="(max-width: 589px) 100vw, 589px" /></figure></div>


<h2 class="wp-block-heading">Introducing .NET Core Localizer Services</h2>



<p>Localized services are a new concept introduced by.NET Core to increase developer productivity. These services can give you access to the resources saved in resource files and can be injected using dependency injection. These are the three localizer services:</p>



<ol type="1">
<li>IStringLocalizer or IStringLocalizer&lt;T&gt;</li>
<li>IHtmlLocalizer or IHtmlLocalizer&lt;T&gt;</li>
<li>IViewLocalizer</li>
</ol>



<h3 class="wp-block-heading">Using IStringLocalizer Service</h3>



<p>A service that offers localized strings is represented by IStringLocalizer. As shown in the code snippet below, let&#8217;s inject the IStringLocalizerT&gt; into the application&#8217;s HomeController.</p>



<p><strong>HomeController.cs</strong></p>



<pre class="wp-block-code"><code>public class HomeController : Controller
{
    private readonly IStringLocalizer&lt;HomeController&gt; _stringLocalizer;
 
    public HomeController(IStringLocalizer&lt;HomeController&gt; stringLocalizer)
    {
        _stringLocalizer = stringLocalizer;
    }
 
    public IActionResult Index()
    {
        ViewData["PageTitle"] = _stringLocalizer["page.title"].Value;
        ViewData["PageDesc"] = _stringLocalizer["page.description"].Value;
 
        return View();
    } 
}</code></pre>



<p>When the localizer is ready, you can use its indexer to retrieve the localized strings from the resource file that correspond to the current cultural context. Using the keys page.title and page.description, we are retrieving localized strings in the aforementioned example and storing them in a ViewData object. In our razor view, we can then access this ViewData object and display the localized strings as displayed in the example below.</p>



<p><strong>Index.cshtml</strong></p>



<pre class="wp-block-code"><code>&lt;div class="text-center"&gt;
    &lt;h1 class="display-4"&gt;
        @ViewData["PageTitle"]
    &lt;/h1&gt;
    &lt;p&gt;
        @ViewData["PageDesc"]
    &lt;/p&gt;
&lt;/div&gt;</code></pre>



<p>If you run the application, the localized strings in English will appear on the page.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="667" height="294" class="wp-image-3663" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-demo.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-demo.png 667w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-demo-300x132.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-demo-50x22.png 50w" sizes="(max-width: 667px) 100vw, 667px" /></figure></div>


<p>By directly injecting the IStringLocalizerT&gt; into your razor views, as shown in the following code snippet, you can avoid having to pass strings from controllers to views using the ViewData object and cut down on some of the code from the above example.</p>



<p><strong>Index.cshtml</strong></p>



<pre class="wp-block-code"><code>@using AspNetCoreLocalizationDemo.Controllers
@using Microsoft.Extensions.Localization
 
@inject IStringLocalizer&lt;HomeController&gt; Localizer
 
&lt;div class="text-center"&gt;
    &lt;h1 class="display-4"&gt;
        @Localizer["page.title"]
    &lt;/h1&gt;
    &lt;p&gt;
        @Localizer["page.description"]
    &lt;/p&gt;
&lt;/div&gt;</code></pre>



<h3 class="wp-block-heading">Using IHtmlLocalizer Service</h3>



<p>Let&#8217;s introduce the HTML bold tag to your string to add some HTML content, as seen in the screenshot below.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="565" height="176" class="wp-image-3664" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-5.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-5.png 565w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-5-300x93.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-5-50x16.png 50w" sizes="(max-width: 565px) 100vw, 565px" /></figure></div>


<p>You will notice that the browse does not display the formatted string if you run the application right away. This is due to the IStringLocalizer&#8217;s inability to encode the HTML that is present in the strings. Utilize IHtmlLocalizer, which will HTML-encode the resource string&#8217;s HTML characters but not the resource string itself.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="385" height="153" class="wp-image-3665" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage.png 385w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage-300x119.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage-50x20.png 50w" sizes="(max-width: 385px) 100vw, 385px" /></figure></div>


<p>The injection and use of IHtmlLocalizer are very similar to those of IStringLocalizer. The following shows how IHtmlLocalizer is used in the razor view.</p>



<p><strong>Index.cshtml</strong></p>



<pre class="wp-block-code"><code>@using AspNetCoreLocalizationDemo.Controllers
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Localization
 
@inject IStringLocalizer&lt;HomeController&gt; Localizer
@inject IHtmlLocalizer&lt;HomeController&gt; HtmlLocalizer
 
&lt;div class="text-center"&gt;
    &lt;h1 class="display-4"&gt;
        @Localizer["page.title"]
    &lt;/h1&gt;
    &lt;p&gt;
        @HtmlLocalizer["page.description"]
    &lt;/p&gt;
&lt;/div&gt;</code></pre>



<p>Restart the application, and the word &#8220;home page&#8221; should appear bold this time.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="337" height="163" class="wp-image-3666" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage-2.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage-2.png 337w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage-2-300x145.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage-2-50x24.png 50w" sizes="(max-width: 337px) 100vw, 337px" /></figure></div>


<h3 class="wp-block-heading">Using IViewLocalizer Service</h3>



<p>A view receives localized strings from the IViewLocalizer service. The naming convention and location of the resource files become even more crucial when we use the IViewLocalizer service. This is so that the resource file can be located using the view file name rather than the default implementation of IViewLocalizer. This also implies that IViewLocalizer cannot use the global shared resource files.</p>



<p>Create a resource file called Index.en-US.resx at the ResourcesViewsHome folder with the name Index.razor since our view file&#8217;s name is Index.razor, as shown in the following screenshot.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="290" height="307" class="wp-image-3667" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/resource-files-2.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/resource-files-2.png 290w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/resource-files-2-283x300.png 283w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/resource-files-2-47x50.png 47w" sizes="(max-width: 290px) 100vw, 290px" /></figure></div>


<p>For demonstration purposes, let’s add a different string in the <strong>Index.en-US.resx</strong> file.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="363" height="166" class="wp-image-3668" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-6.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-6.png 363w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/home-controller-6-300x137.png 300w" sizes="(max-width: 363px) 100vw, 363px" /></figure></div>


<p>To use IViewLocalizer, inject it in the Index.cshtml file as shown in the code snippet below.</p>



<p><strong>Index.cshtml</strong></p>



<pre class="wp-block-code"><code>@using AspNetCoreLocalizationDemo.Controllers
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Localization
 
@inject IStringLocalizer&lt;HomeController&gt; Localizer
@inject IHtmlLocalizer&lt;HomeController&gt; HtmlLocalizer
@inject IViewLocalizer ViewLocalizer
 
&lt;div class="text-center"&gt;
    &lt;h1 class="display-4"&gt;
        @Localizer["page.title"]
    &lt;/h1&gt;
    &lt;p&gt;
        @HtmlLocalizer["page.description"]
    &lt;/p&gt;
    &lt;p&gt;
        @ViewLocalizer["view.breadcrumb.text"]
    &lt;/p&gt;
&lt;/div&gt;</code></pre>



<p>When you rerun the application, you should see the words &#8220;Home &#8211; Index&#8221; displayed on the page thanks to the IViewLocalizer service.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="358" height="191" class="wp-image-3669" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage-3.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage-3.png 358w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage-3-300x160.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-homepage-3-50x27.png 50w" sizes="(max-width: 358px) 100vw, 358px" /></figure></div>


<p>You can add more languages and set any language as your default language if you&#8217;re using the Chrome browser by going to Settings. For instance, I added the German language to the screenshot below and instructed the Chrome browser to display everything in German.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="719" height="455" class="wp-image-3670" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/language.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/language.png 719w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/language-300x190.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/language-50x32.png 50w" sizes="(max-width: 719px) 100vw, 719px" /></figure></div>


<p>Run your application right away to see the translated strings from the German language resource file displayed on the page.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="701" height="323" class="wp-image-3671" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-german-language.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-german-language.png 701w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-german-language-300x138.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/display-german-language-50x23.png 50w" sizes="(max-width: 701px) 100vw, 701px" /></figure></div>


<h2 class="wp-block-heading">Overview of Default Request Culture Providers</h2>



<p>There are some request culture providers included right out of the box when we configure and use the request localization in.NET Core. In our application, we have the option to either use these default providers or define our own unique request culture provider. The list of default request culture providers is provided below.</p>



<ol type="1">
<li>AcceptLanguageHeaderRequestCultureProvider</li>
<li>QueryStringRequestCultureProvider</li>
<li>CookieRequestCultureProvider</li>
</ol>



<h3 class="wp-block-heading">AcceptLanguageHeaderRequestCultureProvider</h3>



<p>Web browsers automatically send the client culture along with each request using the Accept-Header, which is typically set to the user&#8217;s native language. The tools in the Chrome browser make it simple to see this header and its value. For instance, because I added the German language in the earlier section, my browser is currently displaying both en-US and de-DE.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="829" height="594" class="wp-image-3672" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/header-chrome-browser.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/header-chrome-browser.png 829w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/header-chrome-browser-300x215.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/header-chrome-browser-768x550.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/header-chrome-browser-50x36.png 50w" sizes="(max-width: 829px) 100vw, 829px" /></figure></div>


<h3 class="wp-block-heading">QueryStringRequestCultureProvider</h3>



<p>To override the culture, you can pass a query string to this provider. Because the query string&#8217;s culture value can be changed, developers can quickly test or debug various cultures. Culture and ui-culture parameters can be passed to the query string provider. One of the two culture or ui-culture values may be passed in place of the other, and the query string provider will set both values using that value. By including fr-FR in the query string, let&#8217;s test this provider in our application. You&#8217;ll notice that the page&#8217;s contents are converted to French strings right away.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="607" height="291" class="wp-image-3673" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/french-language.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/french-language.png 607w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/french-language-300x144.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/french-language-50x24.png 50w" sizes="(max-width: 607px) 100vw, 607px" /></figure></div>


<p>Let’s change the value to <strong>de-DE</strong> and the page contents will update accordingly.</p>



<p>&nbsp;</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="607" height="287" class="wp-image-3674" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/german-query-link.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/german-query-link.png 607w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/german-query-link-300x142.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/german-query-link-50x24.png 50w" sizes="(max-width: 607px) 100vw, 607px" /></figure></div>


<h3 class="wp-block-heading">CookieRequestCultureProvider</h3>



<p>To establish the culture, most production apps typically use cookies. The cookie with the name is used by the CookieRequestCultureProvider.AspNetCore.Culture by default, and you can use the tools in your browser to see how the cookie value is formatted. c=%LANGCODE%|uic=%LANGCODE%, where c stands for Culture and uic for UICulture, is the cookie format.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="616" height="348" class="wp-image-3675" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/culture-cookie.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/culture-cookie.png 616w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/culture-cookie-300x169.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/culture-cookie-50x28.png 50w" sizes="(max-width: 616px) 100vw, 616px" /></figure></div>


<h2 class="wp-block-heading">Switching Language in ASP.NET Core Applications</h2>



<p>Now that we are aware of the standard methods for changing the ASP.NET Core application culture, such as Accept-Header, the query string, and cookies, let&#8217;s build a sample demo that will give the application&#8217;s end user the option to switch to a different language at runtime using one of the standard methods mentioned above. To display supported cultures in a dropdown at the top of the page, we must first obtain the list of supported cultures. The following code snippet should be added to the top of the _Layout.cshtml file after opening it.</p>



<p><strong>_Layout.cshtml</strong></p>



<pre class="wp-block-code"><code>@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Localization
@using Microsoft.Extensions.Options
 
@inject IOptions&lt;RequestLocalizationOptions&gt; LocOptions
 
@{
    string returnUrl = ViewContext.HttpContext.Request.Path;
 
    var requestCulture = Context.Features.Get&lt;IRequestCultureFeature&gt;();
    var cultureItems = LocOptions.Value.SupportedUICultures
        .Select(c =&gt; new SelectListItem { Value = c.Name, Text = c.DisplayName })
        .ToList();
}</code></pre>



<p>Access to the collection of feature interfaces for the current request is made possible by the HttpContext&#8217;s Features property. We are particularly interested in the IRequestCultureFeature, which stands for the feature that conveys details about the culture of the active request.</p>



<pre class="wp-block-code"><code>var requestCulture = Context.Features.Get&lt;IRequestCultureFeature&gt;();</code></pre>



<p>We are using the RequestLocalizationOptions object to retrieve the complete list of supported cultures that we configured in the Startup.cs file at the beginning of this post. In order to bind the SelectListItem with the HTML select control, we are also creating a SelectListItem from the list of SupportedUICultures.</p>



<pre class="wp-block-code"><code>var cultureItems = LocOptions.Value.SupportedUICultures
        .Select(c =&gt; new SelectListItem { Value = c.Name, Text = c.DisplayName })
        .ToList();</code></pre>



<p>The asp-items property will be used to link the HTML select dropdown with the cultures in the form that will be added to the top navigation bar. To ensure that the current culture is pre-selected automatically on page refresh, the current culture name is also bound with the asp-for property. Additionally, I automated the submission of the form to the ChangeLanguage action method, which will perform all the magic for us, using the onchange event.</p>



<pre class="wp-block-code"><code>&lt;ul class="navbar-nav flex-grow-1"&gt;
    &lt;li class="nav-item"&gt;
        &lt;a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index"&gt;Home&lt;/a&gt;
    &lt;/li&gt;
 
    &lt;li class="nav-item"&gt;
        &lt;form asp-action="ChangeLanguage" asp-controller="Home" method="post"&gt;
 
            &lt;input type="hidden" id="returnUrl" name="returnUrl" value="@returnUrl" /&gt;
 
            &lt;select id="culture"
                name="culture"
                class="form-control"
                onchange="this.form.submit();"
                asp-items="cultureItems"
                asp-for="@requestCulture.RequestCulture.UICulture.Name"&gt;
            &lt;/select&gt;
 
        &lt;/form&gt;
    &lt;/li&gt;
&lt;/ul&gt;</code></pre>



<p>The primary function of the HomeController class&#8217;s ChangeLanguage action method is to create a cookie with the currently selected culture and add it to the HTTP response cookies collection. It takes the culture and returnUrl as parameters.</p>



<pre class="wp-block-code"><code>[HttpPost]
public IActionResult ChangeLanguage(string culture, string returnUrl)
{
    Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
            new CookieOptions
            {
                Expires = DateTimeOffset.UtcNow.AddDays(7)
            }
    );
 
    return LocalRedirect(returnUrl);
}</code></pre>



<p>You only need that one line of code to implement language switching. The page contents will be automatically translated to French when you launch the application and choose French from the dropdown.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" class="wp-image-3676" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/french-language-2.png" alt="" width="588" height="322" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/french-language-2.png 588w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/french-language-2-300x164.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/french-language-2-50x27.png 50w" sizes="(max-width: 588px) 100vw, 588px" /></figure></div>


<p>Now try to select the German language from the dropdown and the page contents will update accordingly.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="588" height="320" class="wp-image-3677" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/german-language.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/german-language.png 588w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/german-language-300x163.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/german-language-50x27.png 50w" sizes="(max-width: 588px) 100vw, 588px" /></figure></div>


<p>At this point, if you check the cookies in the browser developer tools, you will see that the culture is currently set to German.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="616" height="348" class="wp-image-3678" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/aspnetcore-culture.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/aspnetcore-culture.png 616w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/aspnetcore-culture-300x169.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/aspnetcore-culture-50x28.png 50w" sizes="(max-width: 616px) 100vw, 616px" /></figure></div>


<h2 class="wp-block-heading">Summary</h2>



<p>Many web developers find localization to be a frightening subject, but you will agree with me that ASP.NET Core has made localization incredibly easy to implement. The configuration of multiple languages, the creation of localized string resources, and the use of the default request culture providers were all covered in this post. Additionally, we have mastered the art of dynamic language switching. I sincerely hope this post was helpful to you. Please leave your feedback in the section below if you have any suggestions or comments. Don&#8217;t forget to spread the word about this tutorial to your friends and neighbors.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-build-multilingual-applications-in-asp-net-core/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ASP.NET Developer MUST Know These 4 Logging Techniques</title>
		<link>https://topreviewhostingasp.net/4-asp-net-core-logging-techniques/</link>
					<comments>https://topreviewhostingasp.net/4-asp-net-core-logging-techniques/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Thu, 13 Jul 2023 07:19:42 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net core basic logging]]></category>
		<category><![CDATA[asp net logging]]></category>
		<category><![CDATA[asp net tips]]></category>
		<category><![CDATA[asp net tutorial]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3624</guid>

					<description><![CDATA[Because logging in ASP.net core is so simple to use, it&#8217;s also simple to overlook key crucial diagnostics capabilities or to misuse these potent logging tools. I&#8217;ll walk you through the fundamentals of ASP.net core Structured Logging both with and without Serilog in this tutorial. You can easily understand the fundamental ideas with the help [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Because logging in ASP.net core is so simple to use, it&#8217;s also simple to overlook key crucial diagnostics capabilities or to misuse these potent logging tools. I&#8217;ll walk you through the fundamentals of ASP.net core Structured Logging both with and without Serilog in this tutorial. You can easily understand the fundamental ideas with the help of this guide. Let&#8217;s start by exploring these 4 Structured Logging Techniques in ASP.NET Core.</p>



<h2 class="wp-block-heading">ASP.NET Core Basic Logging</h2>



<p>As I mentioned before, the default logging framework that comes with Asp.net core is already set up when you start a web application builder. You don&#8217;t need to do anything because the default configuration adds console, debug, event source, and event log as described in the documentation.</p>



<h3 class="wp-block-heading">Using a logging provider (use case: Serilog)</h3>



<p>Let&#8217;s discuss about providers before getting into the meat of this piece. Since we&#8217;ll discuss both serilog and the standard ASP.net core logging system. Other logging providers that will improve your logging can be used with ASP.net core. You should make use of the robust features offered by these companies. We will utilize serilog as our supplier in this article.</p>



<h3 class="wp-block-heading">Adding Serilog to your project</h3>



<p>Serilog configuration is simple. Add the &#8220;Serilog.AspNetCore&#8221; nugget package to your project. Serilog must be configured after the nugget package has been included. Use this code fragment in your program.cs (Dotnet 6+) to add console logging, make serilog the default provider, and load configurations from our appsettings file.</p>



<pre class="wp-block-code"><code>Log.Logger = new LoggerConfiguration()
       .WriteTo.Console()
       .ReadFrom.Configuration(builder.Configuration)
       .CreateLogger();

builder.Host.UseSerilog();</code></pre>



<p>Following this, we can expand the appsettings.json file&#8217;s configuration choices. For instance, you could use the following to modify the log level in serilog:</p>



<pre class="wp-block-code"><code> 
   "Serilog": {
    "MinimumLevel": "Debug",
}</code></pre>



<p>You might use the following to limit this log level to a certain logging context or namespace. Keep in mind that this is highly configurable. I&#8217;ll include links to places where you may learn more about these settings options at the end of this article.</p>



<pre class="wp-block-code"><code>   "Serilog": {
    "MinimumLevel": {
      "Override": {
        "Default": "Debug",
        "Microsoft.AspNetCore": "Information"
      }
    }
}</code></pre>



<h3 class="wp-block-heading">1. To correctly delimit your logs, use scopes.</h3>



<p>A logging scope is defined. I&#8217;ll use Microsoft&#8217;s explanation. &#8220;A series of logical operations can be grouped into a scope. The same data can be attached to each log that is produced as part of a set using this grouping.</p>



<p>Here, we&#8217;ll add scopes that cover whole HTTP requests as well as a user-id or client-id scope, allowing us to identify which user or client of our API is executing which action at any given time. This eliminates the need to repeatedly type the user id or client id in each log for the appropriate logs and clearly delimits the logs, even in the inner level logs of the framework. It also results in cleaner code. Here&#8217;s how we go about it:</p>



<p><strong>NB</strong>: Scopes are called in using statements because some resources need to be freed once the scope is done.</p>



<ul><li>We must intercept http requests at the beginning and determine whether they are authentic. If so, we define the scope using the user&#8217;s ID or the API client&#8217;s ID. If not, the request flow is simply continued. We&#8217;ll need a middleware for this.</li></ul>



<pre class="wp-block-code"><code>public class CurrentCallerScopeLoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger&lt;CurrentCallerScopeLoggingMiddleware> _logger;

    public CurrentCallerScopeLoggingMiddleware(RequestDelegate next, 
        ILogger&lt;CurrentCallerScopeLoggingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (context.User.Identity is { IsAuthenticated: true })
        {
            //TODO: It might be a good idea to add both user id and client id at the same time.
            //If the caller is authenticated and he is a client like an API client this value will not be null.
            var clientId = context.User?.Claims?.FirstOrDefault(claim => claim.Type == "client_id")?.Value;

            if (context.User?.HasClaim(c => c.Type == ClaimTypes.NameIdentifier) ?? false)
            {
                var userId = context.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
                //Let the current user be taken as the request scope.
                using (_logger.BeginScope("User Id: {UserId}", userId))
                {
                    await _next(context);
                }
            }
            else if (!string.IsNullOrEmpty(clientId))
            {
                //Let the current user be taken as the request scope.
                using (_logger.BeginScope("Client Id: {ClientId}", clientId))
                {
                    await _next(context);
                }
            }
        }
        else
        {
            await _next(context);
        }
    }
}</code></pre>



<ul><li>Our middleware must be included to the project. Note that if it is introduced before the middleware for authentication, authentication will not take place until it is called. And that&#8217;s not what we want.</li></ul>



<pre class="wp-block-code"><code>        app.UseAuthentication();
        app.UseMiddleware&lt;CurrentCallerScopeLoggingMiddleware>();
        app.UseAuthorization();     </code></pre>



<p>Your logs will be properly defined after doing this, which will make diagnosis easier.</p>



<p>Here is a fantastic post I made about CQRS Command Validation with Mediatr in Asp.net Core in case you utilize CQRS. This post, in my opinion, will be very helpful for all developers, but especially for those that incorporate validation logic into their Command and Query business logic.</p>



<h3 class="wp-block-heading">2. Make use of structured logging features: Logging in JSON Format</h3>



<p>The second ASP.NET core structured logging mechanism is presented here. Let&#8217;s define structured logging first. This is the process of logging application events in a well-organized and consistent manner, facilitating reading, searching, and interpreting the logs. Compared to simply logging strings in an output, this is superior. In light of this, structuring our logs is the most effective technique to log effectively. What could be more ideal than JSON?</p>



<p><strong>Configuring JSON format for your logs in ASP.net core</strong></p>



<p>It is simple to configure the output format of your log entries with ASP.net core. You may accomplish this by using the &#8220;FormatterName&#8221; and &#8220;FormatterOptions&#8221; parameters found in the appsettings.json file. Here&#8217;s an illustration:</p>



<pre class="wp-block-code"><code>"Console": {
      "FormatterName": "json",
      "FormatterOptions": {
        "SingleLine": true,
        "IncludeScopes": true,
        "UseUtcTimestamp": true,
        "TimestampFormat": "HH:mm:ss",
        "JsonWriterOptions": {
          "Indented": true
        }
      }
    }</code></pre>



<p>In the aforementioned example, I define that each console log shall be indented, contain scopes, and be in json format. Your logs will then show up in the console with the json format when you provide this.</p>



<p><strong>Setting up Serilog&#8217;s JSON format for your logs</strong></p>



<p>Naturally, serilog enables you to give your logs a specified structure. We&#8217;ll create a json format for our console logs in our example. Keep in mind the code above that configures Serilog? Simply make a small modification to it:</p>



<p>.WriteTo.Console(formatter: new JsonFormatter())</p>



<p>The output template can then be modified to either log solely json logs or to include more information in the log output. Here&#8217;s how to add the JSON message to logs, followed by a newline and any potential exceptions:</p>



<pre class="wp-block-code"><code>   "Serilog": {
    "MinimumLevel": ...
    ...
    "WriteTo": &#91;
        {
          "Name": "Console",
          "Args": {
            "theme": ...,
            "outputTemplate": "{Message:lj}{NewLine}{Exception}"
          }
        }
    }</code></pre>



<h3 class="wp-block-heading">3. How to appropriately use logging parameters and destructure them</h3>



<p>It is crucial to pass parameters when logging, and doing so is extremely simple. The parameter name only has to be enclosed in curly brackets and added to the logging procedure. You don&#8217;t need to preface your strings with a &#8220;$&#8221; sign. The mechanism for logging already takes care of that. The code below, for instance, logs the user&#8217;s age.</p>



<pre class="wp-block-code"><code>        _logger.LogInformation("User's age: {UserAge}", user.Age);</code></pre>



<p>If structured logging with Json was enabled when this option was supplied, the output would be clearly documented, making it simple to query the logs using the user&#8217;s age parameter I passed. The possible output is shown in part below:</p>



<pre class="wp-block-code"><code>"MessageTemplate":"User's age: {UserAge}","Properties":{"UserAge":20,"S…</code></pre>



<p>What about logging while passing complicated objects as parameters? Since it only uses complicated objects&#8217; &#8220;ToString()&#8221; methods to convert them to strings, ASP.net core demonstrates its limitations in this situation. JSON objects won&#8217;t be present in your logs. Destructuring is the process of converting these parameters to json objects, which is supported by logging providers like Serilog.</p>



<p>Use &#8220;@&#8221; to destructure a complex parameter in serilog to json, and &#8220;$&#8221; to merely display the parameter&#8217;s type or signification. Here&#8217;s an illustration.</p>



<pre class="wp-block-code"><code>_logger.LogInformation("Silly info: {@Info}", new Info
{
    AccountId = 32,
    Description = "kfdoa"
});</code></pre>



<p>The aforementioned code will generate a log entry in json format with the Info parameter. When structured logging is turned on, it will appear as follows:</p>



<pre class="wp-block-code"><code>"MessageTemplate":"Silly info: {@Info}","Properties":{"Info":{"_typeTag":"Info","AccountId":32,"Description":"kfdoa","Id":0,"Label":".....</code></pre>



<p>Now, if I destroy using the $ sign, as displayed below:</p>



<pre class="wp-block-code"><code>_logger.LogInformation("Silly info: {$Info}", new Info
{
    AccountId = 32,
    Description = "kfdoa"
});</code></pre>



<p>I get the following output:</p>



<pre class="wp-block-code"><code>"MessageTemplate":"Silly info: {$Info}","Properties":{"Info":"DemoApp.Api.Info","SourceContext":"…</code></pre>



<p>With the help of this free, serilog-compatible open-source software, <a href="https://github.com/destructurama/" target="_blank" rel="noreferrer noopener">https://github.com/destructurama/</a>attributed, you can customize how your parameters are destructured completely. It enables you to cover confidential data with &#8220;***&#8221; in the event that it is a password, for example, or to hide sensitive data when destroying objects.</p>



<p>You can add custom configurations to your appsettings.json file to configure destructuring. This is an illustration of the configurations I included. I&#8217;ve included links at the conclusion of this article that you may use to learn more about this feature.</p>



<pre class="wp-block-code"><code>"Serilog": {
    "Using": ..,
    "MinimumLevel": ...
    "Enrich": ...,
    "WriteTo": ...,
    "Destructure": &#91;
      {
        "Name": "ToMaximumDepth",
        "Args": { "maximumDestructuringDepth": 4 }
      },
      {
        "Name": "ToMaximumStringLength",
        "Args": { "maximumStringLength": 100 }
      },
      {
        "Name": "ToMaximumCollectionCount",
        "Args": { "maximumCollectionCount": 10 }
      }
    ],
    "Properties": {
      "Application": "YouScribe.Affiliates.Api"
    }
  },</code></pre>



<h3 class="wp-block-heading">4. Don&#8217;t forget to choose the appropriate log level and select the logging category.</h3>



<p>The structured logging method in ASP.net core that is easiest to use is this one. You only need to inject an ILogger or ILoggerT> in your class, where &#8220;T&#8221; denotes the category of logs and class type. This is covered in the documents I cited before. Once T is defined, a string containing the name of the class it belongs to will appear in every report. Here&#8217;s an illustration:</p>



<pre class="wp-block-code"><code>public class DemoController : BaseController
{
    public DemoController(IMediator mediator, ILogger&lt;DemoController> logger)
    {
    }
}</code></pre>



<p> For example, if I log the following:</p>



<pre class="wp-block-code"><code>_logger.LogInformation("Silly info logged");</code></pre>



<p>The output will contain the category and will be:</p>



<pre class="wp-block-code"><code>MyApi.DemoController: Information: Silly info logged</code></pre>



<p>This is quite beneficial while conducting diagnostics. When an error happens, you want to know where your logs are coming from.</p>



<p>It is simple to specify the log level. The documentation does an excellent job of outlining how to do that here (<a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-7.0#configure-logging" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-7.0#configure-logging</a>). However, what log level should you pick? The various log levels and their definitions are listed below.</p>



<ul><li><strong>Trace:</strong> The smallest log level, used to record the most information possible. It is jam-packed with knowledge about how the system works. Write logs at this level if you wish to include a lot of specific details about how your product works internally. Additionally, due to the excessive amount of information it contains, this log level in the configurations should NEVER be activated by default in production. When attempting to resolve intricate problems that have arisen in your software, you should turn it on.</li><li><strong>Debug</strong>: The following level is the bottommost one. It is used to log debug information and also contains a lot of information, as the name suggests. This ought to only be used in test settings. To determine when something went wrong, you might activate it during manufacturing, but be sure to rewind to a higher level.</li><li><strong>Information</strong>: This is used to transmit data about how the software is utilized.</li><li><strong>Warning</strong>: This is utilized when your software exhibits unexpected behavior but not in a way that your system will fail. For instance, when the user&#8217;s search results are not returned.</li><li><strong>Error</strong>: When a system failure occurs, use this log level. failures that are unique to a particular user or usage circumstance. These errors shouldn&#8217;t prevent your machine from functioning properly.</li><li><strong>Critical</strong>: Use this log level if a system malfunctions. errors that are specific to a given user or usage situation. Your machine shouldn&#8217;t be rendered incapable of performing as intended by these faults.</li></ul>



<h2 class="wp-block-heading">Conclusion</h2>



<p>What do you think of these 4 ASP.NET Core structured logging techniques? These are, in my opinion, the key ideas you need to understand before adding logging functionality to your ASP.NET Core application. With these, you can log expertly and cut down on your time spent on troubleshooting and diagnostics. I hope this is useful to you as you pursue software development.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/4-asp-net-core-logging-techniques/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Add HTTP Methods to ASP.NET Core</title>
		<link>https://topreviewhostingasp.net/how-to-add-http-methods-to-asp-net-core/</link>
					<comments>https://topreviewhostingasp.net/how-to-add-http-methods-to-asp-net-core/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Mon, 10 Jul 2023 04:42:21 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net core http method]]></category>
		<category><![CDATA[asp net tips]]></category>
		<category><![CDATA[asp net tutorial]]></category>
		<category><![CDATA[http method]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3620</guid>

					<description><![CDATA[The HTTP standard is a dynamic document that is regularly reviewed and updated. The specification may be &#8220;done&#8221; to some developers&#8217; eyes, but there are a ton of new and intriguing HTTP methods that are about to be proposed. The QUERY method, which has semantics identical to a GET method call but allows users to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>The HTTP standard is a dynamic document that is regularly reviewed and updated. The specification may be &#8220;done&#8221; to some developers&#8217; eyes, but there are a ton of new and intriguing HTTP methods that are about to be proposed. The QUERY method, which has semantics identical to a GET method call but allows users to submit a request body, is one such HTTP method. As you might guess, this opens up a world of possibilities for searches that are more complicated than what would be possible with a standard query string.</p>
<p>In this article, we&#8217;ll go through how to enable ASP.NET Core to support experimental HTTP methods. We&#8217;ll also go through some reasons why you might not want to. Let&#8217;s get going.</p>
<h2>The HTTP Query Method: What is it?</h2>
<p>We should discuss HTTP Query and why others would want to utilize it in their API implementations before moving on to the C# implementation.</p>
<p>Queries are often delivered via the GET or POST method when developers create HTTP APIs. The URL path and the query parameters are included in GET requests. While complicated queries can be transmitted using the GET method, this approach is constrained by the HTTP standard. A URL may only contain a certain amount of data, and items in the query string must be URL encoded. The POST method, which permits more complicated query syntax in the request body, is frequently used by developers when they approach the boundaries of utilizing the GET method. Nevertheless, utilizing POST has disadvantages as well because these calls do not adhere to the same caching restrictions as GET requests and as a result, place greater strain on the host server.</p>
<p>With regard to caching and idempotency semantics, the QUERY method combines the advantages of the GET method with the flexibility for developers to publish a body akin to a publish request. Developers may now send any message to the server, even those using sophisticated query languages like GraphQL, SQL, LINQ, and others, thanks to the inclusion of the body.</p>
<h2>A New HTTP Method Should Be Added To Simple API Endpoints</h2>
<p>Fortunately, HTTP method detection in ASP.NET Core may be customized. As a result, you don&#8217;t need a lot of plumbing code to add any HTTP method. Let&#8217;s start by giving a Minimal API endpoint the QUERY function.</p>
<p>You may utilize the <code>MapMethods</code> method on <code>IEndpointConventionBuilder</code> when working with Minimal APIs. Any string value that ASP.NET Core could perceive as an HTTP method can be sent into the method. You may also create a <code>MapQuery</code> extension method to match the existing methods of <code>MapGet</code>, <code>MapPost</code>, etc. for user convenience.</p>
<pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">HttpQueryExtensions</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">static</span> <span class="n">IEndpointConventionBuilder</span> <span class="nf">MapQuery</span><span class="p">(</span>
        <span class="k">this</span> <span class="n">IEndpointRouteBuilder</span> <span class="n">endpoints</span><span class="p">,</span>
        <span class="kt">string</span> <span class="n">pattern</span><span class="p">,</span>
        <span class="n">Func</span><span class="p">&lt;</span><span class="n">Query</span><span class="p">,</span> <span class="n">IResult</span><span class="p">&gt;</span> <span class="n">requestDelegate</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">endpoints</span><span class="p">.</span><span class="nf">MapMethods</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="s">"QUERY"</span> <span class="p">},</span> <span class="n">requestDelegate</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">static</span> <span class="n">IEndpointConventionBuilder</span> <span class="nf">MapQuery</span><span class="p">(</span>
        <span class="k">this</span> <span class="n">IEndpointRouteBuilder</span> <span class="n">endpoints</span><span class="p">,</span>
        <span class="kt">string</span> <span class="n">pattern</span><span class="p">,</span>
        <span class="n">RequestDelegate</span> <span class="n">requestDelegate</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">endpoints</span><span class="p">.</span><span class="nf">MapMethods</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="s">"QUERY"</span> <span class="p">},</span> <span class="n">requestDelegate</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
<p>A <code>&lt;FuncQuery,IResult&gt;</code> is present in our extension function, as you would have seen. The purpose of the <code>Query</code> type is to model-bind our request&#8217;s body to a string. Examining this class, you may choose to implement the reading of the body in any manner you choose, perhaps including serializing it into a strongly-typed entity. However, doing so is absolutely optional.</p>
<pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Query</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">string</span><span class="p">?</span> <span class="n">Text</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="k">static</span> <span class="k">async</span> <span class="n">ValueTask</span><span class="p">&lt;</span><span class="n">Query</span><span class="p">&gt;</span> <span class="nf">BindAsync</span><span class="p">(</span>
        <span class="n">HttpContext</span> <span class="n">context</span><span class="p">,</span>
        <span class="n">ParameterInfo</span> <span class="n">parameter</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="kt">string</span><span class="p">?</span> <span class="n">text</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
        <span class="kt">var</span> <span class="n">request</span> <span class="p">=</span> <span class="n">context</span><span class="p">.</span><span class="n">Request</span><span class="p">;</span>

        <span class="k">if</span> <span class="p">(!</span><span class="n">request</span><span class="p">.</span><span class="n">Body</span><span class="p">.</span><span class="n">CanSeek</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="c1">// We only do this if the stream isn't *already* seekable,</span>
            <span class="c1">// as EnableBuffering will create a new stream instance</span>
            <span class="c1">// each time it's called</span>
            <span class="n">request</span><span class="p">.</span><span class="nf">EnableBuffering</span><span class="p">();</span>
        <span class="p">}</span>

        <span class="k">if</span> <span class="p">(</span><span class="n">request</span><span class="p">.</span><span class="n">Body</span><span class="p">.</span><span class="n">CanRead</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">request</span><span class="p">.</span><span class="n">Body</span><span class="p">.</span><span class="n">Position</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
            <span class="kt">var</span> <span class="n">reader</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">StreamReader</span><span class="p">(</span><span class="n">request</span><span class="p">.</span><span class="n">Body</span><span class="p">,</span> <span class="n">Encoding</span><span class="p">.</span><span class="n">UTF8</span><span class="p">);</span>
            <span class="n">text</span> <span class="p">=</span> <span class="k">await</span> <span class="n">reader</span><span class="p">.</span><span class="nf">ReadToEndAsync</span><span class="p">().</span><span class="nf">ConfigureAwait</span><span class="p">(</span><span class="k">false</span><span class="p">);</span>
            <span class="n">request</span><span class="p">.</span><span class="n">Body</span><span class="p">.</span><span class="n">Position</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="k">new</span> <span class="n">Query</span> <span class="p">{</span> <span class="n">Text</span> <span class="p">=</span> <span class="n">text</span> <span class="p">};</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">static</span> <span class="k">implicit</span> <span class="k">operator</span> <span class="kt">string</span><span class="p">(</span><span class="n">Query</span> <span class="n">query</span><span class="p">)</span> <span class="c1">// implicit digit to byte conversion operator</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">query</span><span class="p">.</span><span class="n">Text</span> <span class="p">??</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span> <span class="c1">// implicit conversion</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
<p>Let&#8217;s finally put our objective into practice. I&#8217;ll turn the request&#8217;s body into a LINQ expression in this illustration. This shouldn&#8217;t be done in production since an expression is C# code and might create security flaws. This sample is being used as a demo.</p>
<pre class="highlight"><code><span class="n">app</span><span class="p">.</span><span class="nf">MapQuery</span><span class="p">(</span><span class="s">"/people"</span><span class="p">,</span> <span class="n">query</span> <span class="p">=&gt;</span>
<span class="p">{</span>
    <span class="k">try</span>
    <span class="p">{</span>
        <span class="c1">// database</span>
        <span class="kt">var</span> <span class="n">people</span> <span class="p">=</span> <span class="n">Enumerable</span><span class="p">.</span><span class="nf">Range</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="m">100</span><span class="p">)</span>
            <span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">i</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="n">Person</span> <span class="p">{</span> <span class="n">Index</span> <span class="p">=</span> <span class="n">i</span><span class="p">,</span> <span class="n">Name</span> <span class="p">=</span> <span class="s">$"Minion #</span><span class="p">{</span><span class="n">i</span><span class="p">}</span><span class="s">"</span> <span class="p">});</span>

        <span class="c1">// let's use the Query</span>
        <span class="kt">var</span> <span class="n">parameter</span> <span class="p">=</span> <span class="n">Expression</span><span class="p">.</span><span class="nf">Parameter</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">Person</span><span class="p">&gt;),</span> <span class="k">nameof</span><span class="p">(</span><span class="n">people</span><span class="p">));</span>
        <span class="kt">var</span> <span class="n">expression</span> <span class="p">=</span> <span class="n">DynamicExpressionParser</span><span class="p">.</span><span class="nf">ParseLambda</span><span class="p">(</span><span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="n">parameter</span> <span class="p">},</span> <span class="k">null</span><span class="p">,</span> <span class="n">query</span><span class="p">.</span><span class="n">Text</span><span class="p">);</span>
        <span class="kt">var</span> <span class="n">compiled</span> <span class="p">=</span> <span class="n">expression</span><span class="p">.</span><span class="nf">Compile</span><span class="p">();</span>

        <span class="c1">// execute query</span>
        <span class="kt">var</span> <span class="n">result</span> <span class="p">=</span> <span class="n">compiled</span><span class="p">.</span><span class="nf">DynamicInvoke</span><span class="p">(</span><span class="n">people</span><span class="p">);</span>

        <span class="k">return</span> <span class="n">Results</span><span class="p">.</span><span class="nf">Ok</span><span class="p">(</span><span class="k">new</span>
        <span class="p">{</span>
            <span class="n">query</span><span class="p">,</span>
            <span class="n">source</span> <span class="p">=</span> <span class="s">"endpoint"</span><span class="p">,</span>
            <span class="n">results</span> <span class="p">=</span> <span class="n">result</span>
        <span class="p">});</span>
    <span class="p">}</span>
    <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">Results</span><span class="p">.</span><span class="nf">BadRequest</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">})</span>
<span class="p">.</span><span class="nf">WithName</span><span class="p">(</span><span class="s">"endpoint"</span><span class="p">);</span></code></pre>
<p>Later on, we&#8217;ll call this endpoint, but for now, let&#8217;s also give ASP.NET Core MVC QUERY support.</p>
<h2>Enhance ASP.NET Core MVC With A New HTTP Method</h2>
<p>It is considerably simpler to integrate experimental HTTP methods into ASP.NET Core MVC. Only a class inherited from <code>HttpMethodAttribute</code> must be implemented.</p>
<pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">HttpQueryAttribute</span> <span class="p">:</span> <span class="n">HttpMethodAttribute</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="k">static</span> <span class="k">readonly</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">SupportedMethods</span> <span class="p">=</span> <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="s">"QUERY"</span> <span class="p">};</span>

    <span class="c1">/// &lt;summary&gt;</span>
    <span class="c1">/// Creates a new &lt;see cref="Microsoft.AspNetCore.Mvc.HttpGetAttribute"/&gt;.</span>
    <span class="c1">/// &lt;/summary&gt;</span>
    <span class="k">public</span> <span class="nf">HttpQueryAttribute</span><span class="p">()</span>
        <span class="p">:</span> <span class="k">base</span><span class="p">(</span><span class="n">SupportedMethods</span><span class="p">)</span>
    <span class="p">{</span>
    <span class="p">}</span>

    <span class="c1">/// &lt;summary&gt;</span>
    <span class="c1">/// Creates a new &lt;see cref="Microsoft.AspNetCore.Mvc.HttpGetAttribute"/&gt; with the given route template.</span>
    <span class="c1">/// &lt;/summary&gt;</span>
    <span class="c1">/// &lt;param name="template"&gt;The route template. May not be null.&lt;/param&gt;</span>
    <span class="k">public</span> <span class="nf">HttpQueryAttribute</span><span class="p">([</span><span class="nf">StringSyntax</span><span class="p">(</span><span class="s">"Route"</span><span class="p">)]</span> <span class="kt">string</span> <span class="n">template</span><span class="p">)</span>
        <span class="p">:</span> <span class="k">base</span><span class="p">(</span><span class="n">SupportedMethods</span><span class="p">,</span> <span class="n">template</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">template</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentNullException</span><span class="p">(</span><span class="k">nameof</span><span class="p">(</span><span class="n">template</span><span class="p">));</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
<p>Once it has been implemented, all that is left to do is add the new attribute to your ASP.NET Core MVC method. Let&#8217;s have a look at an action that can now process QUERY queries as the final implementation.</p>
<pre class="highlight"><code><span class="p">[</span><span class="nf">Route</span><span class="p">(</span><span class="s">"api/people"</span><span class="p">)]</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">PeopleController</span> <span class="p">:</span> <span class="n">Controller</span>
<span class="p">{</span>
    <span class="p">[</span><span class="n">HttpQuery</span><span class="p">,</span> <span class="nf">Route</span><span class="p">(</span><span class="s">""</span><span class="p">,</span> <span class="n">Name</span> <span class="p">=</span> <span class="s">"controller"</span><span class="p">)]</span>
    <span class="k">public</span> <span class="k">async</span> <span class="n">Task</span><span class="p">&lt;</span><span class="n">IActionResult</span><span class="p">&gt;</span> <span class="nf">Index</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">try</span>
        <span class="p">{</span>
            <span class="kt">var</span> <span class="n">body</span> <span class="p">=</span> <span class="k">await</span> <span class="k">new</span> <span class="nf">StreamReader</span><span class="p">(</span><span class="n">Request</span><span class="p">.</span><span class="n">Body</span><span class="p">).</span><span class="nf">ReadToEndAsync</span><span class="p">();</span>
            <span class="kt">var</span> <span class="n">query</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Query</span> <span class="p">{</span> <span class="n">Text</span> <span class="p">=</span> <span class="n">body</span> <span class="p">};</span>

            <span class="c1">// database</span>
            <span class="kt">var</span> <span class="n">people</span> <span class="p">=</span> <span class="n">Enumerable</span><span class="p">.</span><span class="nf">Range</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="m">100</span><span class="p">)</span>
                <span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">i</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="n">Person</span> <span class="p">{</span> <span class="n">Index</span> <span class="p">=</span> <span class="n">i</span><span class="p">,</span> <span class="n">Name</span> <span class="p">=</span> <span class="s">$"Minion #</span><span class="p">{</span><span class="n">i</span><span class="p">}</span><span class="s">"</span> <span class="p">});</span>

            <span class="c1">// let's use the Query</span>
            <span class="kt">var</span> <span class="n">parameter</span> <span class="p">=</span> <span class="n">Expression</span><span class="p">.</span><span class="nf">Parameter</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">Person</span><span class="p">&gt;),</span> <span class="k">nameof</span><span class="p">(</span><span class="n">people</span><span class="p">));</span>
            <span class="kt">var</span> <span class="n">expression</span> <span class="p">=</span> <span class="n">DynamicExpressionParser</span><span class="p">.</span><span class="nf">ParseLambda</span><span class="p">(</span><span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="n">parameter</span> <span class="p">},</span> <span class="k">null</span><span class="p">,</span> <span class="n">query</span><span class="p">.</span><span class="n">Text</span><span class="p">);</span>
            <span class="kt">var</span> <span class="n">compiled</span> <span class="p">=</span> <span class="n">expression</span><span class="p">.</span><span class="nf">Compile</span><span class="p">();</span>

            <span class="c1">// execute query</span>
            <span class="kt">var</span> <span class="n">result</span> <span class="p">=</span> <span class="n">compiled</span><span class="p">.</span><span class="nf">DynamicInvoke</span><span class="p">(</span><span class="n">people</span><span class="p">);</span>

            <span class="k">return</span> <span class="nf">Ok</span><span class="p">(</span><span class="k">new</span>
            <span class="p">{</span>
                <span class="n">query</span><span class="p">,</span>
                <span class="n">source</span> <span class="p">=</span> <span class="s">"controller"</span><span class="p">,</span>
                <span class="n">results</span> <span class="p">=</span> <span class="n">result</span>
            <span class="p">});</span>
        <span class="p">}</span>
        <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">return</span> <span class="nf">BadRequest</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
<p>Because ASP.NET Core MVC&#8217;s model binding can be too complex in this instance, I&#8217;ve avoided using it. Please be considerate and email me a link to your implementation if you decide to try to build it yourself. Before fully implementing the QUERY method, you might wish to take into account your query approach.</p>
<p>Great! Now that a Query call from a client can be responded to, we have a Minimal API endpoint and an ASP.NET Core MVC action. Let&#8217;s look at the call method for these endpoints.</p>
<h2>Calling our QUERY Endpoints and Actions</h2>
<p>The following is the first restriction you&#8217;ll probably encounter while using experimental HTTP methods: The majority of the tooling you use is unaware of the method&#8217;s existence. Unfortunately, you can&#8217;t use tools like Postman, Swagger, and similar tools because of the experimental nature. Your ally is the code. Fortunately, using the <code>HttpClient</code> class to call the APIs is rather simple.</p>
<p>Despite the fact that the request might be made by any C# code housed in any code base, I&#8217;ll utilize another GET endpoint to access our Query API.</p>
<pre class="highlight"><code><span class="n">app</span><span class="p">.</span><span class="nf">MapGet</span><span class="p">(</span><span class="s">"/"</span><span class="p">,</span> <span class="k">async</span> <span class="p">(</span><span class="n">HttpContext</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">LinkGenerator</span> <span class="n">generator</span><span class="p">,</span> <span class="kt">string</span><span class="p">?</span> <span class="n">q</span><span class="p">,</span> <span class="kt">string</span><span class="p">?</span> <span class="n">e</span><span class="p">)</span> <span class="p">=&gt;</span>
<span class="p">{</span>
    <span class="kt">var</span> <span class="n">client</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">HttpClient</span><span class="p">();</span>
    <span class="kt">var</span> <span class="n">endpoint</span> <span class="p">=</span> <span class="n">e</span> <span class="k">switch</span> <span class="p">{</span>
        <span class="s">"endpoint"</span> <span class="p">=&gt;</span> <span class="s">"endpoint"</span><span class="p">,</span>
        <span class="s">"controller"</span> <span class="p">=&gt;</span> <span class="s">"controller"</span><span class="p">,</span>
        <span class="n">_</span> <span class="p">=&gt;</span> <span class="s">"endpoint"</span>
    <span class="p">};</span>

    <span class="kt">var</span> <span class="n">request</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">HttpRequestMessage</span><span class="p">(</span>
        <span class="k">new</span> <span class="nf">HttpMethod</span><span class="p">(</span><span class="s">"QUERY"</span><span class="p">),</span>
        <span class="n">generator</span><span class="p">.</span><span class="nf">GetUriByName</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">endpoint</span><span class="p">)</span>
    <span class="p">);</span>

    <span class="c1">//language=C#</span>
    <span class="n">q</span> <span class="p">??=</span> <span class="s">"people.OrderByDescending(p =&gt; p.Index).Take(10)"</span><span class="p">;</span>

    <span class="n">request</span><span class="p">.</span><span class="n">Content</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">StringContent</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">Encoding</span><span class="p">.</span><span class="n">UTF8</span><span class="p">,</span> <span class="s">"text/plain"</span><span class="p">);</span>

    <span class="kt">var</span> <span class="n">response</span> <span class="p">=</span> <span class="n">client</span><span class="p">.</span><span class="nf">Send</span><span class="p">(</span><span class="n">request</span><span class="p">);</span>
    <span class="kt">var</span> <span class="n">result</span> <span class="p">=</span> <span class="k">await</span> <span class="n">response</span><span class="p">.</span><span class="n">Content</span><span class="p">.</span><span class="nf">ReadAsStringAsync</span><span class="p">();</span>

    <span class="k">return</span> <span class="n">Results</span><span class="p">.</span><span class="nf">Content</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="s">"application/json"</span><span class="p">);</span>
<span class="p">});</span></code></pre>
<p>The use of the <code>HttpMethod</code> class is the main lesson to be learned from the code above. Any string value can be entered, and in our case, we want to set the method to QUERY. Additionally, a LINQ expression will be sent to filter our dataset. The remaining code is normal for a <code>HttpClient</code> application.</p>
<p>When our GET endpoint is called, our Query endpoints are also called, and our results are then obtained.</p>
<h2>Effects of Experimentation</h2>
<p>While considering and trying out experimental HTTP methods in your APIs can be interesting, you should first weigh the downsides.</p>
<ol>
<li>Because it&#8217;s experimental, the specification could change after you put it into practice.</li>
<li>You&#8217;ll probably have to code all interactions because your preferred tools won&#8217;t likely support your experimental techniques.</li>
<li>Typical ASP.NET Core libraries won&#8217;t function as intended. For instance, Swashbuckle (The OpenAPI library) will not materialize your endpoint schema in ASP.NET Core.</li>
<li>I am unaware of any infrastructure-related advantages of caching, load balancers, etc. Even worse, you could cause problems with your infrastructure.</li>
</ol>
<h2>Conclusion</h2>
<p>As long as you know what to implement, ASP.NET Core allows you to add any method. This was an enjoyable experiment that, if nothing else, clarified certain endpoint resolution methods.</p>
<p>Thank you for reading. Happy coding!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-add-http-methods-to-asp-net-core/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Fix No &#8216;Access-Control-Allow-Origin&#8217; .NET API CORS</title>
		<link>https://topreviewhostingasp.net/how-to-fix-no-access-control-allow-origin-net-api-cors/</link>
					<comments>https://topreviewhostingasp.net/how-to-fix-no-access-control-allow-origin-net-api-cors/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Wed, 14 Jun 2023 08:15:55 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net]]></category>
		<category><![CDATA[asp net tips]]></category>
		<category><![CDATA[asp net tutorial]]></category>
		<category><![CDATA[how to fix No 'Access-Control-Allow-Origin' header]]></category>
		<category><![CDATA[No 'Access-Control-Allow-Origin' header]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3571</guid>

					<description><![CDATA[In this article, I will discuss about the error message that you might found when calling a CORS protected .NET Core Api. The following is the full error message: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>In this article, I will discuss about the error message that you might found when calling a CORS protected .NET Core Api. The following is the full error message:</p>
<pre class="lang:default decode:true">Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header
is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. 
The response had HTTP status code 405.</pre>
<h2>How to Fix Error No &#8216;Access-Control-Allow-Origin&#8217;</h2>
<h3>1. Allow Method &#8220;Options&#8221;</h3>
<p>A preflight request is one that the browser sends to see if the CORS settings have been correctly implemented.</p>
<p>Therefore, if your endpoint supports POST, PUT, or DELETE operations and the browser sends a &#8220;application/json&#8221; request, the browser sends two requests: the &#8220;OPTIONS&#8221; request first, then a POST, PUT, or DELETE request.</p>
<p>You must therefore enable OPTIONS: in your application&#8217;s CORS settings.</p>
<pre class="lang:default decode:true ">app.UseCors(builder =&gt;
{
  builder
     .WithOrigins("http://localhost:4200", "https://localhost:4200")
     .SetIsOriginAllowedToAllowWildcardSubdomains()
     .AllowAnyHeader()
     .AllowCredentials()
     .WithMethods("GET", "PUT", "POST", "DELETE", "OPTIONS")
     .SetPreflightMaxAge(TimeSpan.FromSeconds(3600));
}
);</pre>
<h3>2. Cors is Defined Twice in Your Code</h3>
<p>Check that you have defined CORS twice.</p>
<p>First add CORS to the <strong>WebApplicationBuilder </strong>Services:</p>
<pre class="lang:default decode:true ">var builder = WebApplication.CreateBuilder();
...
...
builder.Services.AddCors();</pre>
<p>Then when defining the app:</p>
<div>
<pre class="lang:default decode:true ">var app = builder.Build();
app.UseCors(builder =&gt;
      {
        builder
              .WithOrigins("http://localhost:4200", "https://localhost:4200")
              .SetIsOriginAllowedToAllowWildcardSubdomains()
              .AllowAnyHeader()
              .AllowCredentials()
              .WithMethods("GET", "PUT", "POST", "DELETE", "OPTIONS")
              .SetPreflightMaxAge(TimeSpan.FromSeconds(3600));
 
      }
);</pre>
<h3>3. Check the Sequence of Calls</h3>
<p>You must define CORS before you map controllers, define routes etc.</p>
</div>
<div>
<pre class="lang:default decode:true ">var app = builder.Build();
 
// The first thing in the chain of calls is to define the CORS
app.UseCors(builder =&gt;
      {
        builder
              .WithOrigins("http://localhost:4200", "https://localhost:4200")
              .SetIsOriginAllowedToAllowWildcardSubdomains()
              .AllowAnyHeader()
              .AllowCredentials()
              .WithMethods("GET", "PUT", "POST", "DELETE", "OPTIONS")
              .SetPreflightMaxAge(TimeSpan.FromSeconds(3600));
 
      }
);
 
...
...
 
// After that, I can do mapping, routing, redirection etc...
app.MapControllers();
app.UseRouting();
app.UseHttpsRedirection();
 
if (app.Environment.IsProduction())
{
  app.UseTokenAuthentication();
}
 
app.Run();</pre>
<h3>4. Your Load Balancer Must Allow &#8220;Options&#8221; as well</h3>
<p>In front of your API, do you have a load balancer? Verify that OPTIONS methods are also supported by the load balancer.</p>
<p>Hopefully, tips above help you to fix above error. Happy Coding!</p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-fix-no-access-control-allow-origin-net-api-cors/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Stay Safe with Secure User Authentication</title>
		<link>https://topreviewhostingasp.net/stay-safe-with-secure-user-authentication/</link>
					<comments>https://topreviewhostingasp.net/stay-safe-with-secure-user-authentication/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 18 Apr 2023 09:20:25 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net tips]]></category>
		<category><![CDATA[asp net tutorial]]></category>
		<category><![CDATA[guide to secure website]]></category>
		<category><![CDATA[password policy]]></category>
		<category><![CDATA[secure asp net application]]></category>
		<category><![CDATA[secure user authentication]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3515</guid>

					<description><![CDATA[APIs are crucial for the development of contemporary software because they enable seamless data exchange and communication between various systems. Authentication and authorization are just two of the many aspects that must be carefully taken into account when developing an API that is secure and dependable. The distinction between authentication and authorization in API design [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>APIs are crucial for the development of contemporary software because they enable seamless data exchange and communication between various systems. Authentication and authorization are just two of the many aspects that must be carefully taken into account when developing an API that is secure and dependable.</p>



<p>The distinction between authentication and authorization in API design will be discussed in this post, along with some best practices for implementing secure user authentication.</p>



<h2 class="wp-block-heading">Authentication vs Authorization</h2>



<p>Verifying a user&#8217;s or system&#8217;s identity through <a href="https://topreviewhostingasp.net/how-to-implement-windows-authentication-in-asp-net-mvc/" target="_blank" rel="noreferrer noopener">authentication</a> usually entails asking for credentials like a username and password. The initial line of defense against unauthorized access to an API is authentication.</p>



<p>On the other hand, authorization is the process of deciding what operations a user or system is permitted to carry out within an API. Authorization is based on the user&#8217;s identity as determined by authentication and the permissions linked to that identity.</p>



<h2 class="wp-block-heading">A Guide to Secure User Authentication</h2>



<h3 class="wp-block-heading">Use Strong Password Policies</h3>



<p>Make it necessary for users to create secure passwords that mix upper- and lowercase letters, numbers, and special characters. Enforce password expiration rules as well to guarantee that passwords are changed frequently.</p>



<p>Consider factors like password complexity, expiration, and history when implementing strong password policies in your API. When using.NET or another well-known programming language, the following best practices should be kept in mind when implementing strong password policies:</p>



<ol>
<li><strong>Password complexity</strong>: Demand that users create secure, challenging passwords. This can be done by mandating that passwords have a minimum of 8 characters and be composed of a combination of capital and lowercase letters, numbers, and special characters. You can use.NET libraries like PasswordValidator to enforce these policies.</li>
<li><strong>Password Expiration</strong>: Demand that users change their passwords frequently, preferably every 90 days. Setting password expiration policies in your API will help you accomplish this. To set password expiration policies, you can use libraries like Identity Framework from the.NET Framework.</li>
<li><strong>Password History</strong>: By keeping track of users&#8217; previous passwords, you can stop them from using the same password repeatedly. Use.NET libraries like PasswordHistory to enforce password history policies.</li>
<li><strong>Account Lockout</strong>: By putting account lockout policies in place, you can stop brute-force attacks on user accounts. To implement account lockout policies, you can use.NET libraries like LockoutPolicy.</li>
</ol>



<p>Here is some sample.NET Core code that shows how to use the PasswordValidator library to enforce password complexity policies:</p>



<pre class="wp-block-code"><code>services.Configure&lt;IdentityOptions&gt;(options =&gt;
{
    // Password settings
    options.Password.RequiredLength = 8;
    options.Password.RequireLowercase = true;
    options.Password.RequireUppercase = true;
    options.Password.RequireDigit = true;
    options.Password.RequireNonAlphanumeric = true;

    // Lockout settings
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
    options.Lockout.MaxFailedAccessAttempts = 5;

    // User settings
    options.User.RequireUniqueEmail = true;
});</code></pre>



<ol>
<li><strong>Password Settings</strong>: You can define password guidelines for users using these options. As an illustration, we stipulate that passwords must contain a combination of lowercase and uppercase letters, numbers, and special characters, and that they must be at least 8 characters long.</li>
<li><strong>Lockout Options</strong>: Using these settings, you can set account lockout rules to guard against brute-force attacks on user accounts. In this example, we&#8217;re limiting the number of failed login attempts to 5, and setting the lockout time to 15 minutes.</li>
<li><strong>User Settings</strong>: You can configure user-specific settings with these options, such as requiring distinctive email addresses. In this case, creating an account requires users to enter their individual email addresses.</li>
</ol>



<p>By setting these configurations in the <code class="er oi oj ok nz b">services.Configure&lt;IdentityOptions&gt;(options =&gt;</code> method call, you can ensure that your API has strong password policies, is protected against brute force attacks, and enforces unique email addresses for user accounts. These configurations are an important step in securing your API against unauthorized access and other security threats</p>
<p><img loading="lazy" decoding="async" class="aligncenter  wp-image-3519" src="https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-scaled.jpg" alt="" width="377" height="377" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-scaled.jpg 2560w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-300x300.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-1024x1024.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-150x150.jpg 150w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-768x768.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-1536x1536.jpg 1536w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-2048x2048.jpg 2048w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-50x50.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-70x70.jpg 70w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-127x127.jpg 127w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-476x476.jpg 476w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/17465926_2007.i039.019_cyber_security_spyware_data_protection_isometric_set-06-min-125x125.jpg 125w" sizes="(max-width: 377px) 100vw, 377px" /></p>



<h3 class="wp-block-heading">Implement Multi-Factor Authentication</h3>



<p>By requiring users to provide additional authentication factors, such as a code sent to their mobile device in addition to their password, multi-factor authentication (MFA) adds an extra layer of security.</p>



<p>Multi-factor authentication (MFA) implementation is a crucial step in protecting your API from unauthorized access. By requiring users to provide additional authentication factors in addition to their password, MFA adds an extra layer of security. We&#8217;ll go over some best practices in this section for integrating MFA into your API using.NET or any other well-liked programming language.</p>



<p>MFA options include hardware tokens, authenticator apps, and SMS codes, among others. Here are a few typical procedures for integrating MFA into your API:</p>



<ol>
<li><strong>Choose an MFA Approach</strong>: Pick an MFA approach that is suitable for your API and users. Although SMS codes are a popular MFA technique, hardware tokens and authenticator apps can offer more security.</li>
<li><strong>Integrate MFA with User Accounts</strong>: Integrate multi-factor authentication (MFA) with user accounts to make users submit additional authentication factors in addition to their passwords. Libraries like the.NET Identity Framework can be used for this.</li>
<li><strong>Store MFA Credentials Securely</strong>: In order to stop attackers from accessing user credentials even if they have access to the database, securely store MFA credentials using encryption and hashing methods.</li>
</ol>



<p>Here is some sample.NET Core code that illustrates how to use the Identity Framework to implement MFA:</p>



<pre class="wp-block-code"><code>services.AddIdentity&lt;ApplicationUser, IdentityRole&gt;(options =&gt;
{
    // Configure MFA options
    options.SignIn.RequireConfirmedEmail = true;
    options.User.RequireUniqueEmail = true;
})
.AddDefaultTokenProviders()
.AddTokenProvider&lt;EmailTokenProvider&lt;ApplicationUser&gt;&gt;(TokenOptions.DefaultEmailProvider);

services.Configure&lt;DataProtectionTokenProviderOptions&gt;(options =&gt;
    options.TokenLifespan = TimeSpan.FromHours(3));

services.Configure&lt;EmailTokenProviderOptions&gt;(options =&gt;
    options.TokenLifespan = TimeSpan.FromDays(1));

services.AddScoped&lt;IUserClaimsPrincipalFactory&lt;ApplicationUser&gt;, AppClaimsPrincipalFactory&gt;();

services.AddScoped&lt;EmailTokenProvider&lt;ApplicationUser&gt;&gt;();</code></pre>



<p>In this code, we set up the Identity Framework so that verified email addresses are needed for MFA and separate email addresses are needed for user accounts. Additionally, we are setting the token lifespan and configuring token providers for email and data protection. We are also introducing a service that will produce email tokens for MFA.</p>



<p>To add an additional layer of security and guard against unauthorized access, you can quickly implement MFA in your API by following these best practices and utilizing the libraries and frameworks provided by your programming language.</p>



<h3 class="wp-block-heading">Use Secure Communication Protocols</h3>



<p>Use secure protocols like TLS 1.2 or higher and <a href="https://topreviewhostingasp.net/how-to-force-https-in-asp-net-core/" target="_blank" rel="noreferrer noopener">HTTPS</a> to encrypt all communications between the API and the client.</p>



<p>An important step in protecting your API from attackers who might try to intercept or tamper with data in transit is the use of secure communication protocols. All communications between the API and the client are encrypted and secure thanks to secure communication protocols like HTTPS. We&#8217;ll go over the best practices for integrating secure communication protocols into your <a href="https://topreviewhostingasp.net/how-to-build-crud-rest-apis-with-asp-net-core-3-1-and-entity-framework/" target="_blank" rel="noreferrer noopener">API using .NET</a> or any other well-liked programming language in this section.</p>



<p>The following are some typical procedures for integrating secure communication protocols in your API:</p>



<ol>
<li>Use <strong>HTTPS</strong>: Use HTTPS to encrypt all communications between the API and the client. This can be done by obtaining an SSL/TLS certificate and configuring your web server to use HTTPS. In .NET, you can use the <a href="https://topreviewhostingasp.net/how-to-force-https-in-asp-net-core/" target="_blank" rel="noreferrer noopener"><code>UseHttpsRedirection</code> method to enforce HTTPS</a>.</li>
<li><strong>Use Secure Protocols:</strong> Use secure protocols such as TLS 1.2 or higher. TLS (Transport Layer Security) is a protocol used to encrypt data in transit and protect against eavesdropping and tampering. In .NET, you can configure the TLS protocol using the <code>UseHttps</code> method.</li>
<li><strong>Use Strong Cipher Suites:</strong> Use strong cipher suites to encrypt communications between the API and the client. Cipher suites are combinations of cryptographic algorithms that are used to encrypt data in transit. In .NET, you can configure cipher suites using the <code>UseCipherSuites</code> method.</li>
</ol>
<p><img loading="lazy" decoding="async" class="aligncenter  wp-image-3520" src="https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min.jpg" alt="" width="456" height="456" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min.jpg 2000w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min-300x300.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min-1024x1024.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min-150x150.jpg 150w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min-768x768.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min-1536x1536.jpg 1536w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min-50x50.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min-70x70.jpg 70w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min-127x127.jpg 127w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min-476x476.jpg 476w, https://topreviewhostingasp.net/wp-content/uploads/2023/04/22896757_6670922-min-125x125.jpg 125w" sizes="(max-width: 456px) 100vw, 456px" /></p>



<p>The following.NET Core sample code illustrates how to implement secure communication protocols:</p>



<pre class="wp-block-code"><code>public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddHttpsRedirection(options =&gt;
    {
        options.HttpsPort = 443;
    });

    services.AddMvc();

    services.AddHttpsRedirection(options =&gt;
    {
        options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
        options.HttpsPort = 443;
    });

    services.Configure&lt;MvcOptions&gt;(options =&gt;
    {
        options.Filters.Add(new RequireHttpsAttribute());
    });
}</code></pre>



<p>In order to enforce secure communication protocols, we have added HTTPS redirection to this code. Additionally, we are including a filter that uses the <code>RequireHttpsAttribute()</code> method to require HTTPS in all requests.</p>



<p>You can quickly implement secure communication protocols in your API and guard against unauthorized access and data breaches by adhering to these best practices and utilizing libraries and frameworks provided by your programming language.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><a href="https://topreviewhostingasp.net/best-asp-net-hosting-ddos-protection/" target="_blank" rel="noreferrer noopener">Top 3 Best Secure ASP.NET Hosting</a></p>
</blockquote>



<h3 class="wp-block-heading">Implement Rate Limiting</h3>



<p>To stop automated attacks on the API, such as brute force attacks, use rate limiting.</p>



<p>In order to protect your API from attacks that could lead to server overload, denial of service, or other security problems, rate limiting must be put into place. By using rate limiting, you can restrict how many requests a user can make to your API in a given amount of time. The best practices for implementing rate limiting in your API using.NET or any other well-liked programming language are covered in this section.</p>



<p>Following are some typical procedures for implementing rate limiting in your API:</p>



<ol>
<li><strong>Set Up Your Rate Limiting Plan</strong>: Select a rate limiting technique that works for both your API and your users. Limits can be set based on IP addresses, user agents, or user accounts, among other common tactics.</li>
<li><strong>Apply Rate Limiting Middleware</strong>: Apply rate limiting middleware to make sure your rate limiting strategy is being followed. .NET libraries like AspNetCoreRateLimit can be used for this.</li>
<li><strong>Set Rate Limits</strong>: Using the middleware library you selected, set rate limits for your API. The AddRateLimit method in AspNetCoreRateLimit can be used to accomplish this.</li>
</ol>



<p>Here is some sample.NET Core code that shows how to use the AspNetCoreRateLimit middleware to implement rate limiting:</p>



<pre class="wp-block-code"><code>public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddMemoryCache();

    services.Configure&lt;IpRateLimitOptions&gt;(options =&gt;
    {
        options.GeneralRules = new List&lt;RateLimitRule&gt;
        {
            new RateLimitRule
            {
                Endpoint = "*",
                Limit = 100,
                Period = "1m"
            }
        };
    });

    services.AddSingleton&lt;IRateLimitConfiguration, MemoryCacheRateLimitConfiguration&gt;();

    services.AddHttpContextAccessor();
    services.AddMvc();
}</code></pre>



<p>The IpRateLimitOptions class, which enables us to set restrictions based on IP addresses, is being used in this code to configure rate limits. Additionally, we&#8217;re imposing a cap of 100 requests per minute across all endpoints. In order to handle rate limiting, we are also adding the <code>MemoryCacheRateLimitConfiguration service</code>.</p>



<p>You can easily implement rate limiting in your API and safeguard against unauthorized access and server overload by adhering to these best practices and utilizing the libraries and frameworks provided by your programming language.</p>



<h3 class="wp-block-heading">Keep Password Securely</h3>



<p>The first step in protecting your API from unauthorized access and data breaches is to store passwords securely. To stop attackers from accessing user passwords even if they gain access to the database, passwords should never be stored in plain text and should always be hashed and salted. In this section, we&#8217;ll go over the best practices for using.NET or any other well-liked programming language to store passwords safely in your API.</p>



<p>Here are some typical procedures for safely storing passwords in your API:</p>



<ol>
<li><strong>Use a Secure Password Hashing Algorithm</strong>: To hash user passwords, use a secure password hashing algorithm like bcrypt or Argon2. Since these algorithms are slow and computationally expensive, it is challenging for attackers to decipher hashed passwords using them.</li>
<li><strong>Use Salt</strong>: Use a salt to add an extra layer of security when hashing passwords. To make it more challenging for attackers to break passwords using pre-generated hash tables, a salt is a random string that is added to the password before hashing.</li>
<li><strong>Use encryption</strong>: Encrypt sensitive data, like API keys and passwords, before storing it in your database. Libraries like the.NET Identity Framework can be used for this.</li>
</ol>



<p>Here is some sample.NET Core code that shows how to use the Identity Framework to store passwords securely:</p>



<pre class="wp-block-code"><code>services.AddIdentity&lt;ApplicationUser, IdentityRole&gt;(options =&gt;
{
    // Configure password hashing
    options.Password.RequireDigit = true;
    options.Password.RequiredLength = 8;
    options.Password.RequireUppercase = true;
    options.Password.RequireNonAlphanumeric = true;
    options.Password.RequiredUniqueChars = 6;
    options.Password.RequireLowercase = true;

    // Configure password hashing algorithm
    options.Password.HashAlgorithm = PasswordHasherCompatibilityMode.IdentityV3;
})
.AddEntityFrameworkStores&lt;ApplicationDbContext&gt;();</code></pre>



<p>In this code, we set up the Identity Framework to work with the secure Identity V3 password hashing algorithm, which was created for ASP.NET Core Identity. Additionally, we are setting up the password policy to demand a combination of uppercase and lowercase letters, numbers, and special characters, as well as a minimum of 8 characters. Furthermore, Entity Framework is being used to store the hashed passwords in the database.</p>



<p>You can easily store passwords securely in your API and guard against unauthorized access and data breaches by adhering to these best practices and utilizing libraries and frameworks provided by your programming language.</p>



<h3 class="wp-block-heading">Keep an eye out for suspicious activity</h3>



<p>Check the API for suspicious activity, such as failed login attempts or unusually high traffic, using tools like log analysis and anomaly detection.</p>



<p>An essential step in protecting your API from attackers who might try to exploit security holes in your system is monitoring for <a href="https://topreviewhostingasp.net/what-is-ddos-and-how-to-prevent-it/" target="_blank" rel="noreferrer noopener">suspicious activity</a>. Failed login attempts, brute force attacks, and other malicious behavior that might point to an attempt at a breach are examples of suspicious activity. In this section, we&#8217;ll go over the best methods for using.NET or any other well-liked programming language to keep an eye out for suspicious activity in your API.</p>



<p>Here are a few typical actions to take when looking for suspicious activity in your API:</p>



<ol>
<li><strong>Use Logging:</strong> Use logging to track and record all activity in your API. This can be done using libraries like Serilog in .NET.</li>
<li><strong>Use Monitoring Tools</strong>: Use monitoring tools to detect and alert you to suspicious activity in your API. This can be done using tools like Application Insights in .NET.</li>
<li><strong>Set Up Alerts</strong>: Set up alerts to notify you of suspicious activity in your API.</li>
</ol>



<p>Here is some sample.NET Core code that shows how to use Serilog to keep an eye out for suspicious activity:</p>



<pre class="wp-block-code"><code>public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // Add Serilog
    loggerFactory.AddSerilog();

    app.UseHttpsRedirection();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =&gt;
    {
        endpoints.MapRazorPages();
        endpoints.MapControllers();
    });
}</code></pre>



<p>We are integrating Serilog into our API in this code to track all activity. Additionally, we are configuring HTTPS redirection and error handling. We also use Razor Pages and Controllers to process requests.</p>



<p>You can easily monitor for suspicious activity in your API and defend against unauthorized access and data breaches by adhering to these best practices and using libraries and frameworks provided by your programming language.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>In conclusion, the design of secure APIs must include both authentication and authorization. You can help ensure that your API is safeguarded against unauthorized access and other security threats by adhering to best practices for implementing secure user authentication. You can contribute to creating an API that users and developers can rely on by following these steps.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/stay-safe-with-secure-user-authentication/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
