IIS 7.5 and IIS 8.0 European Hosting

BLOG about IIS 7.5 Hosting, IIS 8.0 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

IIS 8.0 Hosting - HostForLIFE.eu :: URL Rewriting Middleware In ASP.NET Core

clock June 24, 2021 09:08 by author Peter

In the previous article of this series, we discussed the route concept with MVC Pattern within .NET Core Application. Now, in this article, we will discuss how can we use URL rewriting mechanism.


Basically URL Rewriting is the act of modifying request URLs based on one or more predefined rules. URL rewriting creates an abstraction between resource locations and their addresses so that the locations and addresses are not tightly linked. There are several scenarios where URL rewriting is valuable:

    Moving or replacing server resources temporarily or permanently while maintaining stable locators for those resources
    Splitting request processing across different applications or across areas of one application
    Removing, adding, or reorganizing URL segments on incoming requests
    Optimizing public URLs for Search Engine Optimization (SEO)
    Permitting the use of friendly public URLs to help people predict the content they will find by following a link
    Redirecting insecure requests to secure endpoints
    Preventing image hotlinking

We can define rules for changing the URL in several ways, including regular expression (regex) matching rules, rules based on the Apache mod_rewrite module, rules based on the IIS Rewrite Module, and with your own method and class rule logic. In this article, we will discuss about the URL rewriting with instructions on how to use URL Rewriting Middleware in ASP.NET Core applications.

URL redirect and URL rewrite
A URL redirect is a client-side operation, where the client is instructed to access a resource at another address. This requires a round-trip to the server, and the redirect URL returned to the client will appear in the browser's address bar when the client makes a new request for the resource. If /resource is redirected to /different-resource, the client will request /resource, and the Server will respond that the client should obtain the resource at /different-resource with a status code indicating that the redirect is either temporary or permanent. The client will execute a new request for the resource at the redirect URL.

A URL rewrite is a server-side operation to provide a resource from a different resource address. Rewriting a URL doesn't require a round-trip to the server. The rewritten URL is not returned to the client and won't appear in a browser's address bar. When /resource is rewritten to /different-resource, the client will request /resource, and the server will internally fetch the resource at /different-resource. Although the client might be able to retrieve the resource at the rewritten URL, the client won't be informed that the resource exists at the rewritten URL when it makes its request and receives the response.

When to use URL Rewriting Middleware
Use URL Rewriting Middleware when you are unable to use the URL Rewrite module in IIS on Windows Server, the Apache mod_rewrite module on Apache Server, URL rewriting on Nginx, or your application is hosted on WebListener server. The main reasons to use the server-based URL rewriting technologies in IIS, Apache, or Nginx are that the middleware doesn't support the full features of these modules and the performance of the middleware probably won't match that of the modules. However, there are some features of the server modules that don't work with ASP.NET Core projects, such as the IsFile and IsDirectory constraints of the IIS Rewrite module. In these scenarios, you can use the middleware instead.

Package
To include the middleware in your project, add a reference to the Microsoft.AspNetCore.Rewrite package. The middleware depends on .NET Framework 4.5.1 or .NET Standard 1.3 or later. This feature is available for apps that target ASP.NET Core 1.1.0 or later.

Extension and options
Establish your URL rewrite and redirect rules by creating an instance of the RewriteOptions class with extension methods for each of your rules. Chain multiple rules in the order that you would like them processed. The RewriteOptions are passed into the URL Rewriting Middleware as it's added to the request pipeline with app.UseRewriter(options);
    var options = new RewriteOptions()  
    .AddRedirect("redirect-rule/(.*)", "redirected/$1")  
    .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", skipRemainingRules: true)  
    .AddApacheModRewrite(env.ContentRootFileProvider, "ApacheModRewrite.txt")  
    .AddIISUrlRewrite(env.ContentRootFileProvider, "IISUrlRewrite.xml")  
    .Add(RedirectXMLRequests)  
    .Add(new RedirectImageRequests(".png", "/png-images"))  
    .Add(new RedirectImageRequests(".jpg", "/jpg-images"));  
    app.UseRewriter(options);  


URL redirect
Use AddRedirect() to redirect requests. The first parameter will contain your regex for matching on the path of the incoming URL. The second parameter is the replacement string. The third parameter, if present, specifies the status code. If you don't specify the status code, it defaults to 302 (Found), which indicates that the resource has been temporarily moved or replaced.
    var options = new RewriteOptions()  
    .AddRedirect("redirect-rule/(.*)", "redirected/$1")  
    .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", skipRemainingRules: true)  
    .AddApacheModRewrite(env.ContentRootFileProvider, "ApacheModRewrite.txt")  
    .AddIISUrlRewrite(env.ContentRootFileProvider, "IISUrlRewrite.xml")  
    .Add(RedirectXMLRequests)  
    .Add(new RedirectImageRequests(".png", "/png-images"))  
    .Add(new RedirectImageRequests(".jpg", "/jpg-images"));  
    app.UseRewriter(options);  


In a browser with developer tools enabled, make a request to the sample application with the path /redirect-rule/1234/5678. The regex matches the request path on redirect-rule/(.*), and the path is replaced with /redirected/1234/5678. The redirect URL is sent back to the client with a 302 (Found) status code. The browser makes a new request at the redirect URL, which will appear in the browser's address bar. Since no rules in the sample application match on the redirect URL, the second request receives a 200 (OK) response from the application and the body of the response shows the redirect URL. A complete roundtrip is made to the server when a URL is redirected.

Original Request: /redirect-rule/1234/5678

The part of the expression contained by parentheses is called a capture group. The dot ( . ) of the expression means match any character, and the asterisk ( * ) signifies to match the preceding character zero or more times. Therefore, the last two path segments of the URL, 1234/5678, are captured by capture group (.*). Any value you provide in the request URL after redirect-rule/ will be captured by this single capture group. In the replacement string, captured groups are injected into the string with the dollar sign ( $ ) followed by the sequence number of the capture. The first capture group value is obtained with $1, the second with $2, and they continue in sequence for the capture groups in your regex. There is only one captured group in the redirect rule regex in the sample application, so there is only one injected group in the replacement string, which is $1. When the rule is applied, the URL becomes /redirected/1234/5678.

URL redirect to a secure endpoint
Use AddRedirectToHttps() to redirect insecure requests to the same host and path with secure HTTPS protocol (https:// ) with the flexibility to choose the status code and port. If the status code is not supplied, the middleware will default to 302 (Found). If the port is not supplied, the middleware will default to null, which means the protocol will change to https:// and the client will access the resource on port 443. The example shows how to set the status code to 301 (Moved Permanently) and change the port to 5001.
    var options = new RewriteOptions()  
    .AddRedirectToHttps(301, 5001);  
    app.UseRewriter(options);  


Use AddRedirectToHttpsPermanent() to redirect insecure requests to the same host and path with secure HTTPS protocol ( https:// on port 443). The middleware will set the status code to 301 (Moved Permanently).

Original Request using AddRedirectToHttps(301, 5001) : /secure

Original Request using AddRedirectToHttpsPermanent() : /secure

URL rewrite
Use AddRewrite() to create a rules for rewriting URLs. The first parameter will contain your regex for matching on the incoming URL path. The second parameter is the replacement string. The third parameter,

skipRemainingRules: {true|false} , will indicate to the middleware whether or not to skip additional rewrite rules if the current rule is applied.
    var options = new RewriteOptions()  
    .AddRedirect("redirect-rule/(.*)", "redirected/$1")  
    .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", skipRemainingRules: true)  
    .AddApacheModRewrite(env.ContentRootFileProvider, "ApacheModRewrite.txt")  
    .AddIISUrlRewrite(env.ContentRootFileProvider, "IISUrlRewrite.xml")  
    .Add(RedirectXMLRequests)  
    .Add(new RedirectImageRequests(".png", "/png-images"))  
    .Add(new RedirectImageRequests(".jpg", "/jpg-images"));  
    app.UseRewriter(options);  

Original Request: /rewrite-rule/1234/5678


The first thing you will notice in the regex is the carat ( ^ ) at the beginning of the expression. This means that matching should be attempted starting at the beginning of the URL path.

Code for startup.cs
using System;  
using System.IO;  
using Microsoft.AspNetCore.Builder;  
using Microsoft.AspNetCore.Hosting;  
using Microsoft.AspNetCore.Http;  
using Microsoft.AspNetCore.Rewrite;  
using Microsoft.Extensions.Logging;  
using Microsoft.Net.Http.Headers;  
using CoreLibrary;  
 
namespace Prog7_URLRewrite  
{  
    public class Startup  
    {  
        // This method gets called by the runtime. Use this method to add services to the container.  
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940  
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)  
        {  
            var options = new RewriteOptions()  
                                .AddRedirect("redirect-rule/(.*)", "redirected/$1")  
                .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", "rewritten?var1=$1&var2=$2", skipRemainingRules: true)  
                .AddApacheModRewrite(env.ContentRootFileProvider, "ApacheModRewrite.txt")  
                .AddIISUrlRewrite(env.ContentRootFileProvider, "IISUrlRewrite.xml")  
                .Add(RedirectXMLRequests)  
                .Add(new RedirectImageRequests(".png", "/png-images"))  
                .Add(new RedirectImageRequests(".jpg", "/jpg-images"));  
            app.UseRewriter(options);  
            app.Run(context => context.Response.WriteAsync($"Rewritten or Redirected Url: {context.Request.Path + context.Request.QueryString}"));  
        }  
 
        static void RedirectXMLRequests(RewriteContext context)  
        {  
            var request = context.HttpContext.Request;  
            if (request.Path.StartsWithSegments(new PathString("/xmlfiles")))  
            {  
                return;  
            }  
            if (request.Path.Value.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))  
            {  
                var response = context.HttpContext.Response;  
                response.StatusCode = StatusCodes.Status301MovedPermanently;  
                context.Result = RuleResult.EndResponse;  
                response.Headers[HeaderNames.Location] = "/xmlfiles" + request.Path + request.QueryString;  
            }  
        }  
 
        public static void Main(string[] args)  
        {  
            var host = new WebHostBuilder()  
                .ConfigureLogging(factory =>  
                                {  
                                    factory.AddConsole(LogLevel.Debug);  
                                })  
                .UseContentRoot(Directory.GetCurrentDirectory())  
                                .UseKestrel(options =>  
                {  
                    options.UseHttps("testCert.pfx", "testPassword");  
                })  
                                .UseStartup<Startup>()  
                                                .UseUrls("http://localhost:5000", "https://localhost", "https://localhost:5001")  
                                                                .Build();  
            host.Run();  
 
        }  
          
    }  
}  


Code for rewrite.cs
using Microsoft.AspNetCore.Http;  
using Microsoft.AspNetCore.Rewrite;  
using Microsoft.Net.Http.Headers;  
using System;  
using System.Text.RegularExpressions;  
 
namespace CoreLibrary  
{  
    public class RewriteRules : IRule  
    {  
        private string _extension;  
 
        private PathString _newPath;  
 
        public RedirectImageRequests(string extension, string newPath)  
        {  
            if (string.IsNullOrEmpty(extension))  
            {  
                throw new ArgumentException(nameof(extension));  
            }  
            if (!Regex.IsMatch(extension, @"^\.(png|jpg|gif)$"))  
            {  
                throw new ArgumentException("The extension is not valid. The extension must be .png, .jpg, or .gif.", nameof(extension));  
            }  
 
            if (!Regex.IsMatch(newPath, @"(/[A-Za-z0-9]+)+?"))  
            {  
                throw new ArgumentException("The path is not valid. Provide an alphanumeric path that starts with a forward slash.", nameof(newPath));  
            }  
            _extension = extension;  
            _newPath = new PathString(newPath);  
        }  
 
 
 
        public void ApplyRule(RewriteContext context)  
        {  
            var request = context.HttpContext.Request;  
            if (request.Path.StartsWithSegments(new PathString(_newPath)))  
            {  
                return;  
            }  
 
            if (request.Path.Value.EndsWith(_extension, StringComparison.OrdinalIgnoreCase))  
            {  
                var response = context.HttpContext.Response;  
                response.StatusCode = StatusCodes.Status301MovedPermanently;  
                context.Result = RuleResult.EndResponse;  
                response.Headers[HeaderNames.Location] = _newPath + request.Path + request.QueryString;  
            }  
        }  
    }  
}



IIS Hosting Europe - HostForLIFE.eu :: IIS Hosting .Net Core MVC 3.1 | In Process Hosting | w3wp.exe Worker Process

clock June 18, 2021 09:11 by author Peter

I am here to introduce you to InProcess hosting in a .Net Core MVC 3.1 web application with the w3wp worker process.

 
Also, we will learn how to configure the source code to the IIS and run the application with debugging.
 
I suppose that since you are looking for hosting, you have already installed the necessary features for that.
 
The main feature you need to install for hosting in IIS is the IIS runtime support (ASP.NET Core Module v2) Hosting Bundle.
 
I have a Visual studio 2019 community version with pre-installed features for the development of an application.
 
Let begin with downloading the ASP.NET Core Runtime Hosting bundle from Url https://dotnet.microsoft.com/download/dotnet-core/3.1
 
Step 1
 
If you haven't already installed the Hosting Bundle, please install it from the given link.


Step 2
 
After installing, let's go to the IIS manager and map our Project directory source in IIS.


Step 3
Map your Source Code path.

Step 4

I have set the Application Pool setting with NetworkServices Identity. You can also choose another as per your requirement.


Step 5
Add the Module AspNetCoreModuleV2 by following the below-given process in the screenshot.


You can also do this at the application level in your project's web.config
 
If you don't have web config right now, please follow step 6 given below and build your project.
    <system.webServer>  
       <modules>   
         <add name="AspNetCoreModuleV2" />  
       </modules>  
     </system.webServer>  


Step 6
Add the Marked Code in your Launchsettings.json

Add the below code marked in bold:
    {  
      "iisSettings": {  
        "windowsAuthentication": false,  
        "anonymousAuthentication": true,  
        "iis": {  
          "applicationUrl": "http://localhost:1111/",  
          "sslPort": 0  
        },  
        "iisExpress": {  
          "applicationUrl": "http://localhost:59631",  
          "sslPort": 44338  
        }  
      },  
      "profiles": {  
        "IIS Express": {  
          "commandName": "IISExpress",  
          "launchBrowser": true,  
          "environmentVariables": {  
            "ASPNETCORE_ENVIRONMENT": "Development",  
            "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"  
          }  
        },  
        "TestDemo": {  
          "commandName": "Project",  
          "launchBrowser": true,  
          "environmentVariables": {  
            "ASPNETCORE_ENVIRONMENT": "Development",  
            "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"  
          },  
          "applicationUrl": "https://localhost:5001;http://localhost:5000"  
        },  
        "Local IIS": {  
          "commandName": "IIS",  
          "launchBrowser": true,  
          "launchUrl": "http://localhost:1111/",  
          "environmentVariables": {  
            "ASPNETCORE_ENVIRONMENT": "Development"  
          }  
        }  
      }  
    }  


Step 6
Please make sure your project is running with InProcess hosting Model


    <PropertyGroup>  
       <TargetFramework>netcoreapp3.1</TargetFramework>    
       <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>  
     </PropertyGroup>  


Step 7 
As you have recently created a profile using launchsetting.json, now you can change the Debug property to Local IIS and run your application.


Here you can see the URL. Our mapping URL http://Localhost:1111 is working now and you can debug your code.
 
If you are still facing issues with reaching breakpoints, please add webBuilder.UseIIS(); to your program.cs.
     public static IHostBuilder CreateHostBuilder(string[] args) =>  
              Host.CreateDefaultBuilder(args)  
                  .ConfigureWebHostDefaults(webBuilder =>  
                  {  
                      webBuilder.UseIIS();  
                      webBuilder.UseStartup<Startup>();  
                  });  
      }
 

That's it



IIS Hosting Europe - HostForLIFE.eu :: How to Access the Site Using Domain Name Instead of localhost in IIS?

clock June 11, 2021 08:37 by author Peter

Whenever we host a website in Internet Information Services (IIS), we previously would access the website with localhost or with that specific machine IP address in the manner of: http://localhost/TestSite/TestPage.aspx

Did you ever think of accessing your website with a domain name, such as http://www.testsite.com, instead of http://localhost/testsite or http://127.0.0.1/testsite on your local machine?

How can I tell my IIS that http://www.testsite.com is pointing to the files on my local computer and to not try to access the internet?

The answer behind all these questions is the Hosts file.

This will be in <Windows Root Folder>\System32\Drivers\etc\. In general if the Windows Operating System is installed in the C drive then it will be C:\Windows\System32\drivers\etc. You can open this file in Notepad, Notepad++ or any text editor that you have. If you open this file, it will be as follows.

local host

Note: You need administrator privileges to save your changes in this file.

Case 1

If you want to create a new website then that is possible for accessing using a domain name. Use the following procedure.

Open IIS (Click WIN+R, enter inetmgr in the dialog and click OK. Alternatively, search for IIS Manger in start window).

Expand the Server node and click on the Sites folder.

Click on Add Website in the Actions pane.

Note: If need any help for the preceding procedure then please check my blog article How to setup basic website in IIS 8.

Enter the details in the Add Website window as follows.


Click on Ok to create the website.

If you try to browse your website now, you will see an alert in Chrome that your webpage is not available. You will see the same kind of issue in other browsers also.

This is because the address you entered will search in the internet instead of your localhost. To overcome this open the Hosts file in any text editor and add the following command.

127.0.0.1 www.testsite.com

Now try to reload the page by clearing the browser cache. It will work as follows.

Case 2
If you want to access the website using the domain name you created then use the following procedure.

Open IIS (Click WIN+R, enter inetmgr in the dialog and click OK. Alternatively, search for IIS Manger in start window).

Expand the Server node and then expand Sites folder.

Click on the Website that you want to access using a domain name and then click on Bindings in the Actions pane.


Select the binding of type http and then click on Edit. This will open a new window as follows:


Enter the host name in the provided text box.

I am entering this as www.google.com because I want to access my site with a Google address.

Now make the change in the hosts file as we did in #6 in case1.

After having made this change you can access your local website with the Google address.


Note: The changes you are making in the hosts files are applicable only to that specific local machine in which the file exits.

 



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in