@Html.ActionLink("Create Report", "Screenreport", "Reports", null, new { @class = "subNavA AddBorderTop", id = "screenReport", title = "Create Report" })
Once the link is clicked, I have a the following jQuery code which creates a JSON object and post the information.
$().ready(function () {
// Create Report fron the screen data
$("#screenReport").live("click", function (event) { GenerateScreenReport(this, event); });
}) /* end document.ready() */
function GenerateScreenReport(clikedtag, event) {
var table = $(".EvrakTable").html();
var screendata = tableParser(table);
var Screentable = { Screenlist: screendata }; var myurl = $(clikedtag).attr ("href");
var title = $(clikedtag).attr("title");
$.ajax({
url: myurl,
type: 'POST',
data: JSON.stringify(Screentable),
dataType: 'json', contentType: 'application/json',
success: function () { alert("Got it"); }
});
};
To Handle JSON I have the following two classes. Realize two classes in the same namespace
namespace MyProject.ViewModels
{
public class Screenrecord
{
public string Fname{ get; set; }
public string LName { get; set; }
public string Age { get; set; }
public string DOB { get; set; }
}
public class Screentable
{
public List<Screenrecord> Screenlist { get; set; }
}
}
And in my controller, I have the following code:
[HttpPost]
[OutputCache(CacheProfile = "ZeroCacheProfile")]
public FileStreamResult Screenreport(Screentable screendata)
{
MemoryStream outputStream = new MemoryStream();
MemoryStream workStream = new MemoryStream();
Document document = new Document();
PdfWriter.GetInstance(document, workStream);
document.Open();
document.Add(new Paragraph("Hello World"));
document.Add(new Paragraph(DateTime.Now.ToString()));
document.Close();
byte[] byteInfo = workStream.ToArray();
outputStream.Write(byteInfo, 0, byteInfo.Length);
outputStream.Position = 0;
return new FileStreamResult(outputStream, "application/pdf");
}
This code does is supposed to generate PDF.
if I leave [HttpPost] as it is it does NOT generate PDF, and it goes to /Screenreport page, however I see my JSON is passed to the controller properly.
(screendata is populated properly - in controller)
But if I comment out [HttpPost], it DOES generate a PDF but screendata (in controller) is null.
Can someone please explain whats's going on and help me figure it out. Thanks in advance.
not exactly sure what you are trying to do. change your ajax success function to:
success: function(pdf) {
// pdf is the pdf stream converted from binary to unicode.
alert(pdf.length);
}
only javascript knows about the returned pdf. as there current is no way for javascript to load string or binary data into a browser plugin (required to display pdf), I'm not sure what you want to do with the pdf result.
also because post's don't cache and plugins get their data from the cache, there are a lot of bugs using post to get a pdf. you should use a form get with a target of a new window, or use an iframe and set its source to the url.
Do you have another method called CreateScreenReport? If you have method:POST in your ajaxrequest and and comment out the [HttpPost] attribute it would not use that method by default if you have two of them (which is the convention for actions that handle
get/post).
* REMEMBER TO MARK THE ANSWER TO YOUR QUESTION * .NET Developer (ASP.NET, MVC, WPF) MCTS .NET 4 (Web, WCF)
Blog | Twitter
You have minimized my problem , though I decided not to use iframe. I decided to force the user either to download the file. So I am trying to send (post) JSON object, which is an array of objects, to the server. Create PDF, the force the user to download
(or open) file.
The following code creates and forces the user to download, however there is a problem
public ActionResult Screenreport(Screentable screendata)
{
MemoryStream outputStream = new MemoryStream();
MemoryStream workStream = new MemoryStream();
Document document = new Document();
PdfWriter.GetInstance(document, workStream);
document.Open();
document.Add(new Paragraph("Hello World"));
document.Add(new Paragraph(DateTime.Now.ToString()));
document.Close();
On the client site, this is the important part. I generate a JSON object
$().ready(function () {
// Create Report fron the screen data
$("#screenReport").live("click", function (event) { GenerateScreenReport(this, event); });
}) /* end document.ready() */
function GenerateScreenReport(clikedtag, event) {
//event.preventDefault(); var table = $(".EvrakTable").html();
var screendata = tableParser(table);
var Screentable = { Screenlist: screendata };
var myurl = $(clikedtag).attr("href");
var title = $(clikedtag).attr("title");
$.ajax({
url: myurl,
type: 'POST',
data: JSON.stringify(Screentable),
contentType: 'application/json; charset=utf-8'
});
};
if I comment out //event.preventDefault(); then I screendata in my Screenreport
action (public ActionResult Screenreport(Screentable screendata) is null and I DO get the "File Download" pop-up. This is no good because I ned my data here
But if I uncomment it, I see my data on the server side (screendata is NOT null, its good) but I
don't get the "File Download" pop-up
I need to get my data (JSON) to the server, generate PDF and be able to display "File Download"
pop-up so the user will save or view the pdf.
when you use ajax to talk to the server, it uses xmlhttprequest under the covers. when the server responds, xmlhttprequest exposes the data via two properties, responseXML (xml dom) or responseText. in your case because the response type is not xml, responseXML
will be null, and your pdf stream will be in responseText as a javascript string (there is no binary string or byte array in javascript).
if you want the pdf to appear in a window or as a download, then you need to do a browser form post/get, not an ajax call, so the browser can handle the response rather than xmlhttprequest. currently browsers do not support json form posts. you can put the
json in a hidden field and post, or just do a regular form post.
a common approach is a two step. an ajax call to the server to build the pdf. the server builds the pdf, caches it and returns a token. then a second get with the token returns the pdf file. then you query look like:
$.ajax({url:myurl,dataType:'json',data:JSON.stringify(Screentable),sucess: function(r) {
var $f = $('iframe');
if (f$.length == 0) $f = $('<iframe style="display:none"></iframe>').appendTo($('body'));
$f[0].src='getPDF/" + r.token;
});
bruce (sqlwork.com)
Marked as answer by tarslan on May 31, 2011 03:34 PM
Thank you. Your help was very valuable. I ended up doing the following; Created a form which includes a hidden input field, then added the following js
//Get a reference to my hidden field
var $hidInput = $("#dataToReport");
$hidInput.val(JSON.stringify(Screentable));
alert($hidInput.val());
// submit my form which includes the hidden input
$('#frmScreenreport').submit();
Then I had to do parsing on the server side which is not a big deal.
tarslan
Member
13 Points
7 Posts
Return PDF to browser using JSON and MVC ?
May 25, 2011 02:06 PM|LINK
I have a link as follows.
@Html.ActionLink("Create Report", "Screenreport", "Reports", null, new { @class = "subNavA AddBorderTop", id = "screenReport", title = "Create Report" })Once the link is clicked, I have a the following jQuery code which creates a JSON object and post the information.
To Handle JSON I have the following two classes. Realize two classes in the same namespace
namespace MyProject.ViewModels { public class Screenrecord { public string Fname{ get; set; } public string LName { get; set; } public string Age { get; set; } public string DOB { get; set; } } public class Screentable { public List<Screenrecord> Screenlist { get; set; } } }And in my controller, I have the following code:
[HttpPost] [OutputCache(CacheProfile = "ZeroCacheProfile")] public FileStreamResult Screenreport(Screentable screendata) { MemoryStream outputStream = new MemoryStream(); MemoryStream workStream = new MemoryStream(); Document document = new Document(); PdfWriter.GetInstance(document, workStream); document.Open(); document.Add(new Paragraph("Hello World")); document.Add(new Paragraph(DateTime.Now.ToString())); document.Close(); byte[] byteInfo = workStream.ToArray(); outputStream.Write(byteInfo, 0, byteInfo.Length); outputStream.Position = 0; return new FileStreamResult(outputStream, "application/pdf"); }This code does is supposed to generate PDF.
if I leave [HttpPost] as it is it does NOT generate PDF, and it goes to /Screenreport page, however I see my JSON is passed to the controller properly.
(screendata is populated properly - in controller)
But if I comment out [HttpPost], it DOES generate a PDF but screendata (in controller) is null.
Can someone please explain whats's going on and help me figure it out. Thanks in advance.
bruce (sqlwo...
All-Star
36850 Points
5445 Posts
Re: Return PDF to browser using JSON and MVC ?
May 25, 2011 03:08 PM|LINK
not exactly sure what you are trying to do. change your ajax success function to:
success: function(pdf) {
// pdf is the pdf stream converted from binary to unicode.
alert(pdf.length);
}
only javascript knows about the returned pdf. as there current is no way for javascript to load string or binary data into a browser plugin (required to display pdf), I'm not sure what you want to do with the pdf result.
also because post's don't cache and plugins get their data from the cache, there are a lot of bugs using post to get a pdf. you should use a form get with a target of a new window, or use an iframe and set its source to the url.
tarslan
Member
13 Points
7 Posts
Re: Return PDF to browser using JSON and MVC ?
May 25, 2011 08:38 PM|LINK
My goal is to creat PDF dynamicall and display it. I removed caching but it did not make any difference
Would you Please give me an example of how I can use iframe
Forest Cheng...
Star
8370 Points
819 Posts
Re: Return PDF to browser using JSON and MVC ?
May 27, 2011 03:36 AM|LINK
<script type="text/javascript"> $.ajax({ url: myurl, type: 'POST', data: JSON.stringify(Screentable), dataType: 'json', contentType: 'application/json', success: function () { $("#DisplayPDF").html( $('<iframe>', { src: this.href, width:'600px', height: "800px" }) ); } }); </script></div> <div>Hope this helpful,</div> <div>Forest Cheng</div>If you have any feedback about my replies,please contact msdnmg@microsoft.com.
Microsoft One Code Framework
Knecke
Contributor
3712 Points
838 Posts
Re: Return PDF to browser using JSON and MVC ?
May 27, 2011 05:28 AM|LINK
Do you have another method called CreateScreenReport? If you have method:POST in your ajaxrequest and and comment out the [HttpPost] attribute it would not use that method by default if you have two of them (which is the convention for actions that handle get/post).
.NET Developer (ASP.NET, MVC, WPF) MCTS .NET 4 (Web, WCF)
Blog | Twitter
tarslan
Member
13 Points
7 Posts
Re: Return PDF to browser using JSON and MVC ?
May 27, 2011 04:59 PM|LINK
Mr. Cheng,
You have minimized my problem , though I decided not to use iframe. I decided to force the user either to download the file. So I am trying to send (post) JSON object, which is an array of objects, to the server. Create PDF, the force the user to download (or open) file.
The following code creates and forces the user to download, however there is a problem
public ActionResult Screenreport(Screentable screendata)
{
MemoryStream outputStream = new MemoryStream();
MemoryStream workStream = new MemoryStream();
Document document = new Document();
PdfWriter.GetInstance(document, workStream);
document.Open();
document.Add(new Paragraph("Hello World"));
document.Add(new Paragraph(DateTime.Now.ToString()));
document.Close();
byte[] byteInfo = workStream.ToArray();
outputStream.Write(byteInfo, 0, byteInfo.Length);
outputStream.Position = 0;
//Response.AddHeader("Content-Disposition", "attachment; filename=test.pdf");
//return File(byteInfo, "application/pdf", "test.pdf");
return File(outputStream, "application/pdf", "test.pdf");
}
I have a view for this action which does not have much in it
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Screenreport</title>
</head>
<body>
<div>
</div>
</body>
</html>
On the client site, this is the important part. I generate a JSON object
$().ready(function () { // Create Report fron the screen data $("#screenReport").live("click", function (event) { GenerateScreenReport(this, event); }); }) /* end document.ready() */ function GenerateScreenReport(clikedtag, event) { //event.preventDefault(); var table = $(".EvrakTable").html(); var screendata = tableParser(table); var Screentable = { Screenlist: screendata }; var myurl = $(clikedtag).attr("href"); var title = $(clikedtag).attr("title"); $.ajax({ url: myurl, type: 'POST', data: JSON.stringify(Screentable), contentType: 'application/json; charset=utf-8' }); };if I comment out //event.preventDefault(); then I screendata in my Screenreport action (public ActionResult Screenreport(Screentable screendata) is null and I DO get the "File Download" pop-up. This is no good because I ned my data here
But if I uncomment it, I see my data on the server side (screendata is NOT null, its good) but I don't get the "File Download" pop-up
I need to get my data (JSON) to the server, generate PDF and be able to display "File Download" pop-up so the user will save or view the pdf.
Please help
tarslan
Member
13 Points
7 Posts
Re: Return PDF to browser using JSON and MVC ?
May 27, 2011 05:01 PM|LINK
Knecke,
I did remove [HttpPost] from the action but I still have the same problem.
Knecke
Contributor
3712 Points
838 Posts
Re: Return PDF to browser using JSON and MVC ?
May 27, 2011 05:23 PM|LINK
.NET Developer (ASP.NET, MVC, WPF) MCTS .NET 4 (Web, WCF)
Blog | Twitter
bruce (sqlwo...
All-Star
36850 Points
5445 Posts
Re: Return PDF to browser using JSON and MVC ?
May 27, 2011 08:25 PM|LINK
when you use ajax to talk to the server, it uses xmlhttprequest under the covers. when the server responds, xmlhttprequest exposes the data via two properties, responseXML (xml dom) or responseText. in your case because the response type is not xml, responseXML will be null, and your pdf stream will be in responseText as a javascript string (there is no binary string or byte array in javascript).
if you want the pdf to appear in a window or as a download, then you need to do a browser form post/get, not an ajax call, so the browser can handle the response rather than xmlhttprequest. currently browsers do not support json form posts. you can put the json in a hidden field and post, or just do a regular form post.
a common approach is a two step. an ajax call to the server to build the pdf. the server builds the pdf, caches it and returns a token. then a second get with the token returns the pdf file. then you query look like:
$.ajax({url:myurl,dataType:'json',data:JSON.stringify(Screentable),sucess: function(r) {
var $f = $('iframe');
if (f$.length == 0) $f = $('<iframe style="display:none"></iframe>').appendTo($('body'));
$f[0].src='getPDF/" + r.token;
});
tarslan
Member
13 Points
7 Posts
Re: Return PDF to browser using JSON and MVC ?
May 31, 2011 03:34 PM|LINK
bruce,
Thank you. Your help was very valuable. I ended up doing the following; Created a form which includes a hidden input field, then added the following js
//Get a reference to my hidden field var $hidInput = $("#dataToReport"); $hidInput.val(JSON.stringify(Screentable)); alert($hidInput.val()); // submit my form which includes the hidden input $('#frmScreenreport').submit();