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

<channel>
	<title>asp net core &#8211; ASP.NET Hosting Reviews and Guides</title>
	<atom:link href="https://topreviewhostingasp.net/tag/asp-net-core-3/feed/" rel="self" type="application/rss+xml" />
	<link>https://topreviewhostingasp.net</link>
	<description>ASP.NET Hosting &#124; Reviews &#124; Tips &#38; Tutorial</description>
	<lastBuildDate>Mon, 22 Jul 2024 04:50:07 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://topreviewhostingasp.net/wp-content/uploads/2017/01/cropped-trhaico-32x32.png</url>
	<title>asp net core &#8211; ASP.NET Hosting Reviews and Guides</title>
	<link>https://topreviewhostingasp.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>How to Add Attachments to Adobe Using C#</title>
		<link>https://topreviewhostingasp.net/how-to-add-attachments-to-adobe-using-c/</link>
					<comments>https://topreviewhostingasp.net/how-to-add-attachments-to-adobe-using-c/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Mon, 22 Jul 2024 04:11:52 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[adobe c#]]></category>
		<category><![CDATA[angular]]></category>
		<category><![CDATA[asp net core]]></category>
		<category><![CDATA[asp net core tips]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3867</guid>

					<description><![CDATA[PDF/A-3 supports the embedding of any file type into PDF documents. This enables the transition from electronic paper to an electronic container that stores both the human and machine-readable versions of a document. Applications can extract the machine-readable portion of a PDF document and process it. A PDF/A-3 document can include an unlimited number of [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>PDF/A-3 supports the embedding of any file type into PDF documents. This enables the transition from electronic paper to an electronic container that stores both the human and machine-readable versions of a document. Applications can extract the machine-readable portion of a PDF document and process it. A PDF/A-3 document can include an unlimited number of embedded documents for various processes.</p>
<p>This article will teach you how to embed a plain text file in a PDF document and how to extract the attachment from it.</p>
<h2 id="adding-attachments" data-nav="true">Adding Attachments</h2>
<p>This sample code demonstrates how TX Text Control can be used to attach a text file to a PDF document.</p>
<pre>        // create a non-UI ServerTextControl instance
using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl()) {

  tx.Create();
  // set dummy content
  tx.Text = "PDF Document Content";

  // read the content of the attachment
  string sAttachment = System.IO.File.ReadAllText("attachment.txt");

  // create the attachement
  TXTextControl.EmbeddedFile attachment =
     new TXTextControl.EmbeddedFile(
        "attachment.txt",
        sAttachment,
        null) {
       Description = "My Text File",
       Relationship = "Unspecified",
       MIMEType = "application/txt",
       CreationDate = DateTime.Now,
     };

  // attached the embedded file
  tx.DocumentSettings.EmbeddedFiles =
     new TXTextControl.EmbeddedFile[] { attachment };

  // save as PDF/A
  tx.Save("document.pdf", TXTextControl.StreamType.AdobePDFA);
}</pre>
<p>The attached file is represented by the EmbeddedFile object. The constructor accepts the file name, data, and additional meta data. In addition, the MIME type of the attachment (application/text in this case), a textual description, a relationship, and the creation date are provided.</p>
<p>The relationship is an optional string that describes the relationship between the embedded file and the containing document. It can be a predefined value or adhere to the rules for second-class names (ISO 32000-1, Annex E). Predefined values include <strong>&#8220;Source&#8221;</strong>, <strong>&#8220;Data&#8221;</strong>, <strong>&#8220;Alternative&#8221;</strong>, <strong>&#8220;Supplement&#8221;</strong>, and <strong>&#8220;Unspecified&#8221;</strong>.</p>
<p>When you open the document in Adobe Acrobat Reader, the attachment will appear in the Attachments side panel.</p>
<p><img fetchpriority="high" decoding="async" class="size-full wp-image-3868 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/07/attachment.webp" alt="" width="988" height="724" srcset="https://topreviewhostingasp.net/wp-content/uploads/2024/07/attachment.webp 988w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/attachment-300x220.webp 300w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/attachment-768x563.webp 768w, https://topreviewhostingasp.net/wp-content/uploads/2024/07/attachment-50x37.webp 50w" sizes="(max-width: 988px) 100vw, 988px" /></p>
<h2 id="extracting-attachments" data-nav="true">Extracting Attachments</h2>
<p>The code below loads the created PDF file in order to locate the attachment by looping through all embedded files. The found attachment is extracted and saved as a text file.</p>
<pre>// create a non-UI ServerTextControl instance
using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl()) {

  tx.Create();

  // load the PDF document
  TXTextControl.LoadSettings ls = new TXTextControl.LoadSettings();
  tx.Load("document.pdf", TXTextControl.StreamType.AdobePDF, ls);

  // read the attachments
  TXTextControl.EmbeddedFile[] files = ls.EmbeddedFiles;

  // find the specific attachment and save it
  foreach(TXTextControl.EmbeddedFile file in files) {
    if (file.Description == "My Text File") {
      string sAttachment = Encoding.UTF8.GetString((byte[])file.Data);
      System.IO.File.WriteAllText("attachment_read.txt", sAttachment);

      break;
    }
  }
}</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-add-attachments-to-adobe-using-c/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Basic Concepts and Hosting Models Selection ASP.NET Core Blazor</title>
		<link>https://topreviewhostingasp.net/basic-concepts-and-hosting-models-selection-asp-net-core-blazor/</link>
					<comments>https://topreviewhostingasp.net/basic-concepts-and-hosting-models-selection-asp-net-core-blazor/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Thu, 30 May 2024 03:43:56 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net core]]></category>
		<category><![CDATA[asp net core blazor]]></category>
		<category><![CDATA[asp net core tips]]></category>
		<category><![CDATA[asp net core tutorial]]></category>
		<category><![CDATA[webassembly asp net core]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3843</guid>

					<description><![CDATA[A summary of some fundamental Blazor ideas, including the benefits and drawbacks of WebAssembly and server models. Blazor Microsoft created the Blazor framework to facilitate the development of contemporary web applications. The primary benefit lies in the fact that developers can utilize C# to directly create dynamic and interactive web applications. To achieve high-performance application [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>A summary of some fundamental Blazor ideas, including the benefits and drawbacks of WebAssembly and server models.</p>
<h2 id="blazor">Blazor</h2>
<p>Microsoft created the Blazor framework to facilitate the development of contemporary web applications. The primary benefit lies in the fact that developers can utilize C# to directly create dynamic and interactive web applications. To achieve high-performance application development, Blazor uses WebAssembly, a technology that lets back-end code run in the browser similarly to JavaScript, to execute C# programs on the client side.</p>
<p>The introduction given above ought to be sufficient to pique the curiosity of back-end developers who typically work with C#. After actually learning it, I believe the learning curve is fairly easy to navigate if you have some prior knowledge of the C# language. If developers are unfamiliar with the front-end and would like to try learning the full-end, I strongly suggest that they use the Blazor framework as a foundation.</p>
<h2 id="blazor-webassembly-vs-blazor-server">Blazor WebAssembly vs. Blazor Server</h2>
<p>Blazor offers two choices for hosting models. Learning was challenging at first. Allow me to clarify the distinctions between the two.</p>
<p><img decoding="async" class=" wp-image-3844 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/05/blazor-webassembly.png" alt="" width="402" height="225" srcset="https://topreviewhostingasp.net/wp-content/uploads/2024/05/blazor-webassembly.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2024/05/blazor-webassembly-50x28.png 50w" sizes="(max-width: 402px) 100vw, 402px" /></p>
<p>When a user visits the website, the front end uses SignalR, a C# package that implements the WebSocket two-way communication function, to connect to the back end server. The back end provides the majority of the data.</p>
<p>A few advantages are:</p>
<ul>
<li>Compared to WebAssembly mode, the initial loading speed is faster.</li>
<li>In contrast to WebAssembly&#8217;s static website, the API&#8217;s functionality is retained in the Server model.</li>
</ul>
<p>Limitations:</p>
<ul>
<li>The website cannot be accessed if the network is unstable or breaks midway because SignalR is used to transmit information (if the connection is only momentary, the browser will automatically reconnect).</li>
<li>For the website to continue to function, users must be connected. There is a maximum number of connection pools determined by the hardware. This implies that issues could arise if numerous users attempt to connect at once!?</li>
</ul>
<h3 id="blazor-webassembly">Blazor WebAssembly</h3>
<div class="image-container">As can be observed, the client side handles every aspect of the architecture directly. The standalone Blazor WebAssembly application loads upon user connection, and further operations don&#8217;t need communication with the back-end server.</p>
<p>A few advantages are:</p></div>
<div>
<ul>
<li>It is self-sufficient. Consider it as if you were directly downloading an application. The server is unaffected by further use. It is still functional even if disconnected.</li>
<li>After the user accesses the webpage, they can fully utilize the client resources rather than depending on the server resources because there is no interaction with the backend server.</li>
<li>It is simple to set up and is a static webpage.</li>
</ul>
<p>Limitations:</p>
<ul>
<li>The client must enable WebAssembly, which is becoming more and more popular.</li>
<li>The first time you load the web page, it will take a while because the entire code is loaded on the user&#8217;s side.</li>
<li>Similar to the previous example, please take great care when implementing the code because it cannot be protected once it is sent to the client.</li>
</ul>
<h2 id="how-to-choose-hosting-models">How to choose Hosting Models</h2>
<p>When comparing the two models, it can be seen that each has pros and cons of its own, with the drawbacks potentially being resolved in different ways. For instance, you can use loading effects to fix issues where Blazor Server won&#8217;t work if it can&#8217;t connect, and you can adjust the reconnect message that appears when it does. If Blazor WASM isn&#8217;t loading quickly the first time, you can also use loading effects to fix the issue.</p>
<p>In my opinion, Blazor Server is a good option if the project involves a back-end management system, the user base is predictable, and the database needs to be maintained. Blazor WASM is a good option if the project is just a small informational website.</p>
<h3 id="blazor-hybrid">Blazor Hybrid</h3>
<p>Alternatively, you can select the ASP.NET Core Hosted Blazor WASM Hybrid mode to get the best of both worlds. To put it briefly, the back end uses.NET Core to perform API operations, while the front end is WASM. It resolves issues with Blazor Server&#8217;s need for a constant connection, WASM&#8217;s need to preload pages if a website is too big, and security issues with all codes needing to be forwarded to the client.</p>
<p>Several.NET native application architectures, such as.NET MAUI, WPF, and Windows Forms, can be used to create hybrid applications. I decided to construct it using the.NET Core API. This type of Blazor WASM Hosted is very easy to construct. Simply decide to use Visual Studio to build the Blazor WebAssembly project. Select ASP.NET Core Hosted from the framework selection screen and create it.</p>
<p><img decoding="async" class=" wp-image-3845 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/05/create-blazor-wasm-hybrid-project.webp" alt="" width="772" height="511" srcset="https://topreviewhostingasp.net/wp-content/uploads/2024/05/create-blazor-wasm-hybrid-project.webp 1264w, https://topreviewhostingasp.net/wp-content/uploads/2024/05/create-blazor-wasm-hybrid-project-300x199.webp 300w, https://topreviewhostingasp.net/wp-content/uploads/2024/05/create-blazor-wasm-hybrid-project-1024x678.webp 1024w, https://topreviewhostingasp.net/wp-content/uploads/2024/05/create-blazor-wasm-hybrid-project-768x509.webp 768w, https://topreviewhostingasp.net/wp-content/uploads/2024/05/create-blazor-wasm-hybrid-project-50x33.webp 50w" sizes="(max-width: 772px) 100vw, 772px" /></p>
<p>The following is the project&#8217;s structure:</p>
<p><img loading="lazy" decoding="async" class=" wp-image-3846 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2024/05/blazor-wasm-hybrid-project-structure.webp" alt="" width="353" height="532" srcset="https://topreviewhostingasp.net/wp-content/uploads/2024/05/blazor-wasm-hybrid-project-structure.webp 427w, https://topreviewhostingasp.net/wp-content/uploads/2024/05/blazor-wasm-hybrid-project-structure-199x300.webp 199w, https://topreviewhostingasp.net/wp-content/uploads/2024/05/blazor-wasm-hybrid-project-structure-33x50.webp 33w" sizes="(max-width: 353px) 100vw, 353px" /></p>
<p><code>BlazorApp1.Client</code> is part of WebAssembly and is mainly responsible for front-end screen display.<br />
<code>BlazorApp1.Server</code> is part of the back-end Web API. Its implementation is consistent with ASP.NET Web API, and the controller controls the API.<br />
<code>BlazorApp1.Shared</code> is the object storage location for use by Client and Server.</p>
</div>
<h2 id="conclusion">Conclusion</h2>
<p>A completely new framework with great efficiency and flexibility is called Blazor. It is ideal for developers who have experience with the C# language. They are aware of the difficulties faced by back-end engineers who lack front-end experience. They can quickly create a front-end and back-end application for basic applications after using it for personal use. Blazor is a good place to start if you want to communicate with the front-end or full-end.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/basic-concepts-and-hosting-models-selection-asp-net-core-blazor/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>5 Best Secure ASP.NET Core Hosting</title>
		<link>https://topreviewhostingasp.net/5-best-secure-asp-net-core-hosting/</link>
					<comments>https://topreviewhostingasp.net/5-best-secure-asp-net-core-hosting/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Mon, 02 Oct 2023 09:15:00 +0000</pubDate>
				<category><![CDATA[Hosting Review]]></category>
		<category><![CDATA[asp net core]]></category>
		<category><![CDATA[asp net core hosting]]></category>
		<category><![CDATA[best secure asp net core hosting]]></category>
		<category><![CDATA[fast secure asp net core hosting]]></category>
		<category><![CDATA[reliable asp net core hosting]]></category>
		<category><![CDATA[secure asp net core hosting]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3742</guid>

					<description><![CDATA[There are a number of things to take into account when selecting a host for your ASP.NET Core website. Frequently, speed, performance, and uptime are regarded as the &#8220;deal-breakers&#8221; (and they should be), but one crucial aspect that&#8217;s frequently overlooked, or at least given significantly less attention, is web security. The safety and security of [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>There are a number of things to take into account when selecting a host for your ASP.NET Core website. Frequently, speed, performance, and uptime are regarded as the &#8220;deal-breakers&#8221; (and they should be), but one crucial aspect that&#8217;s frequently overlooked, or at least given significantly less attention, is web security.</p>
<p>The safety and security of your data is obviously crucial, so when selecting a web hosting company, you should carefully consider its cybersecurity credentials. After all, a quick, efficient website that loses its users&#8217; trust due to lax security measures won&#8217;t be very successful.</p>
<p>The significance of dependable and secure hosting may already be clear to you if you are the owner website. If not, you might want to keep reading because we&#8217;ll break down the key security features you should consider when selecting a hosting solution and reveal the top 5 best secure ASP.NET hosting companies in terms of security.</p>
<p>Let’s get started.</p>
<p><img loading="lazy" decoding="async" class="wp-image-3384 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/cybersecurity-1.jpg" alt="" width="486" height="243" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/cybersecurity-1.jpg 318w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/cybersecurity-1-300x150.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/cybersecurity-1-50x25.jpg 50w" sizes="(max-width: 486px) 100vw, 486px" /></p>
<h2>What to look for in a hosting provider in terms of security</h2>
<p>Most ASP.NET Core hosting companies will advertise a variety of features designed to keep your website or application (and, of course, your data) secure, but it&#8217;s important to carefully review your hosting package before you sign up because many of these features might not come as standard — some might, for example, only be available on higher-priced plans.</p>
<p>To avoid being caught off guard, make sure the hosting plan you choose includes all the security precautions you need. Your hosting company should at the very least provide the following security features:</p>
<ul>
<li><strong>SSL Certificate:</strong>An <a href="https://topreviewhostingasp.net/how-to-install-free-ssl-certificate-asphostportal/" target="_blank" rel="noopener">SSL certificate</a> is a particular kind of digital certificate that is used to verify a website&#8217;s legitimacy and encrypt data sent between the website and a user&#8217;s computer. It makes sure that all information exchanged between the server and the user is secure and private.</li>
<li><strong>Firewall:</strong>A firewall is a security system created to stop unauthorized access to a computer or private network (also known as a web application firewall). It is intended to filter traffic between various networks and stop malicious traffic from entering the protected system. It may be hardware- or software-based.</li>
<li><strong>Bot Protection</strong>: Bot protection is a type of security that employs automated tools and algorithms to find, keep an eye on, and prevent malicious bots from entering a network or website. Additionally, it can be used to identify and stop harmful behaviors like spamming and data scraping.</li>
<li><strong>Login Security:</strong> A set of safeguards used to make sure that only authorized users can access an online system is known as login security. To ensure the security of user accounts, two-factor authentication is frequently used, along with strong password guidelines and other security measures.</li>
<li><strong>User Access Management:</strong>User access management (UAM) is a security procedure used to regulate and keep track of user access to system resources. In order to ensure that access control policies are being followed, it typically entails creating user accounts, assigning permissions and privileges, and monitoring user activity.</li>
<li><strong>End-to-End Encryption:</strong> End-to-end encryption is a type of communication where only the people who are supposed to read the data can do so. It is typically used to protect sensitive data by ensuring that only the intended recipients can access the data, such as financial information or medical records.</li>
<li><strong>Two-Factor Authentication:</strong> Users must supply two pieces of information as part of a security procedure called two-factor authentication (2FA) in order to access a system or service. Most frequently, a password and a code are sent to the user&#8217;s mobile device for these two pieces of information.</li>
</ul>
<p>In spite of the fact that the number of security features a company needs may vary depending on a variety of factors, including the nature of the company, the sensitivity of its data, the make-up of its workforce, etc., cybersecurity best practice calls for having multiple layers of defense in place.</p>
<p>The five ASP.NET Core hosting companies listed below are the ones we believe provide your company with the best overall security.</p>
<h3>1. ASPHostPortal</h3>
<p><a href="https://www.asphostportal.com" target="_blank" rel="noopener"><img loading="lazy" decoding="async" class="size-full wp-image-2653 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2019/01/asphostportal-slidere.jpg" alt="ASPHostPortal" width="1920" height="901" srcset="https://topreviewhostingasp.net/wp-content/uploads/2019/01/asphostportal-slidere.jpg 1920w, https://topreviewhostingasp.net/wp-content/uploads/2019/01/asphostportal-slidere-300x141.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2019/01/asphostportal-slidere-768x360.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2019/01/asphostportal-slidere-1024x481.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2019/01/asphostportal-slidere-50x23.jpg 50w" sizes="(max-width: 1920px) 100vw, 1920px" /></a></p>
<p>ASPHostPortal is a Windows hosting service that also provides ASP.NET Core hosting. It is a simple, one-click hosting platform with more than 10,000 global servers. Dedicated firewalls, continuous real-time monitoring, automated backups, and regular security patching are just a few of the impressive range of security features it offers to keep your website or app safe from the newest threats. Enterprise-level security with cutting-edge defense against threats from distributed denial-of-service (DDoS) attacks is what ASPHostPortal promises through its partnership with the sector-leading CDN provider <a href="https://topreviewhostingasp.net/free-ssl-cloudflare-asphostportal-hosting/" target="_blank" rel="noopener">Cloudflare</a> (the ASPHostPortal Enterprise add-on is included as standard).</p>
<p><strong>Security features include:</strong></p>
<ul>
<li>Free SSL certificate</li>
<li>Automated backups</li>
<li>Web Application Firewall (WAF)</li>
<li>End-to-end encryption</li>
<li>Malcare bot protection</li>
<li>Two-factor authentication (2FA)</li>
<li>Cloudflare Enterprise add-on</li>
</ul>
<h3>2. HostForLIFE.eu</h3>
<p><a href="https://www.hostforlife.eu" target="_blank" rel="noopener"><img loading="lazy" decoding="async" class="size-full wp-image-673 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2017/07/hostforlife-home-page.jpg" alt="" width="1336" height="656" srcset="https://topreviewhostingasp.net/wp-content/uploads/2017/07/hostforlife-home-page.jpg 1336w, https://topreviewhostingasp.net/wp-content/uploads/2017/07/hostforlife-home-page-300x147.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2017/07/hostforlife-home-page-768x377.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2017/07/hostforlife-home-page-1024x503.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2017/07/hostforlife-home-page-50x25.jpg 50w" sizes="(max-width: 1336px) 100vw, 1336px" /></a></p>
<p>With a variety of shared and cloud hosting options, <a href="https://www.hostforlife.eu" target="_blank" rel="noopener">HostForLIFE.eu</a> was established in 2004 and now hosts more than 2 million domains globally. Although it is on the more &#8220;premium&#8221; end of the web hosting spectrum, its pricing reflects this. However, as with many other things, you get what you pay for. A dedicated IP, a free SSL certificate for each domain, and automatic daily data backups are standard features included with every HostForLIFE plan. HostForLIFE.eu is a complete but expensive solution that works best for big businesses with complicated cloud infrastructures and special security requirements.</p>
<p><strong>Security features include:</strong></p>
<ul>
<li>Free SSL certificate</li>
<li>Automated daily backups</li>
<li>Web Application Firewall (WAF)</li>
<li>Regular patches and updates</li>
<li>Real-time server monitoring</li>
<li>AI anti-bot system</li>
<li>Spam protection</li>
</ul>
<h3>3. UKWindowsHostASP.NET</h3>
<p><a href="https://www.ukwindowshostasp.net" target="_blank" rel="noopener"><img loading="lazy" decoding="async" class="size-full wp-image-2764 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2019/10/ukwindowshostasp-main-page.jpg" alt="" width="1342" height="614" srcset="https://topreviewhostingasp.net/wp-content/uploads/2019/10/ukwindowshostasp-main-page.jpg 1342w, https://topreviewhostingasp.net/wp-content/uploads/2019/10/ukwindowshostasp-main-page-300x137.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2019/10/ukwindowshostasp-main-page-768x351.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2019/10/ukwindowshostasp-main-page-1024x469.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2019/10/ukwindowshostasp-main-page-50x23.jpg 50w" sizes="(max-width: 1342px) 100vw, 1342px" /></a></p>
<p>When it comes to online security, <a href="https://www.UKWindowsHostASP.NET" target="_blank" rel="noopener">UKWindowsHostASP.NET</a> may not be as fully featured as some other ASP.NET Core hosting solutions, but it is still a very dependable and secure option that is advised for smaller businesses or those with simpler infrastructures. The affordable cloud hosting plans from UKWindowsHostASP.NET come with all of your essential security features as well as a few more sophisticated ones. All hosting plans include features like SSL certificates, automated backups, and multi-factor authentication (MFA), and for an additional fee, you can use the &#8220;UKWinShield&#8221; malware removal tool for additional security.</p>
<p><strong>Security features include:</strong></p>
<ul>
<li>SSL certificates</li>
<li>Multi-factor authentication</li>
<li>Automatic daily backups</li>
<li>Domain privacy protection</li>
<li>Firewalls for IIS</li>
<li>‘UKWinShield’ malware removal tool</li>
</ul>
<h3>4. WindowsASPNETHosting.in</h3>
<p><a href="https://www.windowsaspnethosting.in" target="_blank" rel="noopener"><img loading="lazy" decoding="async" class="size-full wp-image-599 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2017/05/WindowsASPNETHosting.in_.jpg" alt="" width="900" height="439" srcset="https://topreviewhostingasp.net/wp-content/uploads/2017/05/WindowsASPNETHosting.in_.jpg 900w, https://topreviewhostingasp.net/wp-content/uploads/2017/05/WindowsASPNETHosting.in_-300x146.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2017/05/WindowsASPNETHosting.in_-768x375.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2017/05/WindowsASPNETHosting.in_-50x24.jpg 50w" sizes="(max-width: 900px) 100vw, 900px" /></a></p>
<p>Similar to UKWindowsHostASP.NET, <a href="https://www.WindowsASP.NETHosting.in" target="_blank" rel="noopener">WindowsASP.NETHosting.in</a> is an inexpensive but surprisingly secure ASP.NET Core hosting option that is perfect for meeting the security requirements of small- to medium-sized businesses. In addition to offering a variety of inexpensive cloud hosting plans and virtual private server (VPS) hosting, WindowsASPNETHosting.in also integrates with Cloudflare to safeguard your website from DDoS attacks using a built-in DNS firewall. There are also tools like &#8220;SpamAssassin&#8221; (which detects and eliminates email spam) and &#8220;Bitninja,&#8221; a security suite that guards against automated assaults like cross-site scripting (XSS), malware, and brute-force attacks.</p>
<p><strong>Security features include:</strong></p>
<ul>
<li>Free SSL certificate</li>
<li>Automated daily or weekly backups</li>
<li>‘SpamAssassin’ tool for removing email spam</li>
<li>‘Bitninja’ tool to prevents automated attacks</li>
<li>Two-factor authentication</li>
<li>Cloudflare DDoS firewall</li>
</ul>
<h3>5. DiscountService.biz</h3>
<p><a href="https://www.discountservice.biz" target="_blank" rel="noopener"><img loading="lazy" decoding="async" class="size-full wp-image-3585 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/discountservice-min.jpg" alt="" width="1339" height="579" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/discountservice-min.jpg 1339w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/discountservice-min-300x130.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/discountservice-min-1024x443.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/discountservice-min-768x332.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/discountservice-min-50x22.jpg 50w" sizes="(max-width: 1339px) 100vw, 1339px" /></a></p>
<p><a href="https://www.discountservice.biz" target="_blank" rel="noopener">DiscountService.biz</a> is well known for its quick speeds (it promises to make your servers run up to 20x faster), but that&#8217;s not all it has to offer: it also includes a range of strong security features, making it a great combination of speed and security. However, DiscountService does provide a variety of VPS hosting solutions with dedicated server resources. DiscountService does not currently offer traditional cloud hosting. When it comes to website security, DiscountService provides a dual firewall (guarding both the server and the network from threats), sophisticated DDoS protection, and a &#8216;HackScan&#8217; tool that offers round-the-clock malware protection.</p>
<p><strong>Security features include:</strong></p>
<ul>
<li>Free SSL certificate</li>
<li>DDoS protection</li>
<li>Automatic backups (not included in the Standard plan)</li>
<li>‘HackScan’ 24/7 malware protection</li>
<li>Server and network firewalls</li>
<li>Server hardening</li>
<li>Two-factor authentication</li>
</ul>
<h2>Conclusion</h2>
<p>In website management, security issues can come from a variety of different places. Security is crucial, whether you choose a shared hosting plan or dedicated hosting. The performance of your website can be significantly impacted by vulnerabilities in plugins, themes, or other software, making it more vulnerable to hackers. Users can avoid some security issues by selecting a ASP.NET Core hosting provider with robust security measures, even though many security issues can be unpredictable.</p>
<p>Depending on the security options it offers, a ASP.NET host may have a direct impact on the security of a website. The features that hosting companies can offer to help secure your website range from firewall protection to SSL encryption. You can figure out which hosting company offers the best protection options by comparing the feature lists of various hosting companies.</p>
<p>A comprehensive set of security features should include a combination of the following:</p>
<ul>
<li>Your personal information can be protected from hackers by using domain security, which also stops them from stealing your credit card or domain login information.</li>
<li>To stop unauthorized access to your website, firewall protection filters through incoming requests.</li>
<li>Backups are a crucial element of a contingency plan. Automatically recover and restore your deleted or lost data.</li>
<li>Your website&#8217;s traffic is secured, and endpoint communication is protected, thanks to an SSL certificate.</li>
<li>DDoS mitigation will safeguard your website against unforeseen attacks and stop them from causing issues with downtime.</li>
<li>Scanners for websites can assist in defending your website against malware and other harmful threats.</li>
</ul>
<p>The security of your website depends on your choice of ASP.NET Core host, especially if you&#8217;re thinking about using a free or inexpensive service. Verify certifications and compliance standards to see if they have been met. By reading customer reviews, you can also learn more about their security procedures and background. This will help you stay away from disappointments and scams.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/5-best-secure-asp-net-core-hosting/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 Setup Angular Code in ASP.NET Core Project</title>
		<link>https://topreviewhostingasp.net/setup-angular-code-in-asp-net-core-project/</link>
					<comments>https://topreviewhostingasp.net/setup-angular-code-in-asp-net-core-project/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Thu, 10 Aug 2023 03:55:42 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[angular]]></category>
		<category><![CDATA[angular tips]]></category>
		<category><![CDATA[angular tutorial]]></category>
		<category><![CDATA[asp net core]]></category>
		<category><![CDATA[asp net core tutorial]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3681</guid>

					<description><![CDATA[Due to their low weight and high performance, Single-Page Applications, or SPAs, have recently become the most sought-after client facing application stacks. In this architecture, the client application renders the fetched data onto a fluid and dynamic layout while the server concentrates on data logic and provides data to the client in the form of [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Due to their low weight and high performance, Single-Page Applications, or SPAs, have recently become the most sought-after client facing application stacks. In this architecture, the client application renders the fetched data onto a fluid and dynamic layout while the server concentrates on data logic and provides data to the client in the form of RESTful APIs.</p>



<p>In addition to improving user experience, this can lessen the load placed on the webserver when rendering and serving HTML content over the network. In order to create the most effective SPAs, client-side frameworks like Angular, ReactJs, and Ionic have advanced significantly. Let&#8217;s discuss how to integrate an SPA powered by Angular inside of an existing ASP.NET Core application in this article.</p>



<p>Assume that the data source for an Angular application is an ASP.NET Core application. We now have two options for deployment: running two instances of both the client and server applications, with the client application configured with the server endpoint. Most of the real-world application deployments we see today are done in this manner.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>A webserver like IIS or Apache must once again host an SPA, which is simply an index.html page with a few js files for runtime and client logic.</p></blockquote>



<p>An innovative method has been developed that sandwiched an angular SPA inside an ASP.NET Core API because we would also need to require the client application to maintain the server address for communication.</p>



<p>With this method, both applications can be created and deployed on a single instance, and they are both local to one another. When a user calls the appropriate routes, the ASPNETCORE application also serves the client application to them. A few libraries must be added to the ASP.NET Core API, and the csproj file must be modified to allow for angular build activities.</p>



<h2 class="wp-block-heading">Steps to Implement Code in ASP.NET Core</h2>



<p>1. Start by copying the Angular application into the ClientApp subdirectory of the ASPNETCORE project. Together with the controllers and other projects, this is located in the root directory. Just keep in mind that since we&#8217;re using an ASPNETCORE API project, we don&#8217;t have a wwwroot folder or Views folder.</p>



<p>2. Install the package listed below, which supports SPA building and rendering, in the ASPNETCORE project.</p>



<pre class="wp-block-preformatted">&lt;PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.3" /&gt;</pre>



<p>3. To support SPA, we would need to add a few middlewares and services to the Startup class. The server application would route to an SPA when making specific requests technically because it is just a collection of static files under the ASPNETCORE project. We would also add support for the server to access these static files in order to make this possible.</p>



<p>The middleware functions UseStaticFiles() and UseSpa() for SPA support accomplish this.</p>



<pre class="wp-block-code"><code>public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
            
    // In production, the Angular files will be served from this directory
    services.AddSpaStaticFiles(configuration =>
    {
        configuration.RootPath = "ClientApp/dist";
    });
}</code></pre>



<pre class="wp-block-code"><code>public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseStaticFiles();
    
    // In Production Environment
    // Serve Spa static files
    if (!env.IsDevelopment())
    {
        app.UseSpaStaticFiles();
    }

    // other ASPNETCORE Routing Code
    // Spa middleware to enable
    // SPA request handling
    app.UseSpa(spa =>
    {
        // The directory from which the 
        // SPA files shall be served for
        // client requests
        spa.Options.SourcePath = "ClientApp";

        // When in Development,
        // Since the SPA app is not build
        // use npm start command to run 
        // the node server for local run
        if (env.IsDevelopment())
        {
            spa.UseAngularCliServer(npmScript: "start");
        }
    });
}</code></pre>



<p>4. We make sure the angular build command configuration in the angular.json file of the client application, which is under the ClientApp directory, so that on angular build, the files are created under the /dist folder relative to the Client app path.</p>



<pre class="wp-block-code"><code>        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "progress": false,
            "extractCss": true,
            "outputPath": "dist", &lt;-- ensure this path
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": &#91;"src/assets"],
            "styles": &#91;
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "src/styles.css"
            ],
            "scripts": &#91;]
          }
        }</code></pre>



<p>This is significant because, when running, the ASPNETCORE application searches for the Spa files under the services-specified path /ClientApp/dist folder.Method AddSpaStaticFiles().</p>



<p>5. Finally, using the csproj and the changes listed below, we wire up the ClientApp and ASPNETCORE app together during project build.</p>



<pre class="wp-block-code"><code>&lt;ItemGroup>
    &lt;!-- Don't publish the SPA source files, but do show them in the project files list -->
    &lt;Content Remove="$(SpaRoot)**" />
    &lt;None Remove="$(SpaRoot)**" />
    &lt;None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules**" />
  &lt;/ItemGroup></code></pre>



<pre class="wp-block-code"><code>&lt;!-- Debug run configuration -->
  &lt;!-- Check for Nodejs installation, install in the ClientApp -->
  &lt;Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
    &lt;!-- Ensure Node.js is installed -->
    &lt;Exec Command="node --version" ContinueOnError="true">
      &lt;Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
    &lt;/Exec>
    &lt;Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
    &lt;Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
    &lt;Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
  &lt;/Target></code></pre>



<pre class="wp-block-code"><code>&lt;!-- Publish time tasks: run npm build along with project publish -->
  &lt;Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
    &lt;!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
    &lt;Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
    &lt;Exec WorkingDirectory="$(SpaRoot)" Command="npm run build -- --prod" />
    &lt;Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr -- --prod" Condition=" '$(BuildServerSideRenderer)' == 'true' " />

    &lt;!-- Include the newly-built files in the publish output -->
    &lt;ItemGroup>
      &lt;DistFiles Include="$(SpaRoot)dist**; $(SpaRoot)dist-server**" />
      &lt;DistFiles Include="$(SpaRoot)node_modules**" Condition="'$(BuildServerSideRenderer)' == 'true'" />
      &lt;ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
        &lt;RelativePath>%(DistFiles.Identity)&lt;/RelativePath>
        &lt;CopyToPublishDirectory>PreserveNewest&lt;/CopyToPublishDirectory>
        &lt;ExcludeFromSingleFile>true&lt;/ExcludeFromSingleFile>
      &lt;/ResolvedFileToPublish>
    &lt;/ItemGroup>
  &lt;/Target></code></pre>



<p>In each of these configurations, we define $(SpaRoot) at the top of the csproj file as the ClientApp rootpath:</p>



<pre class="wp-block-code"><code>&lt;PropertyGroup>
    &lt;TargetFramework>netcoreapp3.1&lt;/TargetFramework>
    &lt;TypeScriptCompileBlocked>true&lt;/TypeScriptCompileBlocked>
    &lt;TypeScriptToolsVersion>Latest&lt;/TypeScriptToolsVersion>
    &lt;IsPackable>false&lt;/IsPackable>

    &lt;!-- the path picked up by all the processing -->
    &lt;SpaRoot>ClientApp&lt;/SpaRoot>
    &lt;DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules**&lt;/DefaultItemExcludes>
    &lt;!-- Set this to true if you enable server-side prerendering -->
    &lt;BuildServerSideRenderer>false&lt;/BuildServerSideRenderer>
&lt;/PropertyGroup></code></pre>



<p>When everything is finished, we can simply publish our project.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/angular-build.webp" alt="" class="wp-image-3682" width="761" height="407" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/angular-build.webp 847w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/angular-build-300x160.webp 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/angular-build-768x411.webp 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/angular-build-50x27.webp 50w" sizes="(max-width: 761px) 100vw, 761px" /></figure></div>


<p>and run to see our changes coming into effect.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" src="https://topreviewhostingasp.net/wp-content/uploads/2023/08/angular-build-run.webp" alt="" class="wp-image-3683" width="809" height="367" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/08/angular-build-run.webp 848w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/angular-build-run-300x136.webp 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/angular-build-run-768x349.webp 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/08/angular-build-run-50x23.webp 50w" sizes="(max-width: 809px) 100vw, 809px" /></figure></div>]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/setup-angular-code-in-asp-net-core-project/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>Custom Output Caching in ASP.NET Core</title>
		<link>https://topreviewhostingasp.net/custom-output-caching-in-asp-net-core/</link>
					<comments>https://topreviewhostingasp.net/custom-output-caching-in-asp-net-core/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 01 Aug 2023 04:26:24 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net]]></category>
		<category><![CDATA[asp net core]]></category>
		<category><![CDATA[asp net core tutorial]]></category>
		<category><![CDATA[caching asp net core]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3648</guid>

					<description><![CDATA[Background Once a page has been cached in the browser (or proxy), the server cannot make the cached copy be utilized in place of the updated version. Pages that are likely to change cannot, therefore, be cached at the client for very long. There is nothing we can do to change this. We should have [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>Background</h2>
<p>Once a page has been cached in the browser (or proxy), the server cannot make the cached copy be utilized in place of the updated version. Pages that are likely to change cannot, therefore, be cached at the client for very long. There is nothing we can do to change this.</p>
<p>We should have greater control at the server, but sadly, the built-in response caching prevents cache invalidation. Additionally, it employs the same cache duration for asking the browser to cache the page and for server-side caching. Some apps cannot use the built-in response caching due to these limitations.</p>
<p>We are going to investigate developing a unique response caching system. We&#8217;ll presum the following conditions:</p>
<ul>
<li>Allow server and client cache durations to be different</li>
<li>Allow an arbitrary page to be removed from the cache at will</li>
<li>Allow multiple cached pages to be removed based on a common criterion (tags)</li>
</ul>
<p>The fundamental prerequisite is the capacity for endless caching at the server and the ability for application code to invalidate current cache entries when content changes.</p>
<p>Additionally, we&#8217;ll prioritize efficiency and quickness over adaptability. IMemoryCache will be used to implement the cache for a single web server. It is simple to go from using IMemoryCache to IDistributedCache in web farm scenarios, however because of this interface&#8217;s less features, the third criteria (tagged) cannot be met without a redesign.</p>
<h2>Implementation</h2>
<p>We will implement our caching as middleware that runs before MVC and can short-circuit the entire request pipeline if a cached page is found in order to enable it to be as quick as feasible.</p>
<p>We have the following flow for a page that is not in the cache:</p>
<ol>
<li>Fail to retrieve page from the cache</li>
<li>Execute inner middleware (the MVC pipeline) redirecting the response to a buffer</li>
<li>Cache the page (if conditions are met)</li>
<li>Render page</li>
</ol>
<p>The sequence is substantially shorter for a page that has already been cached:</p>
<ol>
<li>Retrieve page from cache</li>
<li>Render page</li>
</ol>
<p>The quickest way to return cached material is using middleware, but it is more challenging to allow specific page cache setup. The middleware might be utilized independently if all pages were cached using the same criteria, but for the majority of real-world sites, we require the ability to control which pages are cached and for how long. Although middleware configuration might be used, using attributes on controller actions is considerably simpler.</p>
<h3>Controlling server caching</h3>
<p>We&#8217;ll use a very basic action filter attribute to let us manage how specific pages are cached:</p>
<pre><code>public class CacheAttribute : ActionFilterAttribute
{
    public int? ClientDuration { get; set; }
    public int? ServerDuration { get; set; }
    public string Tags { get; set; }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // validation omitted

        if (ClientDuration.HasValue)
        {
            context.HttpContext.Items[Constants.ClientDuration] = ClientDuration.Value;
        }

        if (ServerDuration.HasValue)
        {
            context.HttpContext.Items[Constants.ServerDuration] = ServerDuration.Value;
        }

        if (!string.IsNullOrWhiteSpace(Tags))
        {
            context.HttpContext.Items[Constants.Tags] = Tags;
        }

        base.OnActionExecuting(context);
    }
}</code></pre>


<p>The filter&#8217;s simple implementation only adds the attribute values to the collection of HttpContext Items. To communicate between the operation and the middleware for caching, we are using the collection.</p>



<h3 class="wp-block-heading">The middleware</h3>



<p>The primary Invoke method of the middleware is quite readable:</p>



<pre class="wp-block-code"><code>public async Task Invoke(HttpContext context)
{
    var key = BuildCacheKey(context);

    if (_cache.TryGet(key, out CachedPage page))
    {
        await WriteResponse(context, page);

        return;
    }

    ApplyClientHeaders(context);

    if (IsNotServerCachable(context))
    {
        await _next.Invoke(context);

        return;
    }            

    page = await CaptureResponse(context);

    if (page != null)
    {
        var serverCacheDuration = GetCacheDuration(context, Constants.ServerDuration);

        if (serverCacheDuration.HasValue)
        {
            var tags = GetCacheTags(context, Constants.Tags);

            _cache.Set(key, page, serverCacheDuration.Value, tags);
        }
    }            
}</code></pre>



<p>Your requirements will determine how you construct the cache key, however it may only require the use of context.Request.Path.</p>



<p>The request is finished if the page can be retrieved from the cache and written to the response.</p>



<pre class="wp-block-code"><code>private async Task WriteResponse(HttpContext context, CachedPage page)
{
    foreach (var header in page.Headers)
    {
        context.Response.Headers.Add(header);
    }

    await context.Response.Body.WriteAsync(page.Content, 0, page.Content.Length);
}</code></pre>



<p>If a cached page cannot be located, additional effort must be done. In order to determine if we may cache the request, we first set any necessary client caching headers. If another method is used, we call the following middleware component and stop processing the request because we only wish to cache GET methods.</p>



<p>Capturing the request output from internal middleware components is the next step. In the part after this, we go over how this is accomplished. If we&#8217;ve set up server side caching (using the action filter mentioned above), the last step is to save the page to the cache.</p>



<h3 class="wp-block-heading">Capturing the response</h3>



<p>You must replace the response body stream&#8217;s default with a MemoryStream in order to capture the page response:</p>



<pre class="wp-block-code"><code>private async Task&lt;CachedPage> CaptureResponse(HttpContext context)
{
    var responseStream = context.Response.Body;

    using (var buffer = new MemoryStream())
    {
        try
        {
            context.Response.Body = buffer;

            await _next.Invoke(context);
        }
        finally
        {
            context.Response.Body = responseStream;
        }

        if (buffer.Length == 0) return null;

        var bytes = buffer.ToArray(); // you could gzip here

        responseStream.Write(bytes, 0, bytes.Length);

        if (context.Response.StatusCode != 200) return null;

        return BuildCachedPage(context, bytes);
    }
}</code></pre>



<p>We return null and make no attempt to cache the response if nothing has been written to it or if the status code is not 200. If not, a CachedPage instance is returned:</p>



<pre class="wp-block-code"><code>internal class CachedPage
{
    public byte&#91;] Content { get; private set; }
    public List&lt;KeyValuePair&lt;string, StringValues>> Headers { get; private set; }

    public CachedPage(byte&#91;] content)
    {
        Content = content;
        Headers = new List&lt;KeyValuePair&lt;string, StringValues>>();
    }
}</code></pre>



<p>The content of the cached page is combined with a subset of the response headers, some of which should be removed (for example, the date header).</p>



<h3 class="wp-block-heading">Controlling client caching</h3>



<p>We choose the straightforward method when it comes to providing caching headers to the browser:</p>



<pre class="wp-block-code"><code>public void ApplyClientHeaders(HttpContext context)
{
    context.Response.OnStarting(() =>
    {
        var clientCacheDuration = GetCacheDuration(context, Constants.ClientDuration);

        if (clientCacheDuration.HasValue &amp;&amp; context.Response.StatusCode == 200)
        {
            if (clientCacheDuration == TimeSpan.Zero)
            {
                context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue
                {
                    NoCache = true,
                    NoStore = true,
                    MustRevalidate = true
                };
                context.Response.Headers&#91;"Expires"] = "0";
            }
            else
            {
                context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue
                {
                    Public = true,
                    MaxAge = clientCacheDuration
                };
            }
        }

        return Task.CompletedTask;
    });            
}</code></pre>



<p>Keep in mind that our action filter determines the ClientDuration value. There are three possibilities:</p>



<ul><li>Unset &#8211; do not send headers</li><li>Zero &#8211; set various headers instructing downstream clients not to cache the response</li><li>Other &#8211; set the cache headers to the provided value</li></ul>



<h3 class="wp-block-heading">The cache</h3>



<p>We haven&#8217;t yet talked about the actual cache, which is one thing. The _cache references in the code above really correspond to a wrapper class that contains the IMemoryCache implementation that is built-in.</p>



<pre class="wp-block-code"><code>public class CacheClient : ICacheClient
{
    private readonly IMemoryCache _cache;
    
    public CacheClient(IMemoryCache cache)
    {
        _cache = cache ?? throw new ArgumentNullException(nameof(cache));
    }

    internal bool TryGet&lt;T>(string key, out T entry)
    {
        return _cache.TryGetValue(Constants.CacheKeyPrefix + key, out entry);
    }

    internal void Set(string key, object entry, TimeSpan expiry, params string&#91;] tags)
    {
        var options = new MemoryCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = expiry
        };

        var allTokenSource = _cache.GetOrCreate(Constants.CacheTagPrefix + Constants.AllTag, 
            allTagEntry => new CancellationTokenSource());

        options.AddExpirationToken(new CancellationChangeToken(allTokenSource.Token));

        foreach (var tag in tags)
        {
            var tokenSource = _cache.GetOrCreate(Constants.CacheTagPrefix + tag, tagEntry =>
            {
                tagEntry.AddExpirationToken(new CancellationChangeToken(allTokenSource.Token));

                return new CancellationTokenSource();
            });

            options.AddExpirationToken(new CancellationChangeToken(tokenSource.Token));
        }

        _cache.Set(Constants.CacheKeyPrefix + key, entry, options);
    }</code></pre>



<p>Expiration tokens are used by the Set function to enable bulk removal of cache entries.</p>



<p>The concept is that we store a CancellationTokenSource for every entry in the cache and additional CancellationTokenSources for each tag we define. If you have never used CancellationTokenSource before, this may be a little difficult to understand. When setting the cache entry, we produce a token by using these CancellationTokenSources. In the following part, we&#8217;ll look at using the CancellationTokenSources to invalidate cache items in bulk.</p>



<h2 class="wp-block-heading">Cache invalidation AKA cache busting</h2>



<p>This unique kind of response caching was implemented primarily to meet the need for the ability to delete cache items before they naturally expire. The following methods are exposed by our CacheClient class for this:</p>



<pre class="wp-block-code"><code>public void Remove(string key)
{
    _cache.Remove(Constants.CacheKeyPrefix + key);
}

public void RemoveByTag(string tag)
{
    if (_cache.TryGetValue(Constants.CacheTagPrefix + tag, out CancellationTokenSource tokenSource))
    {
        tokenSource.Cancel();

        _cache.Remove(Constants.CacheTagPrefix + tag);
    }            
}

public void RemoveAll()
{
    RemoveByTag(Constants.AllTag);
}</code></pre>



<p>As you can see, deleting a single cache entry just requires that you know the key. You could want to allow action, controller, and route values to be given instead to make it more user-friendly.</p>



<p>The RemoveAll and RemoveByTag methods invoke the Cancel() function, which expires all tokens issued by the source, after retrieving the CancellationTokenSource from the cache. These cache entries are eliminated as a result.</p>



<h3 class="wp-block-heading">Limitations</h3>



<p>This is a very simple illustration of response caching and is devoid of many features found in native response caching middleware. The lack of the option to alter caching depending on headers, cookies, etc. is perhaps the most noticeable missing. It would not be extremely challenging to incorporate VaryBy. In reality, all we&#8217;re altering is how the cache key is generated and adding support for CacheAttribute setting.</p>



<p>Additionally, we are using IMemoryCache rather than IDistributedCache, which is more scalable. As was already said, modifying the usage is simple but will reduce functionality. Since IDistributedCache does not allow expiration tokens, the method described here cannot be used to remove pages in bulk. Naturally, nothing prevents you from coming up with a different approach, but unsophisticated implementations will almost surely have a negative impact on performance.</p>



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



<p>The creation of simple response caching middleware that enables manual invalidation of items both individually and in bulk using tags was covered in this post. To store pages (or other action results like JSON) in an in-memory cache, we combined an action filter with a middleware component. Then, we made a number of methods available on our CacheClient class to enable the deletion of cache entries.</p>



<p>The example code should not be used in place of the built-in response caching, which offers far more capability, although it might be helpful in some circumstances.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/custom-output-caching-in-asp-net-core/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>4 Simple Steps to Deploy ASP.NET Core in IIS</title>
		<link>https://topreviewhostingasp.net/4-simple-steps-to-deploy-asp-net-core-in-iis/</link>
					<comments>https://topreviewhostingasp.net/4-simple-steps-to-deploy-asp-net-core-in-iis/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 25 Jul 2023 03:34:42 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net]]></category>
		<category><![CDATA[asp net core]]></category>
		<category><![CDATA[asp net core iis]]></category>
		<category><![CDATA[asp net core tips]]></category>
		<category><![CDATA[asp net core tutorial]]></category>
		<category><![CDATA[host asp net core iis]]></category>
		<category><![CDATA[iis tips]]></category>
		<category><![CDATA[iis tutorial]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3638</guid>

					<description><![CDATA[Deploying an ASP.NET Core app to IIS isn’t complicated. However, ASP.NET Core hosting is different compared to hosting with ASP.NET, because ASP.NET Core uses different configurations. IIS, on the other hand, is a web server that utilizes the Windows OS and the ASP.NET framework. IIS&#8217;s function in this situation is to host ASP.NET Core-built apps. [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Deploying an ASP.NET Core app to IIS isn’t complicated. However, ASP.NET Core hosting is different compared to hosting with ASP.NET, because ASP.NET Core uses different configurations.</p>
<p>IIS, on the other hand, is a web server that utilizes the Windows OS and the ASP.NET framework. IIS&#8217;s function in this situation is to host ASP.NET Core-built apps.</p>
<p>In this article, we&#8217;ll look at how to integrate ASP.NET Core with IIS. Let&#8217;s examine the procedures for deploying ASP.NET Core to IIS without further ado.</p>
<h2>How to Setup an ASP.NET Core Application for IIS</h2>
<p>When starting a new ASP.NET Core project, you will immediately discover that it is a console application. The following code is also present in your project&#8217;s Program.cs file, which is similar to a console application:</p>
<pre class="wp-block-preformatted prettyprint">public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup()
            .Build();

        host.Run();
    }
}</pre>
<h3 id="h-what-is-the-webhostbuilder">What is the WebHostBuilder?</h3>
<p>A WebHost object—essentially the application and web server—is necessary for all ASP.NET Core applications. To configure and create the WebHost in this instance, a WebHostBuilder is utilized. Usually, the setup code for WebHostBuilder contains the statements UseKestrel() and UseIISIntegration().</p>
<p>Why do these?</p>
<ul>
<li><strong>UseKestrel()</strong> – Registers Kestrel as the server that will host your application by registering the IServer interface. Other solutions, such as the Windows-only WebListener, may become available in the future.</li>
<li><strong>UseIISIntegration()</strong> – Provides information to ASP.NET about how IIS will act as a reverse proxy in front of Kestrel, including the port it should listen on, forward headers, and other parameters.</li>
</ul>
<blockquote class="wp-block-quote"><p>If you are planning to deploy your application to IIS, UseIISIntegration() is required</p></blockquote>
<h3 id="h-what-is-aspnetcoremodule">What is AspNetCoreModule?</h3>
<p>You may have noticed that ASP.NET Core projects create a web.config file. This is only used when deploying your application to IIS and registers the <strong>AspNetCoreModule</strong> as an HTTP handler.</p>
<h3 id="h-default-web-config-for-asp-net-core">Default web.config for ASP.NET Core:</h3>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;configuration&gt;
    &lt;system.webServer&gt;
        &lt;handlers&gt;
            &lt;add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/&gt;
        &lt;/handlers&gt;
        &lt;aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/&gt;
     &lt;/system.webServer&gt;
&lt;/configuration&gt;</pre>
<p>All incoming traffic to IIS is handled by AspNetCoreModule, which then serves as a reverse proxy that knows how to send traffic to your ASP.NET Core application. Its source code is accessible on <a href="https://github.com/aspnet/AspNetCoreModule" target="_blank" rel="noopener">GitHub</a>. Additionally, AspNetCoreModule is in charge of launching your process and making sure that your web application is up and running.</p>
<h3 id="h-install-net-core-windows-server-hosting-bundle">Install .NET Core Windows Server Hosting Bundle</h3>
<p>Installing the.NET Core hosting bundle for IIS, which includes the ASP.NET Core module for IIS and the.NET Core runtime, is necessary before you publish your application.</p>
<p>To make sure all the modifications are taken up by IIS after installation, you might need to do a &#8220;net stop was /y&#8221; and &#8220;net start w3svc&#8221; command.</p>
<p>Download: <a href="https://www.microsoft.com/net/download/all" target="_blank" rel="noopener">Windows Server Hosting for.NET Core</a> &#8211; Select &#8220;Windows Server Hosting&#8221; without a doubt.</p>
<h2 id="h-steps-to-deploy-asp-net-core-to-iis">4 Steps to Deploy ASP.NET Core to IIS</h2>
<p>Before you deploy, you need to make sure that WebHostBuilder is configured properly for Kestrel and IIS. Your web.config file should also exist and look similar to our example above.</p>
<h3 id="h-step-1-publish-to-a-file-folder">1. Publish to a File Folder</h3>
<p><img loading="lazy" decoding="async" class="size-full wp-image-3639 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/07/publish-target.png" alt="" width="1024" height="672" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/07/publish-target.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/07/publish-target-300x197.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/07/publish-target-768x504.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/07/publish-target-50x33.png 50w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>
<h3 id="h-step-2-copy-files-to-preferred-iis-location">2. Copy Files to Preferred IIS Location</h3>
<p>Copy your publish output now to the location where you want the files to reside. You might want to zip up the files and transfer them to the server if you are deploying to a distant host. You can replicate them locally if you are deploying to a local development box.</p>
<p>I&#8217;m moving the files to C:\inetpub\wwwroot\AspNetCore46 for our example.</p>
<p>There is no bin folder with ASP.NET Core, and it might copy over a huge number of various.NET DLLs, as you will notice. If you are aiming for the entire.NET Framework, your application might also be an EXE file. Over 100 DLLs were produced by this tiny sample project.</p>
<p><img loading="lazy" decoding="async" class="wp-image-3640 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-file.png" alt="" width="788" height="485" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-file.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-file-300x185.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-file-768x473.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-file-50x31.png 50w" sizes="(max-width: 788px) 100vw, 788px" /></p>
<h3 id="h-step-3-create-application-in-iis">3. Create Application in IIS</h3>
<p>Creating your application in IIS is listed as a single &#8220;Step,&#8221; but you will actually do several different tasks. First, build a new IIS Application Pool with &#8220;<strong>No Managed Code</strong>&#8221; for the.NET CLR. IIS isn&#8217;t actually running any.NET code; it just functions as a reverse proxy.</p>
<p>The second option is to create your application under an already-existing or brand-new IIS Site. In any case, you must select your new IIS Application Pool and direct it to the location where you copied the ASP.NET publish output files.</p>
<p><img loading="lazy" decoding="async" class=" wp-image-3641 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-iis.png" alt="" width="768" height="571" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-iis.png 1036w, https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-iis-300x223.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-iis-1024x761.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-iis-768x571.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/07/aspnetcore-iis-50x37.png 50w" sizes="(max-width: 768px) 100vw, 768px" /></p>
<h3>4. Load Your Application</h3>
<p>At this point, your application should load just fine. If it does not, check the output logging from it. Within your web.config file you define how IIS starts up your ASP.NET Core process. Enable output logging by setting <strong>stdoutLogEnabled</strong>=true. You may also want to change the log output location as configured in <strong>stdoutLogFile</strong>. Check out the example web.config before to see where they are set.</p>
<h2>Where Can I Find Reliable and Cheap ASP.NET Core Hosting?</h2>
<p>The following is my recommendation for ASP.NET Core web hosting:</p>
<p><strong>1. <a href="https://www.asphostportal.com" target="_blank" rel="noopener">ASPHostPortal</a>: </strong>this is my first recommendation to host ASP.NET core website. It is a very reliable platform with a fast server and great customer support. It is a reliable ASP.NET Core hosting service for websites that do not require any special functionality or features.</p>
<p><strong>2. <a href="https://www.hostforlife.eu" target="_blank" rel="noopener">HostForLIFE.eu</a></strong>: HostForLIFE is one of the best ASP.NET core web hosting in Europe. They support all ASP.NET version, start from Classic ASP, ASP.NET 1/2.0/3.5/4.0/4.5 and latest ASP.NET Core version. It is easy to deploy ASP.NET core website to their server.</p>
<p><strong>3. <a href="https://www.UKWindowsHostASP.NET" target="_blank" rel="noopener">UKWindowsHostASP.NET</a>: </strong>One of the most reputable and affordable ASP.Net Core hosting companies in the world is UKWindowsHostASP.NET. It provides cloud hosting, VPS hosting, dedicated servers, and a wide range of adaptable alternatives for your company needs.</p>
<p><strong>4. <a href="https://www.windowsaspnethosting.in" target="_blank" rel="noopener">WindowsASPNETHosting.in</a></strong>: The finest host for developers and new businesses is WindowsASPNETHosting.in. For your web application or other project, WindowsASPNETHosting.in provides an ASP.NET, ASP,.Net Core, and SQL platform that you can easily extend with additional functionality.</p>
<p><strong>5. <a href="https://www.discountservice.biz" target="_blank" rel="noopener">DiscountService.biz</a></strong>: DiscountService committed to provide best, cheap, and reliable ASP.NET Core hosting services. They can offer you the quickest and safest platform to host your ASP.NET websites.</p>
<h2>Conclusion</h2>
<p>I hope above article can help you to publish your ASP.NET Core website easily to IIS. Instead of that, I also give some recommendation for ASP.NET core hosting in case you want to publish your ASP.NET core website online. Hope this helps and stay tune with other interesting tutorial and tips. Thank you for reading.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/4-simple-steps-to-deploy-asp-net-core-in-iis/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Create SOAP Web Service ASP.NET Core</title>
		<link>https://topreviewhostingasp.net/how-to-create-soap-web-service-asp-net-core/</link>
					<comments>https://topreviewhostingasp.net/how-to-create-soap-web-service-asp-net-core/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Tue, 27 Jun 2023 08:26:06 +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[create soap service asp]]></category>
		<category><![CDATA[soap service asp net]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3594</guid>

					<description><![CDATA[We will learn how to construct and use Soap Web Services in Dotnet Core in this tutorial. In software development, Web services implementation comes in two flavors: SOAP and REST API. Web Services are programs that enable internet-based device-to-device communication. Please make sure you have installed The latest version of Visual Studio SQL Server Steps to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>We will learn how to construct and use Soap Web Services in Dotnet Core in this tutorial. In software development, Web services implementation comes in two flavors: SOAP and REST API. Web Services are programs that enable internet-based device-to-device communication.</p>
<p>Please make sure you have installed</p>
<ul>
<li>The latest version of <a href="https://visualstudio.microsoft.com/downloads/">Visual Studio</a></li>
<li>SQL Server</li>
</ul>
<h2>Steps to Create SOAP Demo Application</h2>
<h3 class="wp-block-heading">1. Create a SOAP Webservice in Visual Studio 2019</h3>
<p>1. Create an empty ASP.NET Web Application(.NET Framework) .We will use this project as the soap service demo .To do that just follow the steps below.</p>
<ul>
<li>Select <strong>File</strong> &gt; <strong>New</strong> &gt; <strong>Project</strong>.</li>
<li>Select <strong>ASP.NET Web</strong> <strong>Application</strong>(.NET Framework). Name the project <strong>SoapDemo </strong>to have the same namespace as my project. Click <strong>Create</strong>.</li>
<li>Select an Empty <strong>ASP.NET Web Application</strong>(.NET Framework).</li>
<li>Lastly, Click on <strong>Create</strong>.</li>
</ul>
<p><img loading="lazy" decoding="async" class="size-full wp-image-3595 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio.jpg" alt="" width="1016" height="684" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio.jpg 1016w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-300x202.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-768x517.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-50x34.jpg 50w" sizes="(max-width: 1016px) 100vw, 1016px" /></p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-3596 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-2.jpg" alt="" width="1016" height="684" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-2.jpg 1016w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-2-300x202.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-2-768x517.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-2-50x34.jpg 50w" sizes="(max-width: 1016px) 100vw, 1016px" /></p>
<p>This is what your solution with an empty template would look like after creating a new project. See the picture below.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-3597 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-3.jpg" alt="" width="932" height="637" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-3.jpg 932w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-3-300x205.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-3-768x525.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/visual-studio-3-50x34.jpg 50w" sizes="(max-width: 932px) 100vw, 932px" /></p>
<p>2. Add a new item by right-clicking your project solution and select Add » NewItem. Then search for Web Service ASMX.</p>
<div id="ads-slot1"><img loading="lazy" decoding="async" class="size-full wp-image-3598 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/asmx.jpg" alt="" width="939" height="654" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/asmx.jpg 939w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/asmx-300x209.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/asmx-768x535.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/asmx-50x35.jpg 50w" sizes="(max-width: 939px) 100vw, 939px" /></div>
<div>
<p>3. Click the &#8220;Add&#8221; button to create a template for an ASMX web service that includes the standard web method HelloWorld. View the image that is included below.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-3599 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/soap-demo.jpg" alt="" width="931" height="636" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/soap-demo.jpg 931w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/soap-demo-300x205.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/soap-demo-768x525.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/soap-demo-50x34.jpg 50w" sizes="(max-width: 931px) 100vw, 931px" /></p>
<p>We are now prepared to add our sample method, which in my instance will be a login Web Method, as we now have our Soap Web service. This method will check my website&#8217;s login credentials and provide an error if they are invalid or don&#8217;t exist in my user database.</p>
<h3>2. Create a Sample WEB Method Login</h3>
<p>To use later in our ASP.Net Core Web Application, let&#8217;s construct a sample Login function. To add the sample code, adhere to the steps below.</p>
<p>1. Create a <strong>ResponseModel</strong>. This will serve as our response model template.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-3600 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/Model.jpg" alt="" width="935" height="638" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/Model.jpg 935w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/Model-300x205.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/Model-768x524.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/Model-50x34.jpg 50w" sizes="(max-width: 935px) 100vw, 935px" /></p>
<p>My ResponseModel class has had the following code added. Copy the code snippet below into a new class file with the name ResponseModel.</p>
<h4 class="wp-block-heading">ResponseModel :</h4>
</div>


<pre class="wp-block-code"><code>using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Web;
 namespace SoapDemo.Models
 {
         public class ResponseModel
         {
             public T Data { get; set; }
             public int resultCode { get; set; }
             public string message { get; set; }
         }
 }</code></pre>



<p>2. Next, open the SoapDemo.asmx file and insert the example login validation method that is provided below. With this approach, the User table will be searched for the email and password. This method will return the response code, which is described as follows, once the user has been located in the database.</p>



<figure class="wp-block-table"><table><thead><tr><th>Response Code</th><th>Description</th></tr></thead><tbody><tr><td>200</td><td>Email and password found</td></tr><tr><td>500</td><td>Email and password does not exist</td></tr></tbody></table></figure>



<p>You can choose any response you want to use, but for this example I&#8217;m going to use the response code from above. I utilized the database from my earlier tutorial for this example. To construct your own ASP.NET Core login application, click the link below.</p>



<p>You can copy the code snippet below on your SoapDemo.asmx file.</p>



<pre class="wp-block-code"><code>     &#91;WebMethod]
         public  ResponseModel&lt;string&gt; login(string email, string password)
         {
             ResponseModel&lt;string&gt; response = new ResponseModel&lt;string&gt;();
  
             if (email != null)
             {
                 using (SqlConnection conn = new SqlConnection(@"Server=CODERSIGN\SQLEXPRESS01;Database=IdentityDemo;User Id=freecode;Password=freespot;"))
                 {
                     SqlCommand cmd = new SqlCommand("sp_loginUser",conn);
                     cmd.CommandType = CommandType.StoredProcedure;
                     cmd.Parameters.Add("@email", SqlDbType.NVarChar, 50).Value = email;
                     cmd.Parameters.Add("@password", SqlDbType.NVarChar, 50).Value = password;
                     
  
                     SqlDataAdapter da = new SqlDataAdapter(cmd);
                     DataTable dt = new DataTable();
                     da.Fill(dt);
  
  
                     if (dt.Rows.Count &gt; 0)
                     {
                         response.Data = JsonConvert.SerializeObject(dt);
                         response.resultCode = 200;
                     }
                     else
                     {
                         response.message = "User Not Found!";
                         response.resultCode = 500;
                     }
  
  
                 }
             }
             return response;
         } </code></pre>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="931" height="636" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/soap-demo-1.jpg" alt="" class="wp-image-3601" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/soap-demo-1.jpg 931w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/soap-demo-1-300x205.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/soap-demo-1-768x525.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/soap-demo-1-50x34.jpg 50w" sizes="(max-width: 931px) 100vw, 931px" /></figure>



<p>3. Now, run your project and make sure you see the method you just created. See the image below.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="935" height="638" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/Soap-service.jpg" alt="" class="wp-image-3602" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/Soap-service.jpg 935w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/Soap-service-300x205.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/Soap-service-768x524.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/Soap-service-50x34.jpg 50w" sizes="(max-width: 935px) 100vw, 935px" /></figure>



<figure class="wp-block-table"><table><thead><tr><th>WebMethod</th><th>Description</th></tr></thead><tbody><tr><td>HelloWorld</td><td>Default method created that will return a “Hello World” string</td></tr><tr><td>login</td><td>login validation method</td></tr></tbody></table></figure>



<p>Soap Service URL: https://localhost:44399/SoapDemo.asmx</p>



<h3 class="wp-block-heading">3. Create a Sample ASP.NET Core Web Application Project.</h3>



<p>This is a sample login application that uses cookie authentication</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="583" height="181" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/clone-login-demo.jpg" alt="" class="wp-image-3603" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/clone-login-demo.jpg 583w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/clone-login-demo-300x93.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/clone-login-demo-50x16.jpg 50w" sizes="(max-width: 583px) 100vw, 583px" /></figure></div>


<p>After that open the project using the latest Visual Studio and rebuild the solution.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="935" height="638" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/IdentityDemo.jpg" alt="" class="wp-image-3604" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/IdentityDemo.jpg 935w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/IdentityDemo-300x205.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/IdentityDemo-768x524.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/IdentityDemo-50x34.jpg 50w" sizes="(max-width: 935px) 100vw, 935px" /></figure></div>


<h3 class="wp-block-heading">4. Add a soap service reference for the ASP.NET Core application&#8217;s SoapDemo service.</h3>



<p>Now, we are ready to consume the soap service that we created above. Run your soap service and follow the steps below.</p>



<p>1. Run your soap service, this will open the browser with the soap service URL. In my case my soap URL is https://localhost:44399/SoapDemo.asmx.</p>



<p>2. Now, navigate to&nbsp;<strong>IdentityDemo&nbsp;</strong>project solution. Then right click on the&nbsp;<strong>Connected Services</strong>&nbsp;then&nbsp;<strong>Add Connected Service</strong>.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="985" height="633" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/add-services.jpg" alt="" class="wp-image-3605" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/add-services.jpg 985w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/add-services-300x193.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/add-services-768x494.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/add-services-50x32.jpg 50w" sizes="(max-width: 985px) 100vw, 985px" /></figure>



<p>3. Select&nbsp;<strong>Microsoft WCF Web Service Reference Provider</strong>&nbsp;from&nbsp;<strong>Other Services</strong>&nbsp;option. Then Input your URL and assign the service name.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="985" height="635" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/input-url.jpg" alt="" class="wp-image-3606" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/input-url.jpg 985w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/input-url-300x193.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/input-url-768x495.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/input-url-50x32.jpg 50w" sizes="(max-width: 985px) 100vw, 985px" /></figure>



<p>4. Then click Finish. This will generate references for your Soap Service.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="985" height="635" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/success-added.jpg" alt="" class="wp-image-3607" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/success-added.jpg 985w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/success-added-300x193.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/success-added-768x495.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/success-added-50x32.jpg 50w" sizes="(max-width: 985px) 100vw, 985px" /></figure>



<p>At this point, we have successfully generated the reference for our Web service project.</p>



<h3 class="wp-block-heading">5. Consume Soap Service on ASP.NET Core Application</h3>



<p>Let&#8217;s include the Service&#8217;s implementation in our project. We will add the interface and implementation to the existing IRepository and Repository classes as the ASP.NET core is an existing project.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="935" height="638" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/Irepository.jpg" alt="" class="wp-image-3608" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/Irepository.jpg 935w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/Irepository-300x205.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/Irepository-768x524.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/Irepository-50x34.jpg 50w" sizes="(max-width: 935px) 100vw, 935px" /></figure></div>


<p>This is a summary of how to obtain an instance of the soap service that we recently implemented.</p>



<p>Before you begin the following actions. The following NuGet packages need be installed.</p>



<ul><li>System.ServiceModel.Http</li><li>System.ServiceModel.Premitives</li></ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="854" height="488" src="https://topreviewhostingasp.net/wp-content/uploads/2023/06/success-added-2.jpg" alt="" class="wp-image-3609" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/06/success-added-2.jpg 854w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/success-added-2-300x171.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/success-added-2-768x439.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/06/success-added-2-50x29.jpg 50w" sizes="(max-width: 854px) 100vw, 854px" /></figure>



<p>1. From IRepository class we added a&nbsp;<strong>GetInstanceAsync&nbsp;</strong>method. This method will instatiate the soap service.</p>



<pre class="wp-block-code"><code>Task&lt;SoapDemoClient&gt; GetInstanceAsync();
</code></pre>



<p>2. Then on the implementation class which is Repository.cs. I added this code.</p>



<pre class="wp-block-preformatted">public readonly string serviceUrl = "https://localhost:44399/SoapDemo.asmx";
public readonly EndpointAddress endpointAddress;
public readonly BasicHttpBinding basicHttpBinding;</pre>



<p>Repository Contructor:</p>



<pre class="wp-block-preformatted"> public Repository(IConfiguration configuration)
         {
             _configuration = configuration;
  
             endpointAddress = new EndpointAddress(serviceUrl);
  
             basicHttpBinding = new BasicHttpBinding(endpointAddress.Uri.Scheme.ToLower() == "http" ?
                             BasicHttpSecurityMode.None : BasicHttpSecurityMode.Transport);
             basicHttpBinding.OpenTimeout = TimeSpan.MaxValue;
             basicHttpBinding.CloseTimeout = TimeSpan.MaxValue;
             basicHttpBinding.ReceiveTimeout = TimeSpan.MaxValue;
             basicHttpBinding.SendTimeout = TimeSpan.MaxValue;
         } </pre>



<p><strong>GetInstanceAsync&nbsp;</strong>implementation:</p>



<pre class="wp-block-code"><code> public async Task&lt;SoapDemoSoapClient&gt; GetInstanceAsync()
    {
         return await Task.Run(() =&gt; new SoapDemoSoapClient(basicHttpBinding, endpointAddress));
    } </code></pre>



<p>3. To use this instance you can call it using the code snippet below.</p>



<pre class="wp-block-code"><code> var client = await GetInstanceAsync();
 var result = await client.loginAsync(loginView.Email, loginView.Password); </code></pre>



<p><strong>LoginAsync&nbsp;</strong>is the Login method from the&nbsp;<strong>SoapDemo&nbsp;</strong>service that we added on the Connected Service.</p>



<p>This is now the new code in my&nbsp;<strong>LoginAsync&nbsp;</strong>method.</p>



<pre class="wp-block-code"><code>  public async Task&lt;Response&lt;IdentityModel&gt;&gt; LoginAsync(LoginViewModel loginView)
         {
             Response&lt;IdentityModel&gt; response = new Response&lt;IdentityModel&gt;();
             IdentityModel userModel = new IdentityModel();
  
             try
             {
                 var client = await GetInstanceAsync();
                 var result = await client.loginAsync(loginView.Email, loginView.Password);
  
                 DataTable dt = new DataTable();
                 dt = JsonConvert.DeserializeObject&lt;DataTable&gt;(result.Body.loginResult.Data);
  
                 IdentityModel user = new IdentityModel();
                 user.ID = int.Parse(dt.Rows&#91;0]&#91;"ID"].ToString());
                 user.Email = dt.Rows&#91;0]&#91;"Email"].ToString();
                 user.Role = dt.Rows&#91;0]&#91;"Role"].ToString();
                 user.Reg_Date = dt.Rows&#91;0]&#91;"Reg_Date"].ToString();
  
                 response.Data = user;
                 response.message = (result.Body.loginResult.resultCode == 500) ? "Login failed.Please check Username and / or password" : "data found";
                 response.code = result.Body.loginResult.resultCode;
             }
             catch (Exception ex)
             {
                 response.code = 500;
                 response.message = ex.Message;
             } 
  
             return response;
         } </code></pre>



<h3 class="wp-block-heading">3. Run and Test</h3>



<p>Run the IdentityDemo and SoapDemo projects simultaneously. To create a user for you to log in, utilize the register option. Check out my earlier tutorial to get acquainted with the source code utilized here.</p>



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



<p>This lesson taught us how to use Dotnet Core to construct and use Soap Web Services. The ASP.NET core project differs from the ASP.NET MVC project in how a soap service is implemented. We can also see that using Visual Studio 2019 to create a Soap Webservice does not come with a project template for an ASMX project; instead, a new component had to be added manually. I sincerely hope that this tutorial will be useful to you and be incorporated into your future projects.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-create-soap-web-service-asp-net-core/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
