Keeping a session when using HttpWebRequest
You must use a CookieContainer and keep the instance between calls.
private CookieContainer cookieContainer = new CookieContainer();
public bool isServerOnline()
{
Boolean ret = false;
try
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(VPMacro.MacroUploader.SERVER_URL);
req.CookieContainer = cookieContainer; // <= HERE
req.Method = "HEAD";
req.KeepAlive = false;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
if (resp.StatusCode == HttpStatusCode.OK)
{
// HTTP = 200 - Internet connection available, server online
ret = true;
}
resp.Close();
return ret;
}
catch (WebException we)
{
// Exception - connection not available
Log.e("InternetUtils - isServerOnline - " + we.Status);
return false;
}
}
HttpWebRequest: how get the session id
That depends on the type of server you are sending the request to. For example, if you have an IIS hosted site, it expects a session id inside a cookie named ASP.NET_SessionId
(or on the request string). If you have a Java servlet engine on the other side, it expects a cookie called JSESSIONID
(or a request path parameter jsessionid
).
So it depends. However, setting cookies inside a HttpWebRequest is not difficult. You can use the property CookieContainer
:
CookieContainer cookies = new CookieContainer();
cookies.Add(new Cookie("ASP.NET_SessionId", sessionId));
request.CookieContainer = cookies;
The session identifier you store inside the cookie should have a particular format and again, this depends on the server type at the other end. In ASP.NET by default the class SessionIDManager
is used to produce and validate session ids. This class is hard to reuse because it requires an HttpContext
. However, you could check with Reflector how it generates a session id.
Session.SessionId persistence in requests to ashx
You have to receive session id and pass it to subsequent requests. By default, it will be sent in a cookie, but WebClient doesn't handle cookies. You can use CookieAwareWebClient to solve this:
public class CookieAwareWebClient : WebClient
{
private CookieContainer m_container = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = m_container;
}
return request;
}
}
As long as you're reusing the same instance of web client, you should get the same session id (if the session won't time out of course).
Keeping session alive C#
Browsers by themselves don't do this at all. They only do so if the Web App itself builds in support for it. For example there might be some javascript which makes an AJAX request every 30 seconds or so to send a "keep-session-alive" type request to the server, which would then go and update its state information to reflect that the "most recent activity" was now, and hence prevent a session timeout.
In the example above however, the "client" i.e. html/javascript in the browser, and the "server" would have been written together and thus this type of functionality built in.
If you aren't responsible for the server-side app, and thus can't build the "keep-alive" functionality into it yourself, your best bet would be to either physically go to the web-page, look through all the javascript to try to find possible "keep-alive" code (look for SetTimeout, SetInterval or related methods in any js frameworks they may be using). Of course there might not be any such functionality, in which case your best bet is to simply "refresh" the page you are on (i.e. send the same request again)
Accessing ASP.NET_SessionId on HttpWebResponse C#
After many research, the answer was here
Basically we have to keep the same CookieContainer object reference across all requests. I was extracting some Set-Cookie from the responses and adding them into my requests, but now I don't need to do anything, CookieContainer manages all of it transparently.
Set-Cookie from responses are set on CookieContainer of your request. It's the way they found to resolve possible security issues, so don't lose more time and just keep a reference to your CookieContainer because you will not be able to access session id (and you don't need it).
There's the example of my code now.
var cookieContainer = new CookieContainer();
var httpWebRequest1 = (HttpWebRequest) WebRequest.Create(url);
httpWebRequest1.CookieContainer = cookieContainer;
// do the request and some logic
var httpWebRequest2 = (HttpWebRequest) WebRequest.Create(anotherUrl);
httpWebRequest2.CookieContainer = cookieContainer; // same cookieContainer reference
Everything is working great now, hope it helps someone.
C# WebBrowser Session to WebRequest
Well after a bunch of searching I found a solution. Turns out that if you try to get the cookies from the webbrowser using the way I posted, it will not return the HTTP-Only cookies. Here is a workaround I found, credits to Yoni Couriel!
https://ycouriel.blogspot.com/2010/07/webbrowser-and-httpwebrequest-cookies.html
Related Topics
Show Controls Added Programmatically in Winforms App in Design View
Calculate a Md5 Hash from a String
How to Translate Cultureinfo Language Names
Nsubstitute - Testing for a Specific Linq Expression
How to Get a Type's Alias Through Reflection
Check If List<T> Contains Any of Another List
Retrieve the Respective Coordinates of All Words on the Page with Itextsharp
Visual Studio 2013 Doesn't Discover Unit Tests
The Name '...' Does Not Exist in the Current Context
Escape Button to Close Windows Forms Form in C#
How to Split a String into Multiple Values
Linq to Entities Does Not Recognize the Method 'System.Web.Mvc.Fileresult'
Why How to Not Edit a Method That Contains an Anonymous Method in the Debugger
Using Bindingoperations.Enablecollectionsynchronization
How to 'Await' Raising an Eventhandler Event
No Definition Found for Getactiveobject from System.Runtime.Interopservices.Marshal C#
System.Net.Webexception: the Remote Name Could Not Be Resolved: