I write a HttpModule in .Net 3.5 and trying to install on the server root of IIS 10 server. I use gacutil.exe v7.0A successfully install it and I use /l command confirm that my module exists. I add configuration below to C:\Windows\System32\inetsrv\config\applicationHost.config:
<add name="ModuleModEF35" type="ModuleModEF35.MyModule, ModuleModEF35" preCondition="managedHandler" />
And I got FileNotFoundException when i browsed the child website. Due to some reasons, I can't place my module in the individual \bin folder though I know it definitely works.
namespace ModuleModEF35
{
class MyModule : System.Web.IHttpModule
{
void IHttpModule.Dispose()
{
}
void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += Context_BeginRequest;
}
private void Context_BeginRequest(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (context.Request.RawUrl.Contains("%EF"))
{
context.Response.Redirect("https://http.cat/403");
context.Response.End();
}
}
}
}
Related
I want to add a script on my IIS Server.
So that it will be applied on all the websites that are upload will have that script in their request response.
Anyone who knows how to do it?
I had implemented the IHttpModule and IHttpHandler, it works fine for the asp.net projects.
but if the website contains only html, css, and js files in the folder, this solution doesn't work.
Here the HttpModule and HttpHandler
public class MyCustomHttpModuleClass : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PostRequestHandlerExecute += OnPostRequestHandlerExecute;
}
public void OnPostRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
HttpContext context = application.Context;
context.Response.Write("<h1>alert('HELLO')</h1>");
}
}
public class MyHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("<h1>alert('HELLO')</h1>");
}
}
I'm not sure if you have learnt how to add Custom Module and Handler in IIS. After tested your module and handler with static website, it works fine.
I will just give you a sample of adding them to IIS.
1.Create a project "class library .netframework". I name the project"ClassLibrary1"
2.Add class "MyCustomHttpModuleClass" and "MyHandler" to the project
3.Build this solution and find "ClassLibrary1.dll" in the "project/bin/debug" folder.
4.Copy "ClassLibrary1.dll" to the website root "BIN" folder.
5.Add managed module and handler by choose your dll.(should in the list after you copied)Just mention that your custom handler only work on the file extension you set up.
Now they work.
I'm having the weirdest issue and I have no idea why.
When deploying our .net core 2.2 api to our local IIS server I get the following error message:
HTTP Error 502.5 - ANCM Out-Of-Process Startup Failure
After checking the event log I this is the error that I find:
Application: dotnet.exe
CoreCLR Version: 4.6.27207.3
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidOperationException: No service for type 'Digitise.Infrastructure.Services.DatabaseMigrator' has been registered.
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Digitise.ApiBase.BaseProgram.Initialise(String[] args, IWebHost host) in C:\Projects\Digitise.AspNetCore\Digitise.ApiBase\BaseProgram.cs:line 17
at Digitise.Api.Program.Main(String[] args) in C:\Projects\Digitise.AspNetCore\Digitise.Api\Program.cs:line 27
It seems like the DI is not working correctly! The weird thing is if I run the api.exe or dotnet api.dll the API works perfectly :/
Anyone have any ideas? :)
Program.cs
public class Program
{
public static object _lock = new object();
public static bool _init = false;
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args);
Initialise(args, host);
}
public static IWebHost CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
//.UseIISIntegration()
.UseIIS()
.UseNLog()
.UseShutdownTimeout(TimeSpan.FromSeconds(10))
.Build();
public static void Initialise(string[] args, IWebHost host)
{
var logger = NLogBuilder.ConfigureNLog(Path.Combine(Directory.GetCurrentDirectory(), "NLog.config")).GetCurrentClassLogger();
try
{
logger.Debug("App init");
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
if (!_init)
{
lock (_lock)
{
if (!_init)
{
lock (_lock)
{
services.GetRequiredService<DatabaseMigrator>().Migrate();
}
}
}
}
}
catch (Exception ex)
{
logger.Error(ex, "An error occurred while starting up the app.");
throw;
}
}
host.Run();
}
catch (Exception e)
{
logger.Error(e, "Stopped app due to exception");
throw;
}
}
}
DatabaseMigrator.cs
public class DatabaseMigrator
{
private readonly TenantDbContext _tenantDbContext;
private readonly IOptions<DatabaseConfiguration> _databaseConfig;
private readonly ILogger<DatabaseMigrator> _logger;
private readonly AdminTenantDbInitialiser _adminTenantDbInitialiser;
public DatabaseMigrator(TenantDbContext tenantDbContext, IOptions<DatabaseConfiguration> databaseConfig, ILogger<DatabaseMigrator> logger, AdminTenantDbInitialiser adminTenantDbInitialiser)
{
_tenantDbContext = tenantDbContext;
_databaseConfig = databaseConfig;
_logger = logger;
_adminTenantDbInitialiser = adminTenantDbInitialiser;
}
public void Migrate()
{
//migration logic
}
}
I've just gone through a lot of pain fixing a similar problem. Pretty sure the problem is you using Directory.GetCurrentDirectory(), this does odd things when running with in-process hosting as in IIS. I replaced it with Assembly.GetExecutingAssembly().Location and all worked fine.
Clue came from Dotnet Core Multiple Startup Classes with In-Process Hosting
In my case the issue started to show up after I updated some Nuget packages. Installing the latest .NET Core SDK has helped.
Environment: IIS 7.5 using an AppPool set to Managed Pipeline Integrated mode
I'm trying to log the certain state of the HTTP Request before it enters the pipeline and the HTTP response as it exists, specifically a few form values and the cookie collection.
I'm doing this in an HTTPModule
public class MyLoggingModule : IHttpModule
{
private static readonly log4net.ILog _logger =
log4net.LogManager.GetLogger(typeof(MyLoggingModule));
public void Init(HttpApplication context)
{
context.BeginRequest += LogRequestState;
context.EndRequest += LogResponseState;
}
}
private void LogRequestState(object sender, EventArgs e)
{
//Invokes...
HttpContext.Current.Server.UrlDecode
HttpContext.Current.Request.Url
HttpContext.Current.Request.Form.AllKeys
HttpContext.Current.Request.Cookies
HttpContext.Current.Response.Cookies.AllKeys
_logger.Debug("...");
}
private void LogResponseState(object sender, EventArgs e)
{
// Invokes ...
FederatedAuthentication.SessionAuthenticationModule.CookieHandler.Name
HttpContext.Current.Response.Cookies.AllKeys
_logger.Debug("...");
}
Web.Config settings
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="false">
<add name="MyLoggingModule" type="MyApp.Api.HttpModules.MyLoggingModule, MyApp.Api"/>
</modules>
<urlCompression doStaticCompression="true" doDynamicCompression="true"/>
</system.webServer>
I will get a runtime error only available in the Application Logs (try/catch does not catch this exception):
Exception information:
Exception type: NullReferenceException
Exception message: Object reference not set to an instance of an object.
at System.Web.HttpApplication.PipelineStepManager.ResumeSteps(Exception error)
at System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb)
at System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context)
It seems to be very similar to the issue raised here: HttpModule.Init - safely add HttpApplication.BeginRequest handler in IIS7 integrated mode
That issue has a solution along the lines of
public class MyLoggingModule : IHttpModule
{
public override void Init()
{
base.Init();
lock (_initialisationLockObject)
{
context.BeginRequest -= LogRequestState;
context.BeginRequest += LogRequestState;
context.EndRequest -= LogResponseState;
context.EndRequest += LogResponseState;
}
}
}
Given that the post is over 8 years old and the solution was not accepted and criticized on other posts is there a way to achieve this now?
I have a website using Nancy which is hosted using OWIN.
In my Startup.cs file I define the PassThroughOptions as follows:
public void Configuration(IAppBuilder app)
{
app.UseNancy(o => {
o.PassThroughWhenStatusCodesAre(
HttpStatusCode.NotFound,
HttpStatusCode.InternalServerError
);
o.Bootstrapper = new Bootstrapper();
});
app.UseStageMarker(PipelineStage.MapHandler);
}
I need to pass-through the NotFound requests, so that things like my bundled .less files or miniprofiler-results or static files in the root of my site (robots.txt or sitemap.xml) work.
I also have a custom StatusCodeHandler for the 404 code, which also checks a custom header to distinguish between static files (or .less bundles/miniprofiler) and actual stuff that is not found in my modules' methods.
public void Handle(HttpStatusCode statusCode, NancyContext context)
{
Log.Warn("Not found: " + context.Request.Url);
base.Handle(statusCode, context, "Errors/NotFound");
}
This handler then should actually show the error page.
protected void Handle(HttpStatusCode statusCode, NancyContext context, string view)
{
var response = new Negotiator(context)
.WithModel(GetErrorModel(context))
.WithStatusCode(statusCode)
.WithView(view);
context.Response = responseNegotiator.NegotiateResponse(response, context);
}
But the error page is never shown. The request is processed three times and eventually the default IIS error page is shown (using errorMode="Custom" for httpErrors) or simply a white page (using existingResponse="PassThrough" for httpErrors).
Is there any way to display something so simple as a custom error page when hosting a Nancy website on OWIN?
What you've got there looks good, it looks like you've be using the Hosting Nancy with Owin docs.
Here's what works for me:
The Startup.cs (required for Owin): (We've both coded the configuration function differently, you're just using the extension helper while I'm not. Same result. This is in my App.Web project.)
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseNancy(options =>
{
options.Bootstrapper = new BootStrapper();
options.PerformPassThrough = context => context.Response.StatusCode == HttpStatusCode.NotFound;
});
app.UseStageMarker(PipelineStage.MapHandler);
}
}
404 handler: (As per the docs, doesn't matter where this is in the project, by implementing IStatusCodeHandler it'll be automatically picked up by Nancy This is in my App.WebApi project with other module classes.)
public class StatusCode404Handler : IStatusCodeHandler
{
public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context)
{
return statusCode == HttpStatusCode.NotFound;
}
public void Handle(HttpStatusCode statusCode, NancyContext context)
{
var response = new GenericFileResponse("statuspages/404.html", "text/html")
{
StatusCode = statusCode
};
context.Response = response;
}
}
The 'statuspages' folder in my App.Web project:
Check this SO post for a comparison of using GenericFileReponse or ViewRenderer (How to display my 404 page in Nancy?).
I have a ServiceStack Service with a service call like so:
public class MyService : Service
{
public object Get(MyServiceRequest request)
{
using (Profiler.Current.Step("Getting Data"))
{
// code that gets data
using (Profiler.Current.Step("Doing work with data"))
{
// code that does work
}
}
return response;
}
}
and a global.asax.cs like so:
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
new AppHost().Init();
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (Request.IsLocal)
Profiler.Start();
}
protected void Application_EndRequest(object sender, EventArgs e)
{
Profiler.Stop();
}
}
My problem is that when I test the service call through the browser I only see profile information for the overall request. "show time with children" and "show trivial" don't provider any more granular information. I've also placed breakpoints within each using statement to get a look at Profiler.Current and noticed in each case its Children property is null. Am I doing it wrong? Are they any other things I can do to troubleshoot this?
For some reason setting the level argument to Profile.Info in the Step method resolves my issue. That's weird because Profile.Info is the default if no argument is provided. Oh well. Moving on.