受欢迎的博客标签

err message:Invalid non-ASCII or control character in header: 0x914 in asp .net core(iaspnetcore)

Published

How to capture and log errors in program.cs with ASP.NET Core?

.NET Core version:ASP.NET Core 3.x

OS:windows server 2012 R2

   

I am getting an error on my website with Invalid non-ASCII or control character in header: 0x914. My website has URLs with non-ASCII characters.        

my  code in www.iaspnetcore.com:

public virtual IActionResult SetLanguage(string culture, string returnUrl = "")

{

Response.Cookies.Append(

CookieRequestCultureProvider.DefaultCookieName,

CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),

new CookieOptions

{

Expires = DateTimeOffset.UtcNow.AddYears(1)

}

);

CultureInfo.CurrentUICulture = new CultureInfo(culture);

return Redirect(returnUrl);

}

  Inspecting the std out logs for my site, I see exceptions like this: 

fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0] An unhandled exception has occurred: Invalid non-ASCII or control character in header: 0x0914 

System.InvalidOperationException: Invalid non-ASCII or control character in header: 0x0914 at 

Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.FrameHeaders.ThrowInvalidHeaderCharacter(Char ch) at 

Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.FrameHeaders.ValidateHeaderCharacters(String headerCharacters) at 

Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.FrameHeaders.ValidateHeaderCharacters(StringValues headerValues) at 

Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.FrameResponseHeaders.SetValueFast(String key, StringValues value)

It seems that when a redirect happens, the code in Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.Redirect is setting a Location header, which is probably one of these URLs with a non-ASCII character

  Step 1: Add .CaptureStartupErrors(true) in program.cs 

Please see CaptureStartupErrors and the method .CaptureStartupErrors(true) that will help you find error.  

Here is my usual config for NetCore Web Apps:

public static IWebHost BuildWebHost(string[] args) =>

WebHost .CreateDefaultBuilder(args)

.CaptureStartupErrors(true)

.UseKestrel()

.UseIISIntegration()

.UseStartup<Startup>()

.UseAzureAppServices()

.Build();

Step 2: write ErrorLoggingMiddleware log error into Database

 

public class ErrorLoggingMiddleware

{

private readonly RequestDelegate _next;

private readonly ILogger _logger;

private readonly DiagnosticSource _diagnosticSource;

private readonly IWorkContext _workContext;

public ErrorLoggingMiddleware(RequestDelegate next,

DiagnosticSource diagnosticSource,

ILogger logger,

IWorkContext workContext)

{

if (next == null)

{

throw new ArgumentNullException(nameof(next));

}

if (logger == null)

{

throw new ArgumentNullException(nameof(logger));

}

if (workContext == null)

{

throw new ArgumentNullException(nameof(workContext));

}

_next = next;

_diagnosticSource = diagnosticSource;

_logger = logger;

_workContext = workContext;

}

public async Task Invoke(HttpContext context)

{

var ip = "127.0.0.1";

ip = context.Request.Headers["X-Forwarded-For"].ToString();

if (!string.IsNullOrEmpty(ip))

{

ip = context.Connection.RemoteIpAddress.ToString();

}

try

{

await _next(context);

}

catch (Exception ex)

{

Log log = new Log();

log.LogLevel = LogLevel.Error;

log.ReferrerUrl = context.Request.Headers["referer"].ToString() + " " + context.Connection.RemoteIpAddress.ToString();

log.ShortMessage = "error find:by ErrorLoggingMiddleware";

log.FullMessage = context.Request.Headers["User-Agent"]+ "err message:" +ex.Message +"ex.StackTrace:"+ex.StackTrace;

log.PageUrl = context.Request.Host.ToString() + context.Request.Path.ToString() + context.Request.QueryString.ToString();

log.IpAddress = ip;

log.CreatedOnUtc = DateTime.UtcNow;

_logger.InsertLog(log);

var error = context.Features.Get();

if (error != null)

{

// This error would not normally be exposed to the client

//await context.Response.WriteAsync("Error: " + HtmlEncoder.Default.Encode(error.Error.Message) + "\r\n");

//await context.Response.WriteAsync("Error: " + HtmlEncoder.Default.Encode(ex.StackTrace) + "\r\n");

}

System.Diagnostics.Debug.WriteLine($"The following error happened: {ex.Message}");

throw; // Don't stop the error

}

}

}

Step 3: change

return Redirect(returnUrl);

to

return Redirect(Uri.EscapeUriString(returnUrl));.