<?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 tutorial &#8211; ASP.NET Hosting Reviews and Guides</title>
	<atom:link href="https://topreviewhostingasp.net/tag/asp-net-core-tutorial-2/feed/" rel="self" type="application/rss+xml" />
	<link>https://topreviewhostingasp.net</link>
	<description>ASP.NET Hosting &#124; Reviews &#124; Tips &#38; Tutorial</description>
	<lastBuildDate>Thu, 30 May 2024 03:43:56 +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 tutorial &#8211; ASP.NET Hosting Reviews and Guides</title>
	<link>https://topreviewhostingasp.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<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 fetchpriority="high" 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 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>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>
		<item>
		<title>Easy Way to Restart Your ASP.NET Core Apps Progamatically</title>
		<link>https://topreviewhostingasp.net/easy-way-to-restart-your-asp-net-core-apps-progamatically/</link>
					<comments>https://topreviewhostingasp.net/easy-way-to-restart-your-asp-net-core-apps-progamatically/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Mon, 13 Mar 2023 07:09:53 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net core code]]></category>
		<category><![CDATA[asp net core programming]]></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[shutdown asp net core]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3473</guid>

					<description><![CDATA[We developers won&#8217;t have access to servers all the time, and without management capabilities, it will be difficut to restart a web application. However, in ASP.NET Core, there is a way for us to programmatically restart our application without requring management capabilities from server admins. IApplicationLifetime There is a IApplicationLifetime interface in ASP.NET Core which can handle [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>We developers won&#8217;t have access to servers all the time, and without management capabilities, it will be difficut to restart a web application. However, in ASP.NET Core, there is a way for us to programmatically restart our application without requring management capabilities from server admins.</p>



<h2 class="wp-block-heading">IApplicationLifetime</h2>



<p>There is a <strong>IApplicationLifetime</strong> interface in ASP.NET Core which can handle events like start up and shut down. It provides 3 Cancellation Token, allowing us to use <strong>Action</strong> delegate to handle the ASP.NET Core website&#8217;s start and stop events:</p>



<pre class="wp-block-code"><code>public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifetime)
{
    appLifetime.ApplicationStarted.Register(() =&gt;
    {
        _logger.LogInformation("Moonglade started.");
    });

    appLifetime.ApplicationStopping.Register(() =&gt;
    {
        _logger.LogInformation("Moonglade is stopping...");
    });

    appLifetime.ApplicationStopped.Register(() =&gt;
    {
        _logger.LogInformation("Moonglade stopped.");
    });

    // ... Other code
}</code></pre>



<p>Per Microsoft document:</p>



<figure class="wp-block-table">
<table>
<thead>
<tr>
<th style="text-align: left;">Cancellation Token</th>
<th style="text-align: left;">Triggered when…</th>
</tr>
</thead>
<tbody>
<tr>
<td>ApplicationStarted</td>
<td>The host has fully started.</td>
</tr>
<tr>
<td>ApplicationStopped</td>
<td>The host is completing a graceful shutdown. All requests should be processed. Shutdown blocks until this event completes.</td>
</tr>
<tr>
<td style="text-align: left;">ApplicationStopping</td>
<td style="text-align: left;">The host is performing a graceful shutdown. Requests may still be processing. Shutdown blocks until this event completes.</td>
</tr>
</tbody>
</table>
</figure>



<h2 class="wp-block-heading">Killing the Website</h2>



<p>Besides these 3 events, <strong>IApplicationLifetime</strong> interface got another method named <strong>StopApplication() </strong>which can stop the current ASP.NET Core application. When the website is being stopped, <strong>ApplicationStopping</strong> and <strong>ApplicationStopped</strong> events will be fired in sequence.</p>



<p>We can restart our website based on this method.</p>



<h2 class="wp-block-heading">Implement Restart Functionality</h2>



<p>The most easy way for us to restart a website is to access a certain URL. Take ASP.NET Core MVC application for example:</p>



<p>Inject an <strong>IApplicationLifetime </strong>class into the Controller:</p>



<pre class="wp-block-code"><code>public class AdminController : Controller
{
    IApplicationLifetime applicationLifetime;

    public AdminController(IApplicationLifetime appLifetime)
    {
        applicationLifetime = appLifetime;
    }

    // ...
}</code></pre>



<p>And use an Action to invoke the <strong>StopApplication() </strong>method:</p>



<pre class="wp-block-code"><code>[HttpGet("blow-me-up")]
public IActionResult BlowMeUp()
{
    applicationLifetime.StopApplication();
    return new EmptyResult();
}</code></pre>



<p>Now, when I access the URL &#8220;<strong>blow-me-up</strong>&#8220;, the website will shut down itself:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="887" height="399" class="wp-image-3474 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2023/03/cmd.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/03/cmd.png 887w, https://topreviewhostingasp.net/wp-content/uploads/2023/03/cmd-300x135.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/03/cmd-768x345.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/03/cmd-50x22.png 50w" sizes="(max-width: 887px) 100vw, 887px" /></figure>



<p>To restart the application is easy. Under IIS, the next request goes to the website will start it up again. Which basically means, reopen the website in the browser again and it will start up.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/easy-way-to-restart-your-asp-net-core-apps-progamatically/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Application Insights .NET Core Application</title>
		<link>https://topreviewhostingasp.net/application-insights-net-core-application/</link>
					<comments>https://topreviewhostingasp.net/application-insights-net-core-application/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Mon, 06 Mar 2023 04:18:21 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[.net core application]]></category>
		<category><![CDATA[asp net core]]></category>
		<category><![CDATA[asp net core tips]]></category>
		<category><![CDATA[asp net core tutorial]]></category>
		<category><![CDATA[c# application logs]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3467</guid>

					<description><![CDATA[So why would you ever log to Application Insights AND File log at the same time? Well, if you are hosting your own applications on your own machine, it can be great to have a file version of what’s happened. The file will be updated immediately, whereas Application Insights are sometimes up to 5 minutes [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>So why would you ever log to Application Insights AND File log at the same time? Well, if you are hosting your own applications on your own machine, it can be great to have a file version of what’s happened. The file will be updated immediately, whereas Application Insights are sometimes up to 5 minutes behind.<br />Also, it gives you the opportunity to log at different levels. Application Insights is not cheap, so having Application Insights log only warnings and errors, but the file logging debug can be a money saver.<br />And, when developing, the file log is far superior to Application Insights.</p>



<p><strong>STEP 1: THE NUGET PACKAGES</strong></p>



<p>You need the following packages:</p>



<ul>
<li><a href="https://www.nuget.org/packages/Microsoft.Extensions.Logging/" target="_blank" rel="noreferrer noopener">Microsoft.Extensions.Logging</a></li>
<li><a href="https://www.nuget.org/packages/Serilog.Extensions.Logging.File/" target="_blank" rel="noreferrer noopener">Serilog.Extensions.Logging.File</a></li>
</ul>



<p><strong>STEP 2: THE CONFIGURATION</strong></p>



<p>This will configure the logging:</p>



<pre class="wp-block-code"><code>"ApplicationInsights": {
    "InstrumentationKey": "[The instrumentation key]"
  },
"Logging": {
    "PathFormat": "[The path and file format used in file logging, e.g.: c:\\log-{Date}.txt]",
    "LogLevel": {
      "Default": "Information"
    },
    "ApplicationInsightsLoggerProvider": {
      "LogLevel": {
        "Default": "Warning"
      }
    }
  }</code></pre>



<p>The “Logging” section configures the different log levels for file and Application Insights.</p>



<p><strong>STEP 3: THE EXTENSION METHOD</strong></p>



<p>This method allows you to add logging easily:</p>



<pre class="wp-block-code"><code>using Microsoft.ApplicationInsights.AspNetCore.Extensions;
 
namespace MyCode
{
    public static class WebApplicationBuilderExtensions
    {
        public static void AddLogging(this WebApplicationBuilder builder)
        {
            // Add file logging
            builder.Host.ConfigureLogging(logging =&gt;
                {
                    logging.AddFile(builder.Configuration.GetSection("Logging"));
                }
            );
            // Add Application Insights Logging
            var options = new ApplicationInsightsServiceOptions();
            options.InstrumentationKey = builder.Configuration["ApplicationInsights:InstrumentationKey"];
            builder.Services.AddApplicationInsightsTelemetry(options);
        }
    }
}</code></pre>



<p><strong>STEP 4: CALL THE METHOD WHEN BUILDING YOUR APPLICATION</strong></p>



<p>This is an example where I configure my logging:</p>



<pre class="wp-block-code"><code>using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
 
var webApplicationOptions = new WebApplicationOptions();
var builder = WebApplication.CreateBuilder(webApplicationOptions);
builder.AddLogging();
...
...
...
builder.Build();</code></pre>



<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/application-insights-net-core-application/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Force HTTPS in ASP.NET Core</title>
		<link>https://topreviewhostingasp.net/how-to-force-https-in-asp-net-core/</link>
					<comments>https://topreviewhostingasp.net/how-to-force-https-in-asp-net-core/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Thu, 23 Feb 2023 04:40:52 +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[force https asp net core]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[https middleware]]></category>
		<category><![CDATA[https redirection]]></category>
		<category><![CDATA[url redirection]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3457</guid>

					<description><![CDATA[HTTPS is mandatory to grant security to your web application, regardless of the programming framework you are using. But what happens if a client calls your web app with HTTP instead of HTTPS? How can you force it to use HTTPS? Let&#8217;s delve into the options provided by ASP.NET Core. Use HTTPS Redirection I guess [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>HTTPS is mandatory to grant security to your web application, regardless of the programming framework you are using. But what happens if a client calls your web app with HTTP instead of HTTPS? How can you force it to use HTTPS? Let&#8217;s delve into the options provided by ASP.NET Core.</p>



<h2 class="wp-block-heading" id="Use-HTTPS-Redirection">Use HTTPS Redirection</h2>



<p>I guess that the first idea that comes to your mind is to redirect HTTP requests: if a client calls your application using HTTP, your application redirects it to the same URL starting with HTTPS. <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections" target="_blank" rel="noreferrer noopener">URL redirection</a> is a well-known approach. The web application creates an HTTP response with a status code starting with <code>3</code> and a <code>Location</code> header like in the following example:</p>



<pre class="wp-block-code"><code>HTTP/1.1 301 Moved Permanently
Location: https://www.topreviewhostingasp.net/</code></pre>



<p>While this approach doesn&#8217;t resolve all the security risks, as you will learn along the way, it&#8217;s a good starting point.</p>



<p>Fortunately, in ASP.NET Core, you don&#8217;t need to go to the HTTP level to redirect your client&#8217;s requests. You have a few options to choose from. Let&#8217;s analyze each of them.</p>



<h3 class="wp-block-heading" id="The--RequireHttps--attribute">The <code>RequireHttps</code> attribute</h3>



<p>The first approach we&#8217;ll explore is based on the <code>RequireHttps</code> attribute. You can use it in your Razor Pages applications to force a page to require HTTPS, as shown in the following code snippet:</p>



<pre class="wp-block-code"><code>using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorApp.Pages;

[RequireHttps]
public class PrivacyModel : PageModel
{
  //...existing code...
}</code></pre>



<p>If this page is called through HTTP, an HTTPS redirection response will be automatically created for you. For Razor Pages, you can apply the <code>RequireHttps</code> attribute only to classes inheriting from <code>PageModel</code>. You cannot apply the attribute to the class methods as well.</p>



<p>In ASP.NET Core MVC applications, you can apply the <code>RequireHttps</code> attribute to classes inherited from <code>Controller</code>, as in the following example:</p>



<pre class="wp-block-code"><code>using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using MvcApp.Models;

namespace MvcApp.Controllers;

[RequireHttps]
public class HomeController : Controller
{
  // ...existing code...
}</code></pre>



<p>When the attribute is attached to the controller, the HTTP redirection is applied to any view returned by it. However, in the ASP.NET Core MVC case, you can apply the <code>RequireHttps</code> attribute to specific views. For example, the following code shows how to require HTTPS redirection only for the <em>Privacy</em> view:</p>



<pre class="wp-block-code"><code>using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using MvcApp.Models;

namespace MvcApp.Controllers;

public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    [RequireHttps]
    public IActionResult Privacy()
    {
        return View();
    }
}</code></pre>



<p>The redirection approach based on the <code>RequireHttps</code> attribute is pretty simple. You may also think that the opportunity to apply it selectively to specific pages or views is great because you can limit HTTPS to just pages with confidential content.</p>



<p>Actually, <strong>mixing HTTP and HTTPS pages is a really bad idea!</strong> Your web application is not secure because it is exposed to HTTPS downgrade attacks. To mitigate this risk, make all your web application&#8217;s pages accessible only with the HTTPS protocol.</p>



<p>You may think of applying the <code>RequireHttps</code> attribute to all the pages to reduce the risk, but there are better approaches, as you will see in the next section.</p>



<h3 class="wp-block-heading" id="The-HTTPS-redirection-middleware">The HTTPS redirection middleware</h3>



<p>When you create a web application using one of the standard ASP.NET project templates, the <code>Program.cs</code> file contains the method invocation highlighted in the following code snippet:</p>



<pre class="wp-block-code"><code>// Program.cs

var builder = WebApplication.CreateBuilder(args);

// ...existing code...

var app = builder.Build();

// ...existing code...

app.UseHttpsRedirection();  //? HTTPS redirection
app.UseStaticFiles();

app.UseRouting();

// ...existing code...</code></pre>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://www.asphostportal.com" target="_blank" rel="noreferrer noopener"><img loading="lazy" decoding="async" width="300" height="271" class="wp-image-2584 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2018/11/ahp-banner-aspnet-01.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2018/11/ahp-banner-aspnet-01.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2018/11/ahp-banner-aspnet-01-50x45.png 50w" sizes="(max-width: 300px) 100vw, 300px" /></a></figure></div>


<p>The <code>UseHttpsRedirection()</code> method invocation enables the HTTPS redirection middleware. This means that each request to your application will be inspected and possibly redirected by the middleware. You don&#8217;t need to look for pages missing the <code>RequireHttps</code> attribute. All the pages of your application will require HTTPS. If a client requests a page with HTTP, it will be automatically redirected to the corresponding HTTPS-based URL.</p>



<h3 class="wp-block-heading" id="Enable-the-HSTS-middleware">Enable the HSTS middleware</h3>



<p>The approach based on <code>UseHttpsRedirection()</code> looks awesome! With just one statement in your <code>Program.cs</code> file, your entire web application is forced to be called with the HTTPS protocol.</p>



<p>Unfortunately, while this approach is better than having mixed pages, there are still some potential security issues with your application. Forcing a client to switch from HTTP to HTTPS on each request might not be enough to prevent HTTPS downgrade attacks. The attacker could intercept the client&#8217;s HTTP request before it switches to the corresponding HTTPS request.</p>



<p>You need a way to tell the browser to mandatorily use HTTPS to request <strong>any</strong> resource of your web application. This way exists: the HTTP <code>Strict-Transport-Security</code> header (HSTS). Using HSTS, the browser will call your application using HTTP only the very first time. The subsequent requests against the same domain will be made using the HTTPS protocol, even in the presence of a URL using the HTTP scheme.</p>



<p>To enable HSTS in your ASP.NET Core application, you just need to invoke the <code>UseHsts()</code> method in your <code>Program.cs</code> file as shown below:</p>



<pre class="wp-block-code"><code>// Program.cs

var builder = WebApplication.CreateBuilder(args);

// ...existing code...

var app = builder.Build();

// ...existing code...

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();    //? Enable HSTS middleware
}

// ...existing code...</code></pre>



<p>By invoking the <code>UseHsts()</code> method, you enable the HSTS middleware. You have this code already in your application when you build it by starting from a standard ASP.NET Core template.</p>



<h3 class="wp-block-heading" id="Using-HSTS-in-the-development-environment">Using HSTS in the development environment</h3>



<p>From the code above, you may notice that the HSTS support is enabled only if your application is not running in your development environment. There is a practical reason behind this choice.</p>



<p>Chances are that you use <em>localhost</em> as your development environment domain. If you use HSTS in your development environment, any request made by your browser to <em>localhost</em> will use HTTPS. Actually, using HTTPS in your development environment is a good practice. But suppose your ASP.NET Core application enables HSTS. In that case, it causes your browser to make HTTPS requests to <strong>any application</strong> hosted on <em>localhost</em>, not just your ASP.NET Core application and not just ASP.NET Core applications in general. This may lead to headaches in case you have, say, an Angular application that doesn&#8217;t use HTTPS and stops working overnight.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>HSTS settings include an expiration time, which by default is 30 days for ASP.NET Core applications. To change this and other settings, check out the <a href="https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl#http-strict-transport-security-protocol-hsts" target="_blank" rel="noreferrer noopener">official documentation</a>.</p>
</blockquote>



<h2 class="wp-block-heading" id="HTTPS-Redirection-and-APIs">HTTPS Redirection and APIs</h2>



<p>At this point, we can feel happy with the HTTPS security of our ASP.NET Core application, right? Well, not really. Actually, it depends on the type of web application.</p>



<p>The HTTPS redirection approach relies on sending back to the client a <code>301</code> or another <code>30*</code> HTTP status code, regardless you are using the <code>RequireHttps</code> attribute or the HTTPS redirection middleware. The HSTS approach relies on sending the <code>Strict-Transport-Security</code> header.</p>



<p>Both approaches are well-understood by standard browsers. So, application types whose clients are browsers, such as ASP.NET Core MVC applications, Razor Pages applications, and Blazor Server applications, can rely on these approaches.</p>



<p>However, those approaches are usually ignored by non-browser clients, such as API clients. It&#8217;s extremely rare for a mobile app or a SPA to take care of <code>301</code> status codes or HSTS headers. In this case, you have two alternative ways to deal with clients that make HTTP requests:</p>



<ul>
<li>Ignore HTTP requests.</li>
<li>Respond with a <code>400 Bad Request</code> status code.</li>
</ul>



<h3 class="wp-block-heading" id="Ignore-HTTP-requests">Ignore HTTP requests</h3>



<p>The first option can be done in different ways. One of the easiest ways is to use the <code>--urls</code> flag of the <code>dotnet run</code> command, as shown below:</p>



<pre class="wp-block-code"><code>dotnet run --urls "https://localhost:7123"</code></pre>



<p>This approach allows you to override the URL settings configured in the <code>Properties/launchSettings.json</code> file of your ASP.NET Core project.</p>



<p>A more production-oriented approach to override those settings uses the <code>ASPNETCORE_URLS</code> environment variable. The following shows how to set this variable in PowerShell:</p>



<pre class="wp-block-code"><code>$Env: ASPNETCORE_URLS = "https://localhost:7123"</code></pre>



<p>This is an example in a bash shell:</p>



<pre class="wp-block-code"><code>export ASPNETCORE_URLS="https://localhost:7123"</code></pre>



<h3 class="wp-block-heading" id="Treat-HTTP-requests-as-bad-requests">Treat HTTP requests as bad requests</h3>



<p>To implement the <em>Bad Request</em> approach, you need to create a custom middleware and use it instead of HTTPS redirection and HSTS middleware. The following example shows a simple version of such a middleware:</p>



<pre class="wp-block-code"><code>// Program.cs

var builder = WebApplication.CreateBuilder(args);

// ...existing code...

var app = builder.Build();

// ...existing code...

// ? new code
//app.UseHttpsRedirection();
app.Use(async (context, next) =&gt; {
    if (!context.Request.IsHttps) {
        context.Response.StatusCode = StatusCodes.Status400BadRequest;
        await context.Response.WriteAsync("HTTPS required!");
    } else {
        await next(context);
    }
});
/ ? new code
  
app.UseStaticFiles();

app.UseRouting();

// ...existing code...</code></pre>



<p>The highlighted code shows that the existing <code>UseHttpsRedirection()</code> method invocation is replaced by the custom middleware. The middleware&#8217;s code just checks if the current request uses HTTPS. If this is not the case, it replies with a <code>400 Bad Request</code> status code and a message warning that HTTPS is required.</p>



<h2 class="wp-block-heading" id="HTTPS-Redirection-and-Reverse-Proxies">HTTPS Redirection and Reverse Proxies</h2>



<p>All the above makes sense if your ASP.NET Core application is directly exposed to the Internet. If your application is deployed in an environment with a reverse proxy that handles connection security, there is no need to use HTTPS redirection or HSTS middleware.</p>



<p>In this case, you can simply remove the <code>UseHttpsRedirection()</code> and the <code>UseHsts()</code> method calls from your ASP.NET Core applications. The same applies to ASP.NET Core Web API application as well: you don&#8217;t need to create a custom middleware to deny HTTP requests. You delegate HTTP to HTTPS switching and control to the reverse proxy.</p>



<h2 class="wp-block-heading" id="Summary">Summary</h2>



<p>This article guided you through the different approaches to force a client to use HTTPS when it calls an ASP.NET Core application. You started from the simple <code>RequireHttps</code> attribute, which redirects to HTTPS-based requests on a page-by-page basis. You then explored the <code>UseHttpsRedirection()</code> method, which allows you to apply HTTPS redirection to all your application&#8217;s pages.</p>



<p>You learned that redirecting from HTTP to HTTPS at each page request doesn&#8217;t guarantee you are not exposed to HTTPS downgrade risks. You took a further step in mitigating this risk by learning about HSTS and the <code>UseHsts()</code> method.</p>



<p>You also learned that HTTPS redirection and HSTS are great approaches for regular web applications, such as ASP.NET Core MVC, Razor, and Blazor applications, but they are not suitable for APIs. In this case, you need to ignore HTTP requests or mark them as bad requests.</p>



<p>Finally, you only need to apply all these measures if your deployment environment doesn&#8217;t take care of protocol switching and control. For example, if your application runs behind a reverse proxy, you can delegate all these checks to it.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-force-https-in-asp-net-core/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
