I'm developing a website in asp.net and c# which needs to catch if the user isn't connected when they press a button. So basically, if the user is connected, it will load up the GetList function, and if not a message will appear.
Code so far is...
protected void btnAlphabetical_Click(object sender, EventArgs e)
{
Session["Online"] = 0;
CheckConnect();
if ((int)Session["Online"] == 1) { GetList(); }
if ((int)Session["Online"] == 0) { Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "alertMessage", "alert('You are currently offline')", true); }
}
protected void CheckConnect()
{
System.Uri Url = new System.Uri("http://www.mywebsite.com/apicture.jpg?" + DateTime.Now);
System.Net.WebRequest WebReq;
System.Net.WebResponse Resp;
WebReq = System.Net.WebRequest.Create(Url);
try
{
Resp = WebReq.GetResponse();
Resp.Close();
WebReq = null;
Session["Online"] = 1;
}
catch
{
WebReq = null;
Session["Online"] = 0;
}
}
Basically, we set our Online session value to 0 and call the CheckConnect function. This gets a jpg that's already on the website and, if it can be loaded, sets our Online variable to 1. If it can't find it, it sets it to 0. When control returns to the main function (a button), we progress depending on what Online is - 1 or 0.
Trouble is, and I'm unsure whether this is more to do with my system settings than anything:
when we're online and getting something that DOES exist it works fine and GetList is fired
when we're online and getting something that DOESN'T exist (an invalid URL) it works fine and our message appears (GetList isn't fired)
HOWEVER, when we're offline and fire it, my browser (IE8) just goes to the regular "diagnose connection settings" screen
Is this my code, or part of IE8 in general? I can't use another browser as it's the one my company uses.
Thanks.
EDIT - the general purpose of this is to be used on mobile devices. The user will load up the page and make changes, then use the button. If connection is lost between the page being loaded and the user pressing the button, I don't want the user to lose their changes.
Related
I am using a Payment Gateway Which will send the response to the Success page. Their documentation indicates they are sending response as POST parameters. I tried to Read these parameters but i am not able to get the parameters. I had sent a mail to support and they said they will send the data from their server to our server prior redirection to success page. I implemented my code in success page. Where I should Implement and how to save these values in my code for further use.
My code is Here
protected void Page_Load(object sender, EventArgs e)
{
/// store all the posted form variables in an object to use later
response notifyresponse = new response();
notifyresponse.CreditVouchersTransactionId = Request["CreditVouchersTransactionId"];
notifyresponse.MerchantName = GetFormVariableOrNull(Request["MerchantName"]);
notifyresponse.AmountToPay = GetFormVariableOrNull(Request["AmountToPay"]);
notifyresponse.PaymentOKURL = GetFormVariableOrNull(Request["PaymentOKURL"]);
notifyresponse.OrderId = GetFormVariableOrNull(Request["OrderId"]);
notifyresponse.AmountCurrency = GetFormVariableOrNull(Request["AmountCurrency"]);
notifyresponse.PaymentType = GetFormVariableOrNull(Request["AmountType"]);
notifyresponse.PaymentStatus = GetFormVariableOrNull(Request["PaymentStatus"]);
string[] keys = Request.Form.AllKeys;
for (int i = 0; i < keys.Length; i++)
{
Session["amountpay"]=keys[i] ;
}
}
protected string GetFormVariableOrNull(object formvariable)
{
if (formvariable != null)
{
try
{
return formvariable.ToString();
}
catch (Exception ex)
{
/// log the exception in file or DB
Console.WriteLine(ex.Message);/// just for an example
return null;
}
}
else
return null;
}
Thanks
Use Fiddler, it will show you all the traffic going back forth and provide a more accurate picture as to whats going on between those transactions
https://www.telerik.com/download/fiddler
Edit
A HTTP message can be composed of two part, first is the header, the other is the body.
When making a GET request to a server, it won't contain a body. A POST request on the other hand, will. There are line breaks in between the headers and the body... I've demonstrated a POST request below
hi there :) il get right to it.
Problem :
when i try to instanciate LiveConnectClient and then try to access the event : GetCompleted
which supose to be in the LiveConnectClient is not showing and on all the examples i been looking at even those on here are using it. this is not the only class this is happening on it is also happening on LiveAuthClient as well no events even the post on the net says there should be.
i tried to reinstall Vs2012 and sdk wp8 and live sdk from scratch but have not solved it
for refrence i using this example to see if i can it to work :
//event triggered when Skydrive sign in status is changed
private void btnSignIn_SessionChanged(object sender, Microsoft.Live.Controls.LiveConnectSessionChangedEventArgs e)
{
//if the user is signed in
if (e.Status == LiveConnectSessionStatus.Connected)
{
session = e.Session;
client = new LiveConnectClient(e.Session);
infoTextBlock.Text = "Accessing SkyDrive...";
//get the folders in their skydrive
client.GetCompleted +=
new EventHandler<LiveOperationCompletedEventArgs>(btnSignin_GetCompleted);
client.GetAsync("me/skydrive/files?filter=folders,albums");
}
//otherwise the user isn't signed in
else
{
infoTextBlock.Text = "Not signed in.";
client = null;
}
}
i got no luck solving it and running out of ideas. So im hoping one of u boys out there can shed some light on it or lend a hand with dew wise words :)
thanks in advance. and i do apologies if this is to long a post.
regards jens
Indeed, it seems like those events have been removed in the latest versions of the SDK. You don't need them though, thanks to the async/await keywords. First, mark your method as async, then call the GetAsync method with the await keyword. And place afterward the code you would normally put in the GetCompleted event:
private async void btnSignIn_SessionChanged(object sender, Microsoft.Live.Controls.LiveConnectSessionChangedEventArgs e)
{
//if the user is signed in
if (e.Status == LiveConnectSessionStatus.Connected)
{
session = e.Session;
client = new LiveConnectClient(e.Session);
infoTextBlock.Text = "Accessing SkyDrive...";
//get the folders in their skydrive
var result = await client.GetAsync("me/skydrive/files?filter=folders,albums");
// Do here what you would normally do in btnSignin_GetCompleted
}
//otherwise the user isn't signed in
else
{
infoTextBlock.Text = "Not signed in.";
client = null;
}
}
I am trying to programmatically get my site status from IIS to see if it's stopped, but I kept getting the following error,
The object identifier does not represent a valid object. (Exception from HRESULT: 0x800710D8)
The application is using ServerManager Site class to access the site status. Here is the code,
//This is fine, gets back the site
var serverManager = new Microsoft.Web.Administration.ServerManager(ConfigPath);
var site = serverManager.Sites.FirstOrDefault(x => x.Id == 5);
if (site == null) return;
var appPoolName = site.Applications["/"].ApplicationPoolName;
//error!
var state = site.State;
I've test with static site to isolate the issue, making sure that the site is up and running, all configuration are valid, point to the valid application pool...etc.
Let me know if you need more details. Is it the COM thing?
I figured out where the problem is. Basically, there are two parts to the Server manager, the first part of the server manager allows you to read site details from configuration file, which is what I've been doing above. The problem with that is you will only able get the information that's in file and site state is not part of it.
The second part of the Server Manager allows you to connect to the IIS directly and it does this by interacting with the COM element. So what I should be doing is this:
ServerManager manager= ServerManager.OpenRemote("testserver");
var site = manager.Sites.First();
var status = site.State.ToString() ;
I had a similar problem but mine was caused by the delay needed to activate the changes from the call to CommitChanges on the ServerManager object. I found the answer I needed here:
ServerManager CommitChanges makes changes with a slight delay
It seems like polling is required to get consistent results. Something similar to this solved my problem (I got the exception when accessing a newly added application pool):
...
create new application pool
...
sman.CommitChanges();
int i = 0;
const int max = 10;
do
{
i++;
try
{
if (ObjectState.Stopped == pool.State)
{
write_log("Pool was stopped, starting: " + pool.Name);
pool.Start();
}
sman.CommitChanges();
break;
}
catch (System.Runtime.InteropServices.COMException e)
{
if (i < max)
{
write_log("Waiting for IIS to activate new config...");
Thread.Sleep(1000);
}
else
{
throw new Exception(
"CommitChanges timed out efter " + max + " attempts.",
e);
}
}
} while (true);
...
As per this article, I've extended the System.Windows.Forms.WebBrowser class to implement custom error-handling. Mostly, it works.
The problem comes when the browser gets a "401 Unauthorized" response. That kind of response causes the WebBrowser control to display the standard Username / Password dialog. The NavigateError event isn't fired until that dialog is cancelled.
So what can I do to capture the 401 response and handle it in my own custom way?
I assumed there would be something I could do, such as that which I do to capture the NavigateError event, and handle those my own way but I haven't seen anything.
Edit: Solution Found!
The important steps are:
1. The WebBrowser control must first be navigated to a non-secure page ("about:blank" is the typical URL used) in order to avoid KB 320153
2. The host for the WebBrowser control must implement IOleClientSite, IServiceProvider, and IAuthenticate.
3. IServiceProvider.QueryService must handle the IAuthenticate service request with the IAuthenticate implementation, all other service requests can be handled with the INET_E_DEFAULT_ACTION response.
4. IAuthenticate.Authenticate is your custom authentication handler.
implement IAuthenticate and IAuthenticateEx on your webbrowser host. Basically, your IOleClientSite implementation needs to responde IServiceProvider.QueryService, and return an IAuthenticate(Ex) interface (not the managed one, the native one returned from Marshal.GetComInterfaceForObject) when the service is IID_IAuthenticate. For unrecognized service requests, QueryService should return INET_E_DEFAULT_ACTION.
I don't think the WPF webbrowser has extension points for its IOleClientSite implementation. You can try host a Winform webbrowser class which has an overriden CreateWebBrowserSiteBase virtual method that provides the IAuthenticate(Ex) implementation, or write a webbrowser wrapper from the ground up.
This may not work in a Citrix session.
I found that to be able to navigate the site without the Authorization Header getting lost or removed I had to do the following otherwise for each new page the user was prompted again. This solution also does not require the user:password#site syntax to be enabled.
private bool _redirected = false;
private const string BaseUrl = #"http://mySite";
private void Navigate()
{
var helpUrl = BaseUrl;
var authHeader = GetAuthHeader();
_docWindow.Browser.Navigate(helpUrl, string.Empty, null, authHeader);
_docWindow.Browser.Navigating += Browser_Navigating;
}
private string GetAuthHeader()
{
byte[] authData = UnicodeEncoding.UTF8.GetBytes(_userName + ":" + _password);
string authHeader = "Authorization: Basic " + Convert.ToBase64String(authData);
return authHeader;
}
void Browser_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
{
if (_redirected)
{
_redirected = false;
return;
}
var newPage = BaseUrl + e.Uri.AbsolutePath;
e.Cancel = true;
_redirected = true;
_docWindow.Browser.Navigate(newPage, string.Empty, null, GetAuthHeader());
}
Another question about Web proxy.
Here is my code:
IWebProxy Proxya = System.Net.WebRequest.GetSystemWebProxy();
Proxya.Credentials = CredentialCache.DefaultNetworkCredentials;
HttpWebRequest rqst = (HttpWebRequest)WebRequest.Create(targetServer);
rqst.Proxy = Proxya;
rqst.Timeout = 5000;
try
{
rqst.GetResponse();
}
catch(WebException wex)
{
connectErrMsg = wex.Message;
proxyworks = false;
}
This code hangs the first time it is called for a minute of two. After that on successive calls it works sometimes, but not others. It also never hits the catch block.
Now the weird part. If I add a MessageBox.Show(msg) call in the first section of code before the GetResponse() call this all will work every time without hanging. Here is an example:
try
{
// ========Here is where I make the call and get the response========
System.Windows.Forms.MessageBox.Show("Getting Response");
// ========This makes the whole thing work every time========
rqst.GetResponse();
}
catch(WebException wex)
{
connectErrMsg = wex.Message;
proxyworks = false;
}
I'm baffled about why it is behaving this way. I don't know if the timeout is not working (it's in milliseconds, not seconds, so should timeout after 5 seconds, right?...) or what is going on. The most confusing this is that the message box call makes it all work without hanging.
So any help and suggestions on what is happening is appreciated. These are the kind of bugs that drive me absolutely out of my mind.
EDIT and CORRECTION:
OK, so I've been testing this and the problem is caused when I try to download data from the URI that I am getting a response from. I am testing the connectivity using the GetResponse() method with a WebRequest, but am downloading the data with a WebClient. Here is the code for that:
public void LoadUpdateDataFromNet(string url, IWebProxy wProxy)
{
//Create web client
System.Net.WebClient webClnt = new System.Net.WebClient();
//set the proxy settings
webClnt.Proxy = wProxy;
webClnt.Credentials = wProxy.Credentials;
byte[] tempBytes;
//download the data and put it into a stream for reading
try
{
tempBytes = webClnt.DownloadData(url); // <--HERE IS WHERE IT HANGS
}
catch (WebException wex)
{
MessageBox.Show("NEW ERROR: " + wex.Message);
return;
}
//Code here that uses the downloaded data
}
The WebRequest and WebClient are both accessing the same URL which is a web path to an XML file and the proxy is the same one created in the method at the top of this post. I am testing to see if the created IWebProxy is valid for the specified path and file and then downloading the file.
The first piece of code I put above and this code using the WebClient are in separate classes and are called at different times, yet using a message box in the first bit of code still makes the whole thing run fine, which confuses me. Not sure what all is happening here or why message boxes and running/debugging in Visual Studio makes the program run OK. Suggestions?
So, I figured out the answer to the problem. The timeout for the we request is still 5 sec, but for some reason if it is not closed explicitly it makes consecutive web requests hang. Here is the code now:
IWebProxy Proxya = System.Net.WebRequest.GetSystemWebProxy();
//to get default proxy settings
Proxya.Credentials = CredentialCache.DefaultNetworkCredentials;
Uri targetserver = new Uri(targetAddress);
Uri proxyserver = Proxya.GetProxy(targetserver);
HttpWebRequest rqst = (HttpWebRequest)WebRequest.Create(targetserver);
rqst.Proxy = Proxya;
rqst.Timeout = 5000;
try
{
//Get response to check for valid proxy and then close it
WebResponse wResp = rqst.GetResponse();
//===================================================================
wResp.Close(); //HERE WAS THE PROBLEM. ADDING THIS CALL MAKES IT WORK
//===================================================================
}
catch(WebException wex)
{
connectErrMsg = wex.Message;
proxyworks = false;
}
Still not sure exactly how calling the message box was making everything work, but it doesn't really matter at this point. The whole thing works like a charm.