I want know which page and which URL has calling my Handler .ashx, is that possible?
I need this because, I have an Handler who calls and convert images from database, but some of my URLS of images are not passing the right query argument (they don't exist in database) and I need what is the URL who call to see what is the image for that arguments.
why not just use
context.Request.UrlReferrer?
A quick solution to your immediate question is to call (in C#)
Inside your public void ProcessRequest(HttpContext context){} method, add the following 3 lines.
IServiceProvider provider = (IServiceProvider)context;
HttpWorkerRequest worker = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
String referer = worker.GetKnownRequestHeader(HttpWorkerRequest.HeaderReferer);
This will give you the URL of the page that called your handler.
To go further though, you should ideally be implementing error handling to handle any missing images.
Related
I have a global.asax in which I define some variables that I want to be available throughout the application, such as a class to handle certain database requests. In an aspx page, I can access these variables/objects using for example in Visual Basic:
dim dataMan as clsData = application.get("dataGofer")
My question: is it possible to call this from a generic handler (.ashx file)? If so, can you please show me a code snippet? Thanks!
You have Context parameter of ProcessRequest method through which you can access the page objects.
Dim value=context.Application.Get("key")
I have a WebMethod which accepts one parameter.
When I send a request to the webmethod without any parameters everything works well but when I supply a parameter to the same method, it returns entire site instead of a string.
The page parameter changes nothing except the content of the list.
List is just ListView which displays list of strings.
When I use URLRewriting the URL is different in instances that I supply a parameter from instances when I do not.
Can anybody help me with this problem?
My WebMethod:
[WebMethod]
public static string GetResult(int id)
{
return "Hooray";
}
My web method call:
PageMethods.GetResult(docId,
function onSuccess(list) {
$(element).parent().siblings().filter(":first").append(list);
});
URL without parameter:
www.mywebsite.com/items is rewritten to www.mywebsite.com/items.aspx
URL with parameter:
www.mywebsite.com/items/1 is rewritten to www.mywebsite.com/items.aspx?id=1
Here's a discussion about your same issue that might shed some light on the situation. Basically, what it says is that it's not working because the handler that deals with PageMethods is looking for {pagename.aspx}/{methodname}, and your url rewriting is causing it to not recognize you are calling a page method.
One suggestion on that page was to add the following in your javascript code somewhere after the auto-generated call of the same signature:
PageMethods.set_path('/items.aspx');
This will make it call your page method using the real url instead of the rewritten one.
i want a handler to redirect to a web-forms page, pre-filling in the values of some controls on the form.
i tried setting my current Request.Form data:
if (theyWantToDoSomething)
{
//pre-fill form values
context.Request.Form["TextBox1"] = "test";
context.Request.Form["ComboBox1"] = "test 2";
context.Request.Form["TextBox2"] = GetTheTextForTheThing();
//tell the client to go there
context.Response.Redirect("~/SomeWebForm.aspx");
return;
}
But i get an exception that Form values are read only.
What would be a way to send the client to another page, pre-filling form data?
Answer
i used the Session state to store values. It's important to note that by default a Handler doesn't have access to Session (the Session object will be null). You have to tell IIS to give you the Session object by adding the IRequiresSessionState marker interface to your handler class:
public class Handler : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
...
if (theyWantToDoSomething)
{
//pre-fill form values
context.Session["thing1"] = "test";
context.Session["thing2"] = "test 2";
context.Session["thing3"] = GetTheTextForTheThing();
//tell the client to go there
context.Response.Redirect("~/SomeWebForm.aspx");
return; //not strictly needed, since Redirect ends processing
}
...
}
}
You can only populate your Response, the Request is input data and is indeed read-only.
If you are using ASP.NET, there are a variety of ways you could accomplish what you need:
The best way would probably be to pass the data you need to be pre-populated to SomeWebForm.aspx via the Session object, and on that pages Load method, populate your form. Keep in mind that when you do Response.Redirect, a 302 response is sent to the client with the URL the client should redirect to. The process is transparent to the user...but there is a full round trip involved.
Another alternative to populating the users Session would be to add GET parameters via a query string to the redirect to SomeWebForm.aspx.
If you need to transfer processing to the SomeWebForm.aspx page without round tripping, you could use Server.Transfer. This will transfer execution from the current page to the page you choose...however, this can cause some odd behavior on the client end because the URL does not update. As far as the user is concerned, it will still appear as though they are on the same page they started on.
A few ideas that might get you started:
Pass the values in the query string
Store the values in the session state or in a seperate cookie
Store the values in HttpContext.Items and use Server.Transfer instead of Response.Redirect
Another approach that hasn't been mentioned yet is using Server.Transfer makes it possible to use the Page.PreviousPage property, allowing access to the controls on the page that transferred control.
As jrista mentioned though, using Transfer doesn't update the URL shown to the user, which may or may not be an issue. For example, a user can't precisely bookmark a page they got transferred to since the URL will be that of the original transferring page.
I need to get a value from an API I made with ASHX and normally it is called from javascript but I need to call it right in ASP.NET I figured this shouldn't be a problem but I'm not sure the syntax.
Well you have a couple options
You can refactor the code in your ASHX to be in a shared library so you can access the methods directly and so can the handler.
You can instantiate the handler and invoke the members if they aren't private.
You can create a webrequest to the handler and handle the response.
These are just a few of the easy ways.
I personally like the first method because it promotes code reuse, but depending on scenario you can do what you like.
Edit to provide answers for question in comment.
Essentially Yes... Instead of having a bunch of code in your handler you make a class called something meaningful to you contextually. Inside that class you place the logic that was in your handler. Then from your handler you can create an instance or call a static version of the class (depending on how you implemented it) passing it the HttpContext object or whatever is required for that logic to run correctly. Do the same thing in your ASPX page. You can now call into an object that contains the logic from anywhere in your app instead of having it reside in the handler alone.
EX:
Public Class MyCommonLogic
Public Shared Function ReturnSomethingCommon(context As HttpContext) As String
Return "Hello World!"
End Function
End Class
Then from the handler or the aspx page..
Dim something As String = MyCommonLogic.ReturnSomethingCommon(...)
I made the function static, but that is just an example of course I would implement it however would make more sense in your scenario.
Changed code to VB sorry about that.
If the ASHX is on the same server especially if its within the same web app, you should refactor your logic out of the ashx into a common class that both the aspx and ashx can call.
Otherwise you can look at using: System.Net.WebClient
All literature I see on creating custom handlers deals with associating an extension with a handler, e.g. if I wanted a handler for Ajax requests, I could implement the IHttpHandler interface in an AjaxHandler class.
Now, to have individual instances of AjaxHandlers, e.g. DocAjaxHander, PersonAjaxHandler etc. how would I derive the base AJAX handling of my AjaxHandler class without registering each individual *.ajax page?
It sounds like your assuming 1 HttpHandler = 1 Page or 1 Control, but as I understand, 1 HttpHandler can handle all pages of a certain file extension.
Your Question is not very clear, and your reponse to another answerer makes no sense...
"In fact, it seemed, to me, a lot like I was asking Http handlers, using a .ajax handler as an example."
But I shall assume you are thinking "DocAjaxHander" and "PersonAjaxHandler" should each be created for a "DocAjaxControl" and "PersonAjaxControl" respectively. I dont think that would be neccesary, 1 handler should be able to handle all your ajax requests if you choose to do it that way, but it doesn't feel like the most intuitive solution to me (using HttpHandlers), anyway, onto the details...
every IHttpHandler object needs to implement :
public void ProcessRequest(HttpContext context)
which allows :
context.Response.Write("Your JSON Response in here");
but at the level of 'ProcessRequest()', you have no access to the instance of the control which created the ajax call, or to the 'System.Web.UI.Page' object that holds the control, or anything.
context.Request
to the rescue! With the Request object above you can read QueryStrings, Sessions, an you can determine the path of the original HttpRequest (i.e. PersonAjaxObject may make an ajax call to 'myPersonobjPage.ajax' for its JSON data, but the '.ajax' extention lands the request at your custom http handler and it's ProcessRequest method.)
If I was you, and I was going to use an HttpHandler for my ajax calls, I'd use query string data to provide enough info for my handler to know 'what type of object am I responding too' as well as 'what data is that object requesting'.
Hope that helps.
You can automatically handle AJAX request in a number of ways. Here's how to do it with a web service:
http://www.asp.net/AJAX/Documentation/Live/Tutorials/ConsumingWebServicesWithAJAXTutorial.aspx
Well, one way to do it would be via query string params...