I am using HttpHandler to retrieve image from database and then use the Handler as ImageUrl in an Image web control on my web page (aspx). The code is shown below. But it does not work and so far I could not figure out why. The issue is HttpHandler is never been hit, if I keep the breakpoint at processrequest() it is never hit
Below is the simple code in Handler
public class ImageHandler : IHttpHandler
{
StaffMemberRepository db = new StaffMemberRepository();
public void ProcessRequest(HttpContext context)
{
int id = Convert.ToInt32(context.Request.QueryString["id"].ToString());
byte[] image = db.GetImage(id);
context.Response.ContentType = "image/jpg";
context.Response.BinaryWrite(image);
}
public bool IsReusable
{
get
{
return false;
}
}
}
and below is the markup in my webpage
asp:Image ID="imgStaff" runat="server" ImageAlign="Middle" ImageUrl="~/Handlers/ImageHandler.ashx?id=2"
Can someone let me know what I am doing wrong here?
Ok I could see my folly now. I just registered my handler in web.config and everything seems ok now.
Related
I have to deal with a WebForms (.Net 4.7) application, that loads server-side prerendered UserControls, by calling a HttpHandler by Javascript/Angular from client-side.
The HttpHandler prerenders the UserControls by this old "hack"
public class MyHandler : IHttpHandler
{
public override void ProcessRequest(HttpContext context)
{
var page = new Page();
var control = page.LoadControl("~/MyFancyUC.ascx");
var form = new HtmlForm { ID = "Form1" };
form.Controls.Add(control);
page.Controls.Add(form);
var stringBuilder = new StringBuilder();
using (StringWriter output = new StringWriter(stringBuilder))
{
HttpContext.Current.Server.Execute(page, output, false);
}
context.Response.Write(stringBuilder.ToString());
}
}
As this style worked several years very well, I can't use async/await style within the UserControls, because I'm getting an error, that the Page needs to have the Async=true attribute.
The UserControls look like this:
public partial class MyFancyUC: UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Page.RegisterAsyncTask(new PageAsyncTask(HandleAsync));
}
private async Task HandleAsync()
{
var data = await GetDataAsync();
BindData(data);
}
}
I already tried to create a simple page class, that sets the Async mode programmatically, and use it in the "MyHandler" HttpHandler, but this doesn't work either.
public class AsyncPage : Page
{
public AsyncPage()
{
this.AsyncMode = true;
}
}
}
When I debug the UserControl, the Page property always shows AsyncMode=false, IsAsync = false.
So I guess, this is caused by HttpServerUtility.Execute() call, that is not capable of running a WebForms page in Async mode.
Does anyone know how to deal with this ?
An asynchronous HTTP handler must implement IHttpAsyncHandler Interface.
An asynchronous Page must have its AsyncMode property set to true.
You have to use IHttpAsyncHandler
I have an ASP:NET web project with a simple HTTPHandler which filters out requests from outside IPs.
The code itself works, but the HTTPHandler prevents my page from loading. No error. No infinite load. There's just a blank page.
If I remove the reference in the config, it loads perfectly fine. It's definitely caused by the HTTPHandler. I've also stepped through the handler and the code is definitely reached, it's just that when the handler is done, the page doesn't load like it should.
Here is the code.
public class SecurityHttpHandler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
string ipAddress = context.Request.UserHostAddress;
if (!IsValidIpAddress(ipAddress))
{
context.Response.StatusCode = 403;
}
}
private bool IsValidIpAddress(string ipAddress)
{
return true; //for the time being, this will always return true
}
public void Dispose() { } //clean
}
The handler exists in another project (i have a reference to the assembly) and the httphandler is registered in my webprojects web.config as such:
<handlers>
<add name="SecurityHttpHandler" verb="*"
path="*Default.aspx"
type="MyProjects.CommonResources.Web.SecurityHttpHandler"
resourceType="Unspecified" />
</handlers>
I'm running IIS 7.5 in integrated mode. .net framework 4.0.
Let me know if I should add more code. I excluded the code from my web-project as the handler itself seems to be the cause early in the asp.net pipeline.
In my asp.net mvc3 application, I have a custom Authorization Attribute as seen below.
public class CustomAuthorize : AuthorizeAttribute
{
public IAccountRepository AccountRepository { get; set; }
public CustomAuthorize()
{
this.AccountRepository = new UserModel();
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
base.AuthorizeCore(httpContext);
return AccountRepository.isEnabled(HttpContext.Current.User.Identity.Name);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
}
}
I have the [CustomAuthorize] tag on my controller actions, and the AuthorizeCore method works fine - it performs the logic I want it to (making sure the account is actually enabled), and then returning as such.
However, the overridden HandleUnauthorizedRequest method, which as I understand it should allow me to control the behaviour of an unauthorized request, is not running at all. I put a breakpoint there, I put code in there, I access my application unauthorized, and the code never runs.
What am I missing?
EDIT: I did some more research and found a few other people who had this problem, but no solution unfortunately.
EDIT2: Sample code
[CustomAuthorize]
public class UserController: Controller
{
public UserController()
{
//do stuff here
}
}
EDIT 3: #Fabio
Here's what I'm trying to do. I have a login page (forms auth) that works fine - it calls my custom login, and then calls my AuthorizeCore override. My application uses a large amount of ajax calls, and my eventual goal is for whenever a user is using the application, and the administrator disables them, making an ajax call after being disabled (though still being logged in) should log them out. However, in order to do this, i want to return a custom response if the user is making an ajax call, and for that, I need to ovverride HandleUnauthorizedRequest. But my Authorize Core (and by extension HandleUnauthorizedRequest) are being ignored if the user is logged in (despite the fact that I have customauthorize tags on all of my controller actions that the ajax is calling).
In short: I want to authorize the user on every request, not just the login request (which seems to be what the membership provider is doing right now)
I ended up changing my approach a fair bit. I implemented individual permissions checking, and then that caused AuthorizeCore to be called every time (and not be cached, which I guess was what was happening before).
Interestingly enough, putting a breakpoint on the HandleUnauthorizedRequest override still doesn't break, but putting it inside the method will. Strange, and threw me off for a bit, but I've solved it now.
Code if anyone is interested:
public class CustomAuthorize : AuthorizeAttribute
{
public string Permissions { get; set; }
private IAccountRepository AccountRepository { get; set; }
private string[] permArray { get; set; }
private string reqStatus { get; set; }
public CustomAuthorize()
{
this.AccountRepository = new UserModel();
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
base.AuthorizeCore(httpContext);
if (Permissions != null) {
permArray = Permissions.Trim().Split(' ');
if (AccountRepository.isEnabled(httpContext.User.Identity.Name)) {
this.reqStatus = "permission";
return AccountRepository.hasPermissions(permArray);
} else {
return false;
}
} else {
return AccountRepository.isEnabled(httpContext.User.Identity.Name);
}
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (this.reqStatus == "permission") {
filterContext.Result = new RedirectResult(MvcApplication.eM.cause("no_permission", "redirect"));
} else {
base.HandleUnauthorizedRequest(filterContext);
}
}
}
And then I decorated the controller with this:
[CustomAuthorize(Permissions="test_perm")]
This may be a stupid answer/question but is AccountRepository.isEnabled method returning false so that the HandleUnauthorizedRequest can be executed?
If it's returning true, then the HandleUnauthorizedRequest method won't be executed.
I have search everywhere for help and its starting to annoy me.
I am creating an Internal Tooling Website which stores Tools and their related information.
My vision is to have a web address (Http://website.local/Tool/ID)
Where ID is the ID of the Tool we want displayed.
My reasoning is then I can extend the functionality of the URL to allow for various other functions.
Currently I use a custom httpHandler which intercepts any URL which is in the 'Tool' Folder.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Tooling_Website.Tool
{
public class ToolHandler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
//The URL that would hit this handler is: http://{website}/Tool/{AN ID eg: http://{website}/Tool/PDINJ000500}
//The idea is that what would be the page name is now the ID of the tool.
//tool is an ASPX Page.
tool tl = new tool();
System.Web.UI.HtmlTextWriter htr = new System.Web.UI.HtmlTextWriter(context.Response.Output);
tl.RenderControl(htr);
htr.Close();
}
}
}
Basically I have a page inside the 'Tool' folder (Tool\tool.aspx) which I want my customer httpHandler to Render into the Response.
But this method doesn't work (It doesn't fail, just doesn't show anything) I can write the raw file to the response but obviously thats not my goal.
Thanks,
Oliver
If you still want to use your custom approach, you can try to do the following in your IHttpHandler derived class:
public void ProcessRequest(HttpContext context)
{
//NOTE: here you should implement your custom mapping
string yourAspxFile = "~/Default.aspx";
//Get compiled type by path
Type type = BuildManager.GetCompiledType(yourAspxFile);
//create instance of the page
Page page = (Page) Activator.CreateInstance(type);
//process request
page.ProcessRequest(context);
}
The HttpForbiddenHandler Class is sealed however I'd like to create a class that behaves like it. Something like this:
public class ForbiddenHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// do the 403 here somehow
}
public bool IsReusable
{
get { return true; }
}
}
How would I cause that 403 redirect?
If you simply want to send the 403 status code:
context.Response.Status = "403 Forbidden";
Also, you might want to write some message to the client:
context.Response.Write("This is very much forbidden!");
If you wish to redirect the user to the 403 custom error page, configured in your web.config or machine.config, you should be able to do it like this:
throw new HttpException(403, "Forbidden");