link in excel cause duplicate invocation - c#

Problem Background
In my ASP.net MVC4 web application, we allow user to download data in an Excel workbook, wherein one of the cell contains a hyperlink to a report page. We prepare the link such that when user click the link in Excel, ReportController gets called with parameters, processes the request and return a report summary view i.e. .cshtml page. All works well...
I generate excel using SpreadSheetGear, code snippet that generate link:
rrid = (int.TryParse((string) values[row][column], out outInt) ? outInt : 0);
worksheet.Hyperlinks.Add(worksheet.Cells[row + 1, column],
PrepareProspectProfileLink((int) rrid, downloadCode),
string.Empty,
"CTRL + click to follow link",
rrid.ToString(CultureInfo.InvariantCulture));
Problem
I just noticed that when I click the link in excel, the same request is sent to the web server twice.
Analysis
I checked using Fiddler and placed a breakpoint in application code and its confirmed that the request is indeed sent twice.
In fiddler, Under Process column I found that first request is coming from "excel:24408" and second request is coming from "chrome:4028".
Also if I copy paste link in Outlook, it invokes request just once.
I understand this indicate, the first request is invoked by excel, when excel is served with html, it knows nothing about how to render it hence handover the request to default web browser which is Chrome on my system. Now Chrome fires the same request and on receiving html, it opens the html page.
Question
How can I stop this behavior? It puts unnecessary load on web server. And secondly when I audit user action, I get two entry :(

I'm not sure about excel, but you can handle this weird behavior on web server instead. You can create html page (without auditing) that will use javascript to redirect user to page with real report (and auditing stuff).
If you're concerned just about auditing, you can track requests for report in cache (or db) and consider making auditing entry only if same request for report wasn't fired let's say 5 seconds ago.

Related

MVC Intermediate page between redirecting to another long load time page

How using MVC C# (without the use of JS or JQuery) can I send a user to /home/stasis which will load with a loader image (already implemented using css), and then send them to the final url (which has a really long load time, and users end up clicking multiple times - not helping themselves)
The problem is that the use of JS and JQuery won't work, as this needs to work as an in-app webview as well (which doesn't support either JS or JQuery). So I go to /home/index click on a link to take me to /home/stasis which will load, then automatically begin loading the final url lets say google.com for example.
Without javascript, we have to hope that the browser and server will do the right thing:
The browser will display the entity content when the server returns a 307 redirect.
The server will not return partial entity while the long-running request is pending. In other words. The long-running request should return all its entity data in the final second the request.
The browser won't clear the screen until the first bytes of the next entity have arrived.
Assuming the browser and server behave like this, MVC doesn't offer an easy way to do it. You need to:
Create a new class derived from ActionResult.
In your ActionResult's ExecuteResult() method, write output to ControllerContext.HttpContext.Response. Set the response code to 307, set the RedirectLocation, and write whatever content you want to display to the OutputStream.

Prevent from multiple form submitions without javascript

I've got an Asp.net MVC action that creates user account(after input validation). And a View containing registration form that invokes this action. While action validates input, user is left with webbrowser waiting for server response and click submit button a few more times. This creates several accounts. Is there a way to prvent user from form resubmition without javascript. I cannot use javascript in this project it is intended for non javascript browsers. Or can you suggest(server) other solution?
EDIT:
This form request use POST method
JavaScript is not allowed because this Web Application is aimed for special web browsers for people with disabilities that do not support javascript
You have to handle the situation on the server-side then, there's no way around that.
There are 3 options that come to my mind atm:
create a cookie and for each submit check if it exists
similar, but using a session object
before creating a new account, always check if the user exists in the database. THIS should be a no-brainer anyway!
You can add a unique hidden token as part of the form. This token can also be saved as part of the session on the server.
When the user posts the form on the first action, the token is validated and a flag set to indicate the request is being processed. The action processed and results presented. If, while awaiting results, the user attempts to repost the request, the token validation fails as the request is still being processed.
On a side node, the main reason people continuously click is that there is no feed back on whether the request was received by the server or not. To this affect, it might be better to redirect the user to an interim page that shows the request is being processed. Which in conjunction with the above can be used to show the request progress and redirect to the appropriate page when completed.
Of-course, you should also consider making the process a bit lighter. So, that the system can respond quickly to input rather than making the user wait.
Is it a requirement to use MVC? I think you can accomplish something similar using WebForms. When the user submit the request, in the code behind you can disabled the submit button like this:
btnSubmit.Enabled = false;
But if MVC is a must be, #walther answer would be correct

Issue with submit in Extjs

I am using extjs 4.1.3 . I am submitting the form with
'standardSubmit: true'
In server side we use asp.net webapi. i create a excel in code and attach the same in my HTTPResponseMessage content. when 'standardSubmit: true' i am getting the file downloaded in the browser. When i use 'standardSubmit: false' file is not getting downloaded even if it contains the proper content type and attachment.In this case i am getting the excel xml in the response.
The problem with 'standardSubmit: true' is that it is not showing success/failure (I cannot even see the response). Please help.
The issue is that file upload is handled very differently from other inputs due to AJAX limitation of not allowing file uploads.
The framework does not use ajax to submit the form as usual because of the file upload, see the docs on this: http://docs.sencha.com/ext-js/4-1/#!/api/Ext.form.Basic-method-hasUpload
It uses hidden IFrame to submit and process returned data. Follow instructions carefully to set response header from the server to "text/html"

Response.Redirect timeout in NLB environment

I have a custom Sharepoint 2010 web part that runs the user through a series of steps in a registration process. At each step, when whatever required input is completed, the user clicks the Continue button which is a standard server side button control. The code behind does some validation and DB updates before calling Response.Redirect which refreshes the same page with updated session data.
(Note: the session data is kept in the URL as an encrypted query string parameter, not by the conventional Session object)
This solution works fine in my single server test environment, but as soon as I deploy it to a load balanced stage or production environment some requests simply time out without receiving a response after clicking Continue (ERR_TIMED_OUT).
The Webpart log shows that the webpart is in fact calling Response.Redirect with a valid URL
This is no server resource issue. The timeout can be set to a minute or more, no response is received.
Only happens when deployed to load balanced servers
Everything works fine when I complete a registration on one of the load balanced servers - which leads me to believe there is a problem with load balancing and server sessions. I know that when interacting with a load balanced web application from one of the server nodes in the NLB, all requests will go to that particular server.
I know I have faced a similar issue before, but it is several years ago and I cannot remember what the solution was.
try
{
// get clean URL without query string parameters
string url;
if (string.IsNullOrEmpty(Request.Url.Query))
url = Request.Url.AbsoluteUri;
else
url = Request.Url.AbsoluteUri.Replace(Request.Url.Query, "");
// add encrypted serialized session object
url += "?" + Constants.QueryStringParameterData + "=" + SessionData.Serialize(true);
_log.Info("Redirecting to url '" + url + "'..");
Response.Redirect(url);
}
catch (Exception) { }
OK, the problem has been resolved.
It turned out to be UAG that was doing something in the background, and the way I discovered it was that the links that triggered the postbacks got changed from
http://some_url.com/sites/work/al2343/page.aspx
to
http://some_other_url.domain.com/uniquesigfed6a45cdc95e5fa9aa451d1a37451068d36e625ec2be5d4bc00f965ebc6a721/uniquesig1/sites/work/al2343/page.aspx
(Take note of the "uniquesig" in there)
This was the URL the browser actually tried to redirect to, but because of whatever the issue was with UAG the navigation froze.
I don't know how they fixed it, but at least the problem was not in my component.
One possibility that Request.Url is how particular server sees the url (something like http://internalServer44/myUrl) instead of externally visible load-balanced Ulr (like http://NlbFarmUrl/myUrl).
In case of SharePoint it will be better to use SPContext.Current.Site/Web properties to get base portion of Url since this Urls should already be in externally visible form.

Creating PDFs on the fly using AJAX & C#

I have a web page.There is a link to generate pdf reports.When the user clicks on the link the pdf generation process should start.Since the file size of the generated pdf is huge(>15Mb) the user cannot wait & thus has to proceed ahead with his other activities.That means the following simultaneous things would be happening now
The PDF Generation process continues unabated
The user continues with browsing without any jolt
After the pdf generation is completed the user should receive an email containing the download link.
Basically the implementation is
User clicks on generate report button
Using AJAX I make a call to the c# function say generateReport()
The problem
When I do this the user is not allowed to perform anything unless & untill the entire process completes.Ofcourse he can click on different links but with no response because of the AJAX call still getting implemented
How do I achieve this.I am a dot net(framework 2.0) developer creating aspx web pages using C#.I use javascript & AJAX(AjaxPro) to get rid of the postback in typical ASP.NET web applications.
In cases like this, you might want to consider splitting your PDF generation code out into a separate service, which your AJAX code could interact with to kick off the PDF creation. Once the service has created the PDF file, the service can email the user with the relevant info.
The AJAX code would use remoting to communicate with the service.
The concept you have in creating the reports and having them emailed to the user is a good one.
The implementation of this should be quite simple on the client side, ie a basic call to indicate that a report needs to be created. ie save this to a table (report queue)
The actual creation of the report should not be triggered by any of the calls from the front-end directly, Create a service (Windows Service) that runs through the "report queue" generating the PDF files and sending the emails.
As an added option, assuming the PDF's are not destroyed (ie not an email only solution) an ajax popup could be created on the client where the user can then go to a reports page and download the already generated file.
You could try on a timer make an AJAX call to a Function isReportDone(), that in turn checks a repository for the PDF. For generating the PDF, I THINK you'll need to pass that task out of your normal Request-Response Thread. Either by calling a seperate Thread (Multi-threading is fun) to process it, or by passing the data out to a seperate service on the server.
These are just two ideas really I had a similar issue with generating a file from a DB that had to be forcibly downloaded. I ended up calling a seperate page, in a seperate window, that wrote the data to the response stream. It actually worked great until the customer's network blocked any and all popups.
User asks for report to be generated (clicks a button)
Page kicks off an async service call to GeneratePdf(args).
User sees a spinner of some sort while Pdf is being generated, that way they know something is happening.
Pdf is generated (iTextSharp might come in handy here).
Pdf is stored somewhere. Database blob field would be ideal, that way the webservice can just pass back the id of the new file. Failing that, pass a filename back to the ajax code.
Webservice async (see this one) complete event happens, ajax code throws up either a popup or redirects to a new page. Maybe you want to replace the spinner with a "Ready!" link.
Link to pdf report file is emailed to user.

Categories

Resources