Can not update textbox using with DownloadProgressChangedEventHandler - asp.net

I am trying to download a file from an url using WebClient and multi thread. I am trying to get ProgressPercentage while downloading file and I am trying to do that with DownloadProgressChanged but when I try to print percentage to with debug.WriteLine everything is okey. But when I want to change my textbox.text its not working. I want to update my textbox while downloading.
With this one I am calling a function.
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressChangedEventHandler);
This is the content of function:
public void DownloadProgressChangedEventHandler(object sender, DownloadProgressChangedEventArgs e)
{
//Debug.WriteLine works normal.
Debug.WriteLine(e.ProgressPercentage);
TextBox1.Text = "Progress:" +e.ProgressPercentage.ToString();
progressBarDownload3.Style.Add("width",e.ProgressPercentage.ToString()+"%");
}

Technically, While the solution above could be useful if you are working on a desktop or mobile application but if you are using ASP.NET Server-Side Component and your server is downloading something for you while the page is being posted back, then there is no way the front end can be updated before the download is completed and response is sent back to the requesting client. This is the whole sort of point, every request that goes to the server will only return once the response is completed/interrupted, it cannot come back just to report the progress and then go back to the point where it was running.
If you want to display the progress of the file that is being downloaded then you should go for a client side (JavaScript/jQuery) based solutions.
If you strictly want to download the file with C# code then try checking out for SignalR library, it could be helpful for you in reporting the changes in the backend to the frontend but at the same time, it would be complicated to manage just to report download progress.
Alternatively, you can throw the browser to the download url and it would download the file automatically for the client and the browser's default download progress bar would be visible to the clients downloading the file.
No matter what, you cannot download files from the server and report each byte that gets downloaded to the front end using C# and ASP.NET WebForms/MVC. Unless you include jquery/javascript in the action.

Related

Tabs opened via Hyperlinks in Excel/Word not recognizing session cookies

I have an ASP.Net application with authentication using Cookie session variables. Once the user logs in, they can open new browser tabs for the same application and these are logged in automatically as the session cookie is present.
Clicking on a hyperlink on another web page pointing to a specific page within the application also works fine - there is no login required as the user is already logged in.
However, when a hyperlink to the application is in a Word/Excel document, this link does not open the page directly and gets bounced to the Login page instead. If I copy/paste the Url from Word/Excel and paste it in the Url bar on the browser, it works fine.
Any explanation to this behaviour? Does the browser open a isolated session when a link is clicked in Word/Excel?
Edit: It also seems Word/Excel perform their own check before opening a browser tab. If I use a non-existent link, it doesn't open the tab.
We ran into this at my place of work a while back, and found that like you mentioned, MS Office applications indeed do some mysterious stuff behind the scenes. Details on what it actually does are in this article: https://learn.microsoft.com/en-us/office/troubleshoot/office-suite-issues/click-hyperlink-to-sso-website
Toward the bottom of that article, they suggest a workaround involving a meta refresh, which is what worked for us. In our case, we added a method to our request pipeline that checks for a Microsoft product in the User-Agent header. If found, it sends a meta refresh that triggers the browser to use an existing session rather than trying to start a new session (which is why you're being redirected to a logon page). Here's more or less the code:
private static string MSUserAgentsRegex = #"[^\w](Word|Excel|PowerPoint|ms-office)([^\w]|\z)";
protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
if (!Request.IsAuthenticated)
{
if (System.Text.RegularExpressions.Regex.IsMatch(Request.UserAgent, MSUserAgentsRegex))
{
Response.Write("<html><head><meta http-equiv='refresh' content='0'/></head><body></body></html>");
Response.End();
}
}
}

What actually happens when you Stop Debugging?

I have 2 ASP.NET applications. 1 is in VB, 1 is in C#.
When the user logins with certain credentials in the VB app should be re-routed to the C# app. Likewise, certain credentials for the C# app gets re-routed to the VB app, and vice versa.
VB -> C# works. This functionality was written by a third party. (The C# application is essentially just a rewrite of our VB app, but more modern. However, the entire package isn't being rewritten).
I've tried to reverse the code so that the C# app will call a stored procedure in the DB to create a token, redirect the browser to the VB app which calls a procedure to get that token and set some Session variables.
I don't have it quite working right, one of the major issues is that that the Browser simply does not navigate off the C# login page to the VB page. If I run Profiler on the DB however, I can see that "load token" stored procedure being called. That must mean that the code is getting executed, but the browser isn't redirecting correctly, right?
More importantly, and the reason I'm posting this question however is I don't understand what's actually happening when I stop debugging my app. I set a break point immediately following the call to create that token in the DB. So I run my application, log in, trigger the break point and I can see the good data in the DB. If I immediately Stop Debugging, the load token procedure still gets called. How!?
Here's the code;
In my LoginController:
public ActionResult ValidateUser(objLogin)
{
var ds = LoginData.ValidateUser(objLogin);
string url = "someUrl/" + ds.Tables["Key"].Rows[0][0].ToString();
System.Web.HttpContext.Current.Response.Redirect(url, true);
return Json(objLogin, JsonRequestBehavior.AllowGet);
}
That redirect points to the landing page in the VB application, which parses out the key from the URL and passes that as a parameter to another DB SP... However, the browser never navigates off my login page regardless if I stop debugging or not.
Frankly, I'm not entirely sure what the return statement does; if I try to step into it it just continues on as if I hit "Play". Application resumes control and just chills at the login page. It's part of the third-party rewrite. The VB app was very old, pretty unstructured. New C# rewrite uses MVC. I'm familiar with the principles but I'm not an expert on it, especially not in .NET.
And in LoginData
public DataSet ValidateUser(Login objLogin)
{
DataSet dsData;
using (SqlCommand sqlCommand = new SqlCommand("Validate_User_Main")
{
// execute this procedure; assign results to dsData
}
string authKey = GetAuthKey(dsData.userId);
DataTable dtTemp = new DataTable("key"); //putting break point here after the key gets created but before the redirect is called in LoginController.ValidateUser
dtTemp.Columns.Add("Key");
DataDrow drTemp = dtTemp.NewRow();
drTemp[0] = authkey;
dtTemp.Rows.Add(drTemp);
dsData.Tables.Add(dtTemp);
return dsData;
}
Edit: If I close my browser window while still waiting on my breakpoint, then stop debugging that "load token" call isn't utilized. If I simply Stop Debugging but leave my browser open, it gets called. So it must be redirecting "behind the scenes", right? I don't understand...
When you stop debugging the debugger is detached. This simply means that it stops tracking the running code. The code keeps running, as you have seen, but know you can't set breakpoints, watch variable etc.

Call an asp.net page (ashx handler) from a different asp.net page

I have a admin page in asp.net that adds data to a database. This database is available as a JSON string to external websites, however, since it's a lot of data, the external websites cache this data locally.
I want to be able to ping the external websites to let them know the data has changed so they can referesh their cache. I figure I can setup an ASHX handler that receives a parameter telling them what data has changed, so they can both delete that data and refresh it.
The only part I'm not sure about is the best way to call this external page from my admin page. Do I just do a regular WebRequest and discard the result? or is there a simpler way to call a page from code when you don't need the response?
Basically I just want to "ping" this page, so it knows it needs to refresh.
thanks!
If you just want to call the remote page, you can use the WebRequest class.
http://msdn.microsoft.com/en-us/library/debx8sh9.aspx
WebRequest request = WebRequest.Create("http://my.domain.ext/page.ashx");
using(WebResponse response = request.GetResponse()) {
response.Close();
}
If you want to do more advanced stuff a webservice would be more appropriate.
You could have a flag set up in the database. That would turn this into a much simpler task.
If no alternative exists you can use the WebClient class:
using (var wc = new WebClient())
{
wc.DownloadString(address);
}

Security considerations for an ASP.Net web application that will be used on a public computer or kiosk

I have an application that can be used without authentication on computers in public locations. It's a simple four page application that allows users to apply for a marriage license. Some offices will have a public computer kiosk where applicants can fill out their own information before proceeding to the clerk. They can also do so at home before visiting the office. What considerations should I take to make sure that a user cannot get access to the previous user's input? Some form data will contain sensitive info such as DOB, SSN and Mother's Maiden Name.
1. Disable AutoComplete
So far, I've set autocomplete=false in my Master page form tag.
<form id="frmMain" runat="server" autocomplete="false">
2. Disable Page Caching
I've also been able to disable page caching in IE and FF, but cannot do so in Safari and Chrome. Anybody know the trick? Hitting the back button still shows the form-filled data in Safari and Chrome.
// Disables page-caching in IE
Response.Cache.SetAllowResponseInBrowserHistory(false);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
Response.Expires = 0;
// HACK: fixes Firefoxes cache issue
Response.AddHeader("ETag", new Random().Next(1111111, 9999999).ToString());
3. Manage the session
I've also implemented a timer on each page that will kill the session after n number of minutes. The session holds the current application ID with which the pages use to load previously entered data. They can get more time by clicking a button. When the timer is up, it redirects back to the main page where I kill the session in Page_Load. I also redirect to this page when the users click the "Finished/Submit" button. Once the session is killed, navigating to the pages by URL will never load the previous application. It'll be treated as a new one.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
Session.Abandon();
}
4. what else should I do?
Your awesome suggestions/tips here
Since this is a Kiosk app, you'd want to make sure that the browser is configured to honor requests to not cache anything.
Last time I researched the effectiveness of server side no-cache headers, I realized that any one using customized, buggy or uncommon browser might not be honor requests to not cache documents.
You may also want to add javascript back-button breakers on some pages (e.g. some end of session page) and a history navigation deterrent, but not all pages because no one like the back button to be broken.
I think you have the right idea. Killing the session on "finish/submit" is what I would have recommender. Still read over the owasp top 10 and keep your usual vulnerabilities in mind.
1)Make sure you use HTTPS.
2) Always always always test your application for vulnerabilities before rolling it out. I recommend using Wapiti(free), Acunetix($) or NTOSpider($$$$).
3) Keep your server up to date, make sure you run OpenVAS to make sure your server is secure.
Here you are: What should a developer know before building a public web site
Use JavaScript. You will have to capture and prevent each form's submit event, grab the data, submit it via ajax, then use the form's native reset() method. From there you can navigate elsewhere or show validation errors depending on the ajax result. It's easy with jQuery.

Posting xml with ServerXMLHTTP timeout

I'm working on two websites. One is an existing classic asp site which posts xml to a new asp.net (.net 3.5) website. The classic asp site is using msxml's serverxmlhttp object in vbscript to send this xml over. The whole thing works until I make a seemingly unrelated change to the asp.net site.
When I add a few lines of code that uses System.Speech.Synthesis to generate a wav file from text the classic asp websites serverxmlhttp.send command times out. As far as I can tell the asp.net page is working fine, it makes it through the few new lines of code without an issue (the wav file is generated). The few lines of speech code causing the issue is done well before the timeout.
It seems like the asp.net page was actually sending some sort of acknowledgement back to the classic page which is no longer getting sent. I should also point out that the speech code was throwing an exception saying it needed to be asynchronous which I fixed by adding Async="true" to the . However, it works when async="true", it's just those speech lines that break it. The "problem code" is just
SpeechSynthesizer speaker = new SpeechSynthesizer();
speaker.Volume = 100;
speaker.SelectVoiceByHints(System.Speech.Synthesis.VoiceGender.Female, System.Speech.Synthesis.VoiceAge.Adult, 0);
try
{
speaker.SetOutputToWaveFile("c:\\test\\output.wav");
}
catch (Exception ex)
{
retVal = false;
}
speaker.Speak(msgText);
speaker.SetOutputToDefaultAudioDevice();
Does anyone have any suggestions on what could be wrong or what I could use to help debug this?
It seems like the asp.net page was actually sending some sort of acknowledgement back to the classic page which is no longer getting sent
It sounds like you should investigate it more so you can tell us server's response behavior before and after. Also please indicate the exception thrown.
My guess would be these APIs don't work well in a service process. I have no clue though really. I'm curious about the exception, you're not clear about what you made async.

Resources