I've created a custom module:
namespace KittenFarm.ServerModules
{
public class CustomServerHeaderModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += OnPreSendRequestHeaders;
}
public void Dispose()
{ }
void OnPreSendRequestHeaders(object sender, EventArgs e)
{
HttpContext.Current.Response.Headers.Remove("Server");
}
}
}
And I've registered it in my web config:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<add name="CustomServerHeader" type="CustomServerHeaderModule" />
</modules>
....
However, it never seems to run.
I suspected it was a namespace issue, but I have tried every combination of namespaces in the type= section I can think of and it never hits the breakpoint I put in it.
Any ideas?
You are correct, it is your namespace that is missing from the type.
The following worked for me:
<modules runAllManagedModulesForAllRequests="true">
<add name="CustomServerHeader" type="KittenFarm.ServerModules.CustomServerHeaderModule" />
</modules>
The problem was that the solution was set up to use the Visual Studio Development Server, which doesn't pick up the http modules. After I changed it to use my local IIS, it worked.
You can set your function to run before Application_Start method is called. Add below code in global.asax
[assembly:PreApplicationStartMethod(typeof(CS.MVCHttpModule.MvcApplication),"Register")]
See http://dotnetlionet.blogspot.in/2015_06_01_archive.html
Related
I am trying to learn about the custom Http Handlers. Using VS2019 Community, I created the default ASP.NET Web App with MVC option, target for .NET Framework 4.7.2. Then I defined the custom Http Handler as
namespace WebApplication25
{
public class CustomHandler : IHttpHandler
{
public bool IsReusable
{
get
{
return true;
}
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("<h1>WelCome</h1>");
}
}
}
In the file Web.config
<system.webServer>
<handlers>
<add verb="*" path="*.curry" name="CustomHandler" type="WebApplication25.CustomHandler"/>
</handlers>
</system.webServer>
Then during the standard run with localhost I enter
https://localhost:44325/notes.curry
but the code for CustomHandler is not even run. In the browser I get
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404.....
I have an HttpHandler that I'm trying to use to put a little security layer over a certain directory in my site, but it's behaving strangely.
I've got it registered like this in my Web.Config: no longer valid since I'm in IIS 7.5
<httpHandlers>
<add verb="*" path="/courses/*" type="CoursesAuthenticationHandler" />
I can't tell if it's actually being called or not, because regardless of the code, it always seems to do nothing. On the flip side, if there are any errors in the code, it does show me an error page until I've corrected the error.
Here's the handler itself:
using System;
using System.Web;
public class CoursesAuthenticationHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
if (!context.Request.IsAuthenticated)
context.Response.Redirect("/");
}
}
So... that's pretty much it. The handler is being registered and analyzed at compile time, but doesn't actually do what it's expected to.
Edit: I realized that I'm using IIS 7.5 and that does indeed have an impact on this implementation.
For IIS 7, here's the Web.Config registration I used:
<handlers accessPolicy="Read, Execute, Script">
<add name="CoursesAuthenticationHandler"
verb="*"
path="/courses/*"
type="CoursesAuthenticationHandler"
resourceType="Unspecified" />
Edit 2: Progress! When not logged in, requests made to the /courses/ directory are redirected to the login page. However, authenticated requests to the /courses/ directory return empty pages...
Edit 3: Per #PatrickHofman's suggestion, I've switched to using an HttpModule.
The Web.Config registration:
<modules>
<add name="CourseAuthenticationModule" type="CourseAuthenticationModule" />
The code:
using System;
using System.Web;
public class CourseAuthenticationModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(BeginRequest);
}
public void BeginRequest(Object source, EventArgs e)
{
HttpApplication app = (HttpApplication)source;
HttpContext context = app.Context;
HttpRequest request = context.Request;
HttpResponse response = context.Response;
if (request.Path.ToLower().StartsWith("/courses/") && !request.IsAuthenticated)
{
response.Redirect("/");
}
}
}
Now the problem is that !request.IsAuthenticated is always false. If I'm logged in, and navigate to the /courses/ directory, I'm redirected to the homepage.
What's the deal?
I think the last problem lies in the fact that a HttpHander handles stuff. It is the end point of a request.
Since you didn't add anything to the request, the response will end up empty.
Are you looking for HttpModules? They can be stacked.
As a possible solution when only files are necessary: read the files yourself in the request by either reading and writing to response or use TransmitFile. For ASP.NET pages you need modules.
I have a problem with logging an message to EventViewer\WindowsLogs using a custom HTTPModule class. I've already try to run Visual Studio with admin rights, I also tried from IIS 6.0. It doesn't crash, it just doesn't add any code. Below it's the module class and the config file.
HttpModule
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Diagnostics;
namespace Chapter_V.HttpModules
{
public class MyHttpModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.AuthenticateRequest += new EventHandler(OnAuthentication);
}
private void OnAuthentication(object sender, EventArgs e)
{
string name = HttpContext.Current.User.Identity.Name;
EventLog log = new EventLog();
log.Source = "My First HttpModule";
log.WriteEntry(name + " was authenticated !");
}
public void Dispose()
{
}
}
}
web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<httpModules>
<add name="MyHttpModule" type="Chapter_V.HttpModules.MyHttpModule,ChapterV"/>
</httpModules>
</system.web>
<system.webServer>
<modules>
<add name="MyHttpModule" type="Chapter_V.HttpModules.MyHttpModule,ChapterV"/>
</modules>
</system.webServer>
</configuration>
Do you have any ideea about this issue? (this is only for study purposes)
Provided the user identity on your application pool has the rights to create event log entries.
Try running the following script:
eventcreate /ID 1 /L APPLICATION /T INFORMATION /SO "My First HttpModule" /D "My first log"
This will create a new event source named "My First HttpModule" under APPLICATION event log as INFORMATION event type.
Not sure of the exact reasons why, but a source must already exist (be created) in the event log before it can be used in code.
Source of information is here
1- I have a class structure as shown below.
namespace ViewStateSeoHelper
{
class ViewStateSeoModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
if (application.Context.Request.Url.AbsolutePath.Contains(".aspx"))
application.Response.Filter = new HtmlFilterStream(application.Response.Filter);
}
public void Dispose()
{
}
}
}
I'm using something like this to using in all those pages through upper code.
<httpModules>
<add name="ViewStateSeoModule" type="ViewStateSeoModule" />
</httpModules>
But,I got the configuration error.
Parser Error: Could not load type 'ViewStateSeoModule'.
(C:\Users\xxx\Documents\Visual Studio 2010\WebSites\xxx\web.config
line 78) Line 78:
Thanks in advance.
You have wrapped your code in a namespace but not referred to it in the web.config:
<httpModules>
<add name="ViewStateSeoModule" type="ViewStateSeoHelper.ViewStateSeoModule" />
</httpModules>
The type attribute needs to include your namespace. Try:
<httpModules>
<add name="ViewStateSeoModule" type="ViewStateSeoHelper.ViewStateSeoModule" />
</httpModules>
I've wrote a simple handler:
public class ImageHandler : IHttpHandler, IRequiresSessionState
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
byte[] imgData = context.Session["Data"] as byte[];
if (imgData != null)
{
context.Response.CacheControl = "no-cache";
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.ContentType = "image/png";
context.Response.BinaryWrite(imgData);
context.Response.Flush();
}
}
}
And setup the web.config:
<system.web>
<httpHandlers>
<add verb="GET" path="image.png" type="TestWeb.Handlers.ImageHandler, TestWeb" />
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<add name="Image" verb="GET" path="image.png" type="TestWeb.Handlers.ImageHandler, TestWeb" />
</handlers>
</system.webServer>
If I run the code allowing VS start a new IIS service and open a new tab it reaches the breakpoint on the handler.
If I set don't open a page. Wait for request from an external application it never reaches the handler.
It is not just the breakpoint, no code from the handler executes when I run the website configured on IIS. It only works if I start from VS.
What did I miss when configuring IIS7 ?
I had to switch the Application Pool to Integrated mode, it was using classic.
And I had to remove the handler configuration from <system.web> because it was giving me error 500.23.
HTTP Error 500.23 - Internal Server
Error An ASP.NET setting has been
detected that does not apply in
Integrated managed pipeline mode.
you need to attach to the asp.net worker process. go to tools/attach to process and choose the w3p process.