Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP NET Core Serving specific html page

I have this middleware:

public class SpecificPageMiddleware
{
    private readonly RequestDelegate next;

    public SpecificPageMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (this.IsSubDomainRequest(context.Request.Host.Value)) 
        {
            if (this.IsIndexRequest(context.Request.Path.Value)) 
            {
                await this.ReturnIndexPage(context);
                return;
            }
        }

        await this.next.Invoke(context);
    }

    private bool IsSubDomainRequest(string host)
    {
        return host.StartsWith("subdomain")
                || host.Contains("subdomain");
    }

    private bool IsIndexRequest(string query)
    {
        return query == "/" || query == "/response.html";
    }

    private static async Task ReturnIndexPage(HttpContext context)
    {
        var file = new FileInfo(@"wwwroot\response.html");
        byte[] buffer;
        if (file.Exists)
        {
            context.Response.StatusCode = (int)HttpStatusCode.OK;
            context.Response.ContentType = "text/html";

            buffer = File.ReadAllBytes(file.FullName);
        }
        else
        {
            context.Response.StatusCode = (int)HttpStatusCode.NotFound;
            context.Response.ContentType = "text/plain";

            buffer = Encoding.UTF8.GetBytes("Unable to find the requested file");
        }

        using (var stream = context.Response.Body)
        {
            await stream.WriteAsync(buffer, 0, buffer.Length);
            await stream.FlushAsync();
        }

        context.Response.ContentLength = buffer.Length;
    }
}

Quite simply, when I get something like this through: subdomain.mydomain.com I want to show a specific html page otherwise carry on the normal middleware pipeline to www.mydomain.com.

When this middleware gets hit, it ends up as a 404 in the browser. If I don't set a content type then it ends up as 200 with all the html written out as text, rather then rendered as html. What am I missing here?

I don't want to use app.UseDefaultFiles() or app.UseStaticFiles().

like image 946
Callum Linington Avatar asked Feb 19 '16 16:02

Callum Linington


1 Answers

Answer.

One mistake you're making is here:

await this.ReturnIndexPage(context);                      // wrong!
await SpecificPageMiddleware.ReturnIndexPage(context);    // right (1)
await ReturnIndexPage(context);                           // right (2)

this means the instance. You cannot access a static method from the instance. Instead you have to qualify it with a type name (1) or with no qualification (2) and you're fine.

Works on my machine

For good measure, this is up on GitHub too as a demo.

SimpleMiddleware.cs

using Microsoft.AspNet.Builder;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using System.IO;
using System.Text;
using System.Net;

namespace App04SimpleMiddleware
{
    public class SimpleMiddleware
    {
        private readonly RequestDelegate _next;
        public SimpleMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            if (context.Request.QueryString.ToString().Contains("simple"))
            {
                await ReturnIndexPage(context);          // right! 
                return;
            }
            await _next.Invoke(context);
        }

        private static async Task ReturnIndexPage(HttpContext context)
        {
            var file = new FileInfo(@"wwwroot\response.html");
            byte[] buffer;
            if (file.Exists)
            {
                context.Response.StatusCode = (int)HttpStatusCode.OK;
                context.Response.ContentType = "text/html";

                buffer = File.ReadAllBytes(file.FullName);
            }
            else
            {
                context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                context.Response.ContentType = "text/plain";
                buffer = Encoding.UTF8
                    .GetBytes("Unable to find the requested file");
            }

            context.Response.ContentLength = buffer.Length;

            using (var stream = context.Response.Body)
            {
                await stream.WriteAsync(buffer, 0, buffer.Length);
                await stream.FlushAsync();
            }    
        }
    }
}

Startup.cs

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;

namespace App04SimpleMiddleware
{
    public class Startup
    {   
        public void Configure(IApplicationBuilder app)
        {
            app.UseMiddleware<SimpleMiddleware>();            
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello world!");
            });
        }
    }
}

Result

Simple query string

No query string

like image 120
Shaun Luttin Avatar answered Oct 07 '22 14:10

Shaun Luttin