Issues with Kendo MVVM file upload control - asp.net

I was trying to get a Kendo MVVM file upload working along with ASP.NET. This is how my HTML looks for the upload declaration:
<input name="attachments"
id="fileUpload"
type="file"
data-role="upload"
data-async="{ saveUrl: 'FileUpload.aspx', autoUpload: true }"
data-bind="events: { success: onSuccess,error: onError }">
and the FileUpload page load:
Response.Expires = -1;
//Code to upload -- This returns me the file url that i need to send back as a response
Response.ContentType = "text/plain";
Response.Write(fileUrl);
Response.End();
The page load written above does function as expected and return me the desired result but the kendo control here behaves in a funny manner. It tells me that the upload is unsuccessful as in the error icon shows up on the UI. Moreover it is the error handler provided by Kendo that is executed though the written response is returned properly when I try accessing it as:
e.XMLHttpRequest.responseText
Well I guess I might have missed out something/done some small mistake here or there but unfortunately I am not able to figure the same out. Anyone who could possibly suggest/correct?

Well it seems that the response for the file upload control should be empty or a JSON string otherwise it is treated as an error. I changed the Response text to thus:
Response.Write(new JavaScriptSerializer().Serialize(fileUrl));
to resolve.
Hope this helps someone else!

Related

ASP.NET "application/pdf": code runs only once

I'm working on a SharePoint 2013 site and I've added the ability to save pages in PDF. The PDF conversion is handled by the third party library SelectPdf.
I managed to get everything to work (rendering and file download), except that the "PDF Download" button that I have on my page works only 1 time. Meaning, the click event on the code behind is fired only once, no matter how many times I click the button (notice that I click it with intervals of 10+ seconds). If I want to download the PDF file again, I have to refresh the page.
I put together a "hello world" example (see below) in order to pinpoint the problem:
protected void lnkPdfDownload_Click(object sender, EventArgs e)
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=test.pdf");
/************************************ Create PDF File ************************************/
string html = #"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"">
<html dir=""ltr"" lang=""en-US"">
<body><h1>Hello World</h1></body>
</html>";
HtmlToPdf converter = new HtmlToPdf();
PdfDocument doc = converter.ConvertHtmlString(html);
byte[] bytes = doc.Save();
Response.OutputStream.Write(bytes, 0, bytes.Length); // ALTERNATIVE: doc.Save(Response.OutputStream);
/************************************ Create PDF File ************************************/
//Response.End(); // This throw a ThreadAbortException, therefore I'm using the alternative code below
Response.Flush();
Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
At the beginning I thought it was Response.End() that caused the issue (by throwing the ThreadAbortException), but I replaced it with other code and I still have the same problem (no exceptions are thrown now).
I don't think the problem is in the SelectPdf library: I can comment out the entire block (between the "Create PDF File" comments), and I still get the same thing (obviously no PDF is generated).
I noticed that, at most, I can successfully click the "download" button up to 2 times (it's rare, and not consistent): the third time nothing happens.
While this isn't a huge deal, I think there is something wrong going on that I'm not seeing. Here is why: after I click the "download" button (and get my PDF file), I am not able to go on edit mode in my SharePoint page. The "loading" message keeps spinning but nothing happens (again, unless I refresh the page).
Has anyone had this problem? I looked online but I couldn't find anything about it.
I'm using Internet Explorer 11 and Chrome 51. Please let me know if you need more information. Thank you.
Are you sure there are not javascript/jquery errors happening when the download button is clicked that prevent the re-clicking of the PDF button and also going into edit mode?
Especially since refreshing the page makes everything work again.

Open a new page using HTML Response/JS ASP

Alright, I have decided to go about this by opening a new page (newPage.aspx) which will then initiate the download and close after the download is completed. I am opening newPage.aspx using javascript by writing it to the response of the current page. For some reason, however, the window is not being opened before the original page is re-directed. Is their a method to be called before I redirect? Maybe I have a syntax issue?
Response.Write("<script type='text/javascript'>window.open('~/newPage.aspx', '', ''); </script>")
Response.Redirect("~/oldPage.aspx")
EDIT:
I tried the following but it did not work... (I am working in an Update Panel)
ScriptManager.RegisterStartupScript(udpMain, udpMain.GetType(), "openExcel", "window.open('~/newPage.aspx', '' , '');", True)
EDIT 2: So Close
Ok, so this only works if I comment out the Response.Redirect. It seems that the RegisterStartupScript method takes place on the page load after the Response.Redirect method. Is there any known fix for this?
ScriptManager.RegisterStartupScript(udpMain, udpMain.GetType(), "openExcel", "window.open(NewPage.aspx'); location.href='OldPage.aspx';", True)
Response.Redirect("~/OldPage.aspx")
You can redirect via client script as well. By the way when using ASP.NET preferable way of embedding JS into HTML is ClientScript.RegisterStartupScript e.g
ClientScript.RegisterStartupScript(Me.GetType(), "JSCode" & Rnd(1).ToString, "window.open('newPage.aspx'); location.href = 'oldPage.aspx'", True)

Web form non-responsive after download

I'm working in ASP.NET (2.0) and we have a page where a user is able to select and download a series of files as a zip. I got this to work without undo difficulty by using the DotNetZip library (which is probably not relevant to the problem, but included for completeness.)
After the user checks which files they want to download, the page does a postback, and in the button click event handler, I use the following code:
Response.Clear();
Response.BufferOutput = false; // false = stream immediately
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "filename=FileRequest.zip");
using (ZipFile zip = new ZipFile())
{
zip.AddFile(MapPath("/datafiles/fileToZip.pdf"), "");
zip.Save(Response.OutputStream);
}
Response.Close();
And this all seems to work great. The user clicks the button, a download window pops up, the user downloads the zip. All is good...
...until they decide they want to do something else on the page. The buttons in the form are no longer responsive. For instance, if I click the download button again, it does nothing. If I reload the page, I can repeat this behavior...it works once, then does nothing.
I'm not understanding why the browser doesn't send the new request. It's not "spinning" or otherwise acting busy. I thought that this might be a browser issue, but I've repeated it in both IE and Firefox, so it seems likely that it's something I'm not understanding. Strangely, it's only form submission elements that seem to be non-responsive. Javascript still works, and so do regular links.
So why is this happening, and how do I get around it?
The problem is likely down to you returning;
Response.ContentType = "application/zip";
Once this has been sent (along with the actual content), the browser would assume it has nothing left to do (I believe).
You probably should create a new window specifically for downloading the files by saving the file selection in a session parameter (or equivalent) and opening a popup window that has your download code in.
This will leave the parent page in a suitable state.
Content-disposition header seems to be a discouraged solution. But the same effect of ASP.NET forms not being responsive occurs if you use standard Redirect to a zip file.
I solved very similar problem (returning *.csv files by the server for download) using Tančev Saša's code in "Response.Redirect to new window" Q&A and it works great. Perhaps it might produce some popup warnings in some browsers, but I think this is how it's often done in download sites.

Telerik RadEditor HTTP POST VALUE not being updated (ASP.NET Web Forms)

I am currently writing a ContentManager in ASP.NET. I have a preview button which uses jQuery to post the form data to new window and shows how a page would look without saving it to the database and effecting the live site. Although its been somewhat of a hassle to get ASP.NET to post directly to the page I am trying to preview, I've finally worked it all out using a series of jQuery code. It worked beautifully, I loaded all the post values into the page using Request.Form and displayed them on the page. Unfortunately for some reason the Telerik RadEditor's I was using were posting me the values they had been assigned on the C# Page_Load event and did not reflect the text changes I made. If anyone could help me out that would be great.
function showPreview()
{
url = "<%= (SiteManager.GetSite()).Url + this.Filename %>?preview=true";
var specs = "width=1010,height=700,location=0,resizeable=1,status=1,scrollbars=1";
window.open(url, 'PagePreview', specs).moveTo(25, 25);
$("#__VIEWSTATE").remove();
$("#__EVENTTARGET").remove();
$("#__EVENTARGUMENT").remove();
$("#aspnetForm").removeAttr("action");
$("#aspnetForm").attr("target","PagePreview");
$("#aspnetForm").attr("action", url);
$("#aspnetForm").submit();
}
Here is all the post data I am receiving from the tererik RADEDITOR ::
[ctl00_MainContentPlaceHolder_SideContentRadEditor_dialogOpener_Window_ClientState] => [ctl00_MainContentPlaceHolder_SideContentRadEditor_dialogOpener_ClientState] => [ctl00$MainContentPlaceHolder$SideContentRadEditor] => [ctl00_MainContentPlaceHolder_SideContentRadEditor_ClientState] => [ctl00_MainContentPlaceHolder_ContentRadEditor_dialogOpener_Window_ClientState] => [ctl00_MainContentPlaceHolder_ContentRadEditor_dialogOpener_ClientState] => [ctl00$MainContentPlaceHolder$ContentRadEditor] => %3cp%3eTestPageContent%3c/p%3e
This is the html value of the text editor (shown above) %3cp%3eTestPageContent%3c/p%3e
This is the value in the RadEditor that was loaded during the Page_Load event.
I changed the value to "Test". But it was not sent over the POST Request, it sent what was loaded in the page load.
The editor content area is separate from the textarea used to submit the content during a POST request. The editor will automatically try to save the content in the hidden textarea when the form is submitted, but in your case no event is fired because it happens programmatically (i.e. you call .submit()). You will need to tell the editor to save its content manually before you do the postback. The code is pretty basic - get a reference to the editor and call .saveContent():
//Grab a reference to the editor
var editor = $find("<%=theEditor.ClientID%>");
//Store the content in the hidden textarea so it can be posted to the server
editor.saveContent();
One solution would be to grab the current HTML in the editor in your showPreview method and pass that manually. To do that, add a hidden input element in your page to hold the HTML content:
<input type="hidden" id="htmlContent" name="htmlContent" />
Then, you can set that intput's value in showPreview like this:
function showPreview()
{
url = "<%= (SiteManager.GetSite()).Url + this.Filename %>?preview=true";
var specs = "width=1010,height=700,location=0,resizeable=1,status=1,scrollbars=1";
window.open(url, 'PagePreview', specs).moveTo(25, 25);
$("#__VIEWSTATE").remove();
$("#__EVENTTARGET").remove();
$("#__EVENTARGUMENT").remove();
// *** Begin New Code ***
//Grab a reference to the editor
var editor = $find("<%=theEditor.ClientID%>");
//Get the current HTML content
var html = editor.get_html()
//Put that HTML into this input so it will get posted
$("#htmlContent").val(html);
// *** End New Code ***
$("#aspnetForm").removeAttr("action");
$("#aspnetForm").attr("target","PagePreview");
$("#aspnetForm").attr("action", url);
$("#aspnetForm").submit();
}
Then when you want to get the HTML during the postback you can just use Request.Form["htmlContent"]
One caveat: Since you'll be posting raw HTML, ASP.NET's Request Validation might cause problems. One of the major purposes of that validation is to make sure that HTML content doesn't get posted back to the server - the very thing you're trying to accomplish. You could of course turn the validation off (see the link above) but the validation is there for a reason. Another solution might be to do some basic encoding of the HTML before you post it. If you just replace all less-than symbol (<) with something before posting it, ASP.Net will be happy. Then you just need to 'un-replace' it during the postback.

Display image from database in ASP.net with C#

I know this kind of question has been asked many times.
Yet I don't succeed in displaying an image from my db on a page.
I tried the following method.
protected void Page_Load(object sender, EventArgs e)
{
//Get the picture id by url
//Query here
byte[] picture = queryoutput;
Response.ContentType = "image/jpeg";
Response.BinaryWrite(picture);
}
Link to get the image.
<asp:Image runat="server" ImageUrl="~/givememypicture.aspx?pic=3" ID="testimage" />
The <asp:Image /> tag is located in between <asp:Content > tags.
When I run this code and check in firebug, it simply states 'Failed to load fiven URL'.
I also tried putting the Respone.Con...(picture); part into a public method and call that method with the byte var given.
I'm quite new to asp.net, but I have somewhat more experience in c#.
I start to really dislike asp.net... I have been struggling with this for about 20 hours already and tried a lot of options, yet none worked.
The best would be if I could just fill in the picture via the codefile from that same page. It seems quite illogical to me to call another page to load the image from.
Can somebody please tell me what I'm doing wrong here?
Solution: Master page reference removed from the page directive on the page that handles the image response. Also removed everything else except for the #page directive itself within the aspx file.
try using a handler file (.ashx) put the code form your page_load in that lie so
public void ProcessRequest (HttpContext context) {
//Get the picture id by url
//Query here
byte[] picture = queryoutput;
Response.ContentType = "images/jpeg";
Response.BinaryWrite(picture);
}
public bool IsReusable {
get {
return false;
}
}
then call the handler file and pass the correct querystring items from the
this should then work
There's an error in your path reference...
ImageUrl="/~givememypicture.aspx?pic=3"
should be:
ImageUrl="~/givememypicture.aspx?pic=3"
~ is shorthand for "the application root" and needs to be followed by a slash to indicate that it's a directory. Think of it as similar to other path shorthand notations such as . and ...
Make sure you call Response.Flush(); and also Response.End(); and see if that does the trick
Also, your content type has a misspelling. Is not "images/jpgeg" I think it's "image/jpeg"
EDIT: Yes, I just confirmed in Wikipedia that the correct content-type is image/jpeg.
I do this all the time. Here's some sample code:
Response.ContentType = "image/jpeg";
Response.BinaryWrite(bytes);
That's all there is too it. If it's not working, then something is probably wrong with your data.
A flush is not required. I have working code for this open on my screen right now.
I would suggest that you try writing that buffer of data to a file and see if it opens up as a valid picture. I bet something's wrong with that data.
Also, it's a good idea to enable browser side caching for your dynamic content. Here's a GREAT link that shows exactly how to do that, which will boost your performance / scalability a lot.
http://edn.embarcadero.com/article/38123

Resources