Passing data from .aspx file to .ashx file using Session - c#

Actually I am trying to send data from .aspx to .ashx file. I am using Session in .aspx and trying to get value of session in .ashx but it is showing exception:: Object reference not set to an instance of an object.
Here is my code :-
.aspx code
[WebMethod(enableSession:true)]
public static string SetId(string Id)
{
HttpContext.Current.Session["MId"] = Id.ToString(); Console.Write(" ");
string session = HttpContext.Current.Session["MId"].ToString(); // Here I am getting value
//string session = HttpContext.Current.Session["MId"].ToString();
//BatchReadEmails.EmailProperties session = new BatchReadEmails.EmailProperties();
//session.MailId = Id.ToString();
return "Ok";
}
I am getting value in string session.
.ashx code:-
public class ChangeLogHandler : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
HttpRequest request = context.Request;
HttpResponse response = context.Response;
string session = "";
if (context.Session["MId"] != null)
session = context.Session["MId"].ToString();
else
session = "Hello India";
}
}
Here it is showing session = "Hello India"
My Question:-
Is there any way to send data from .aspx to .ashx file??
I checked so many links all are using if for null but I already check in .aspx file it is showing value there but showing null in .ashx file Why?? (For exceptional cases we can use/ write if condition but I already checked string session has value.
Am I missing something?? Thanks
These are the links I already used:-
How to access Session in .ashx file?
Accessing context session variables in c#

In the aspx you're adding Session["MId"]. In the ashx you're reading Session["MailId"].
Make the keys you're using the same. (ie either MId or MailId, but not both).
Would suggest you define a constant to define this value since it's shared, then you can avoid such problems.

Now it's working.I did these changes:-
Instead of
[WebMethod(enableSession:true)]
I put
[WebMethod(EnableSession = true)]
But Both are the correct way.
And I include
async: false in my ajax call. (I think before setting the session it was trying to read it)

This code worked for me well
protected void Button1_Click(object sender, EventArgs e)
{
Session["MailId"] = "somemail#address.com";
Response.Redirect("Handler.ashx");
}
/// Code in ashx
public class Handler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest (HttpContext context)
{
string sessionValue = context.Session["MailId"].ToString();
context.Response.Write(sessionValue);
}
public bool IsReusable {
get {
return false;
}
}
}
I like to know whether u accessing handler from an ajax call or not

Related

Creating an embedded image button in ASP.net?

I need to create a button in ASP.net that I can embed into another web page.
Essentially the button will query a DB server side on page load and then change it's image depending on the return of the query.
Does anyone know the best approach for this? I am not a pro at ASP.net as you can tell. Written in C# preferably.
In this case I would suggest using a IHttpHandler instead of a generic WebForm. https://msdn.microsoft.com/en-us/library/system.web.ihttphandler(v=vs.110).aspx
The handler is more suitable for this request as it will be able to respond quickly and is purpose built for handling specific requests that are not necessarily HTML based. This can be quite simple to wire up to accept a request, query the database and generate an image that you choose. Now you haven't provided much information about where the image comes from but lets look at a simple request.
To begin in a webforms web application select a new GenericHandler which we will name DynamicImage.ashx. Which will build our initial template as below.
public class DynamicImage : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
}
public bool IsReusable
{
get
{
return false;
}
}
}
This template provides the basics to handle our request. When the request arrives the WebServer will execute the ProcessRequest() method passing in the HttpContext as a parameter. From here we can use this to deliver our response.
For argument sakes lets say we are querying the image based on the QueryString parameter username which represents a user in our database. I have included some basic code on your steps to achieve this. (Code commented)
public void ProcessRequest(HttpContext context)
{
//get our username from the query string
var username = context.Request.QueryString["username"];
//clear the response and set the content type headers
context.Response.Clear();
context.Response.ContentType = "image/png";
//if the username is empty then end the response with a 401 not found status code
if (string.IsNullOrWhiteSpace(username))
{
context.Response.StatusCode = 401;
context.Response.End();
return;
}
//do a db query to validate the user. If not valid do a 401 not found
bool isValidUser = new UserManager().IsValidUser(username);
if (!isValidUser)
{
context.Response.StatusCode = 401;
context.Response.End();
return;
}
//get the user image file path from a server directory. If not found end with 401 not found
string filePath = context.Server.MapPath(string.Format("~/App_Data/userimages/{0}.png", username));
if (!System.IO.File.Exists(filePath))
{
context.Response.StatusCode = 401;
context.Response.End();
return;
}
//finish the response by transmitting the file
context.Response.StatusCode = 200;
context.Response.TransmitFile(filePath);
context.Response.Flush();
context.Response.End();
}
To call this handler you can simply set the src of the image to a path similar to /DynamicImage.ashx?username=johndoe.
Now your requirement may be slightly different. For example you may be retrieving the image from the database as a byte[] therefore instead of using the context.Response.TransmitFile() method you may wish to use the context.Response.BinaryWrite() method. This method transmits a byte[] as the response stream.
Finally I would refer you to another post (of mine) that talks about caching these images from a client perspective. This is very helpful if your button will be generated quite frequently. Leverage browser caching in IIS (google pagespeed issue)
It can be something as simple as
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/arrow-down.gif" OnClick="ImageButton1_Click" />
and code behind:
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
// do some DB processing here
ImageButton1.ImageUrl = "~/arrow-up.gif";
}
If I understand what you are asking.
To put it under the page load would look something like:
private void Page_Load()
{
if(!Page.IsPostBack)
{
// perform db processing here
ImageButton.ImageUrl = "~/arrow-up.gif";
}
}
is all that is needed. Setting the ImageUrl line can be put wherever you need it.

Call another aspx page in a different application

I have 2 different system, lets say SystemA and SystemB.
In SystemB, there is page, say calculate.aspx, where it receive certain parameter and will perform some calculation. This page doesn't display and info, and only serves to execute the code behind.
Now i have a page in SystemA, lets say execute.aspx, that will need to call calculate.aspx in SystemB to run the desired calculation. I cannot use redirect, since that will redirect me to the calculation.aspx page on SystemB.
I had tried using HttpWebRequest but it doesn't call to the page. The code is as below:
HttpWebRequest myRequest =
(HttpWebRequest)WebRequest.Create(nUrl + '?' + fn);
myRequest.Method = "GET";
WebResponse response = myRequest.GetResponse();
Does anyone know what is the correct way of doing it? Thanks.
EDIT
Manage to get it done after changing my codes to above. Thank you all.
You can either use a web service which would be the preferred way or use AJAX to send data to the page and get result in response.
I am probably missing something obvious here, but I'm puzzled by the whole part about the data and content which I'm not used to see in a GET Request.
You should, at your choice :
convert your request to POST
remove the part concerning the data
try this
namespace SampleService // this is service
{
public class Service1 : IService1
{
public string GetMessage()
{
return "Hello World";
}
public string GetAddress()
{
return "123 New Street, New York, NY 12345";
}
}
}
protected void Page_Load(object sender, EventArgs e) // calling the service
{
using (ServiceClient<IService1> ServiceClient =
new ServiceClient<IService1>("BasicHttpBinding_IService1"))
{
this.Label1.Text = ServiceClient.Proxy.GetMessage();
//once you have done the build inteli sense
//will automatically gets the new function
this.Label2.Text = ServiceClient.Proxy.GetAddress();
}
}
refer this link
http://www.codeproject.com/Articles/412363/How-to-Use-a-WCF-Service-without-Adding-a-Service
You can create a WebMethod in your application then you call this WebMethod from any other application, you can return Json serializable or XML data from this WebMethod

Getting URL of next page

Is it possible to get the URL of the next page when leaving the current page in C#?
On my current page I would like to capture the url of the next page before the next page loads. I'm not sure where to start for this...or in which method on my page I would place this logic (such as page_load, buttonClick etc.)
I don't think that it's possible to "capture the url of the next page", but you can get the current request as soon as possible. Use Global.asax therefore:
public class Global : System.Web.HttpApplication
{
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext context = base.Context;
HttpResponse response = context.Response;
HttpRequest request = context.Request;
var url = request.RawUrl;
// and many other properties ...
}
}
Assuming you're doing paging through query strings and your current page is:
url.com/default.aspx?page=1
Then getting the next page URL would just be incrementing the page query string, so:
if (!String.IsNullOrempty(Request.QueryString["page"]) {
int nextPageNumber = int.Parse(Request.QueryString["page"] + 1;
string nextPageUrl = String.Format("url.com/default.aspx?page={0}, nextPageNumber);
}
Ideally you would use UriBuilder to reconstruct the domain and not hard code it as I have in the String.Format method. I did this just for brevity.
CodeProject has a project for saving change on close or exiting page which might be helpful to you.

How to access session in aspx that was modified in ashx?

I am using uploadify to upload files, they automatically post to the handler. I then modify the session in the handler that I have setup as a static property in a common class of the website. I then try to access that same session in the aspx page, and the value is null. I have a feeling this is because of cookies, but there needs to be a way to work around this without exposing the sessionid in the url.
ASHX:
public class Upload : IHttpHandler, IReadOnlySessionState, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
...
CMSSession.Current.UploadedFiles.Add(fileName);
}
}
Session Class:
public class CMSSession
{
public static CMSSession Current
{
get
{
CMSSession session = (CMSSession)HttpContext.Current.Session["__CMSSession__"];
if (session == null)
{
session = new CMSSession();
HttpContext.Current.Session["__CMSSession__"] = session;
}
return session;
}
}
public List<string> UploadedFiles { get; set; }
}
ASPX:
if (CMSSession.Current.UploadedFiles != null)
{
...
}
else
{
IT'S ALWAYS NULL
}
Web.Config:
<sessionState mode="InProc" cookieless="false" /> - causes session to always null in aspx when modified in ashx
<sessionState mode="InProc" cookieless="true" /> - session value is not null, but sessionid is exposed in the url
How do I access & modify the current session within the ASHX file WITHOUT changing cookieless to true and then access the session from the ASPX page?
I have tried using HttpContext and using the context passed into the ASHX...nothing works.
same as this question, but there has to be a more secure way: session set in ashx and get that session on aspx
Any ideas?
I found the answer: When the handler is being called from FLASH (like swfupload or uploadify) it does not pass the current sessionid to the handler. The handler then creates a NEW session. To fix this, do the following:
Your UI: JavaScript:
$(Selector).uploadify({
swf: 'uploadify.swf',
uploader: 'Upload.ashx?ASPSESSID=<%=Session.SessionID%>'
});
Add to: Global.asax:
void Application_BeginRequest(object sender, EventArgs e)
{
try
{
string session_param_name = "ASPSESSID";
string session_cookie_name = "ASP.NET_SESSIONID";
string session_value = Request.Form[session_param_name] ?? Request.QueryString[session_param_name];
if (session_value != null) { UpdateCookie(session_cookie_name, session_value); }
}
catch (Exception) { }
}
void UpdateCookie(string cookie_name, string cookie_value)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
if (cookie == null)
{
HttpCookie cookie1 = new HttpCookie(cookie_name, cookie_value);
Response.Cookies.Add(cookie1);
}
else
{
cookie.Value = cookie_value;
HttpContext.Current.Request.Cookies.Set(cookie);
}
}
Taken & simplified for uploadify from:
http://snipplr.com/view/15180/
You may need to use an authid if using formsauthentication:
&AUTHID=<%= Request.Cookies[FormsAuthentication.FormsCookieName] == null ? "" : Request.Cookies[FormsAuthentication.FormsCookieName].Value %>
append that to the uploader parameter in the jQuery.
Then add the following to the global:
try
{
string auth_param_name = "AUTHID";
string auth_cookie_name = FormsAuthentication.FormsCookieName;
string auth_value = Request.Form[auth_param_name] ?? Request.QueryString[auth_param_name];
if (auth_value != null) { UpdateCookie(auth_cookie_name, auth_value); }
}
catch (Exception) { }
You can now access the same session from the handler (even using the static session object I used above in the question) in IE, Chrome, FF, ect.
Context.Session is null.. because connection to HttpHandler has another Context.Session
(debug and try: Context.Session.SessionId in where is the fileInput is different from Context.Session.SessionId in Upload.ashx)!
I suggest a workaround: pass a reference to the elements you need in the second session ( in my sample i pass the original SessionId using sessionId variable)
....
var sessionId = "<%=Context.Session.SessionID%>";
var theString = "other param,if needed";
$(document).ready(function () {
$('#fileInput').uploadify({
'uploader': '<%=ResolveUrl("~/uploadify/uploadify.swf")%>',
'script': '<%=ResolveUrl("~/Upload.ashx")%>',
'scriptData': { 'sessionId': sessionId, 'foo': theString },
'cancelImg': '<%=ResolveUrl("~/uploadify/cancel.png")%>',
....
and use this items in .ashx file.
public void ProcessRequest(HttpContext context)
{
try
{
HttpPostedFile file = context.Request.Files["Filedata"];
string sessionId = context.Request["sessionId"].ToString();
....
If you need to share complex elements use Context.Application instead of Context.Session, using original SessionID: Context.Application["SharedElement"+SessionID]

Accessing the protected area of an asp.net website via a System.Net.WebClient

I have a website running asp.net 2.0 with url authentication. There is a protected region of the website that requires users to log in to gain access to protected files. Is it possible to do the same thing using a System.Net.WebClient object to download a file in the protected area?
If you try to manually type in the url to a protected file, resource, page, etc it forwards you to the login page. I also get the html for the login page inside of "protectedFile.zip" whenever I execute the code below.
public void test()
{
try
{
using (var client = new CookieAwareWebClient())
{
//Not sure which name values to include, so I used what was in the post output in Firefox's firebug.
var values = new NameValueCollection
{
{ "ctl00$ContentPlaceHolder1$Login1$UserName", "testUsername" },
{ "ctl00$ContentPlaceHolder1$Login1$Password", "testPassword" }
};
retValue = client.UploadValues("www.test.com/login.aspx", values);
//retValue contains the login page?
Console.WriteLine(ASCIIEncoding.ASCII.GetString(retValue));
// If the previous call succeeded we now have a valid authentication cookie??
client.DownloadFile("www.test.com/protected/protectedFile.zip", "protectedFile.zip");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
Console.WriteLine(ASCIIEncoding.ASCII.GetString(retValue));
}
}
public class CookieAwareWebClient : WebClient
{
public CookieAwareWebClient()
{
CookieContainer = new CookieContainer();
}
public CookieContainer CookieContainer { get; private set; }
protected override WebRequest GetWebRequest(Uri address)
{
var request = (HttpWebRequest)base.GetWebRequest(address);
request.CookieContainer = CookieContainer;
return request;
}
}
I have looked at the following related questions but none of them have a final solution that I can understand.
asp.net Download files from protected server
How do I authenticate a WebClient request?
C# WebClient Log onto Website
WebClient accessing page with credentials
Can't login into asp.net website with WebClient
Any help would be appreciated!
If you are trying to "spoof" an ASP.Net Web Forms Postback, you will run into issues that will prevent you from doing so. You have to deal with VIEWSTATE and EVENTVALIDATION
The __EVENTVALIDATION hidden field is a security measure new to ASP.NET 2.0. The feature prevents unauthorized requests sent by potentially malicious users from the client. To ensure that each and every postback and callback event originates from the expected user interface elements, the page adds an extra layer of validation on events.

Categories

Resources