MVC - How to download a csv file using ajax in mvc3 - asp.net-mvc

I have a problem in downloading csv file using $.ajax(); code.
I have a controller which is returning the file as below.
public ActionResult ExportEx()
{
StringBuilder sb = new StringBuilder();
sb.Append("<table>");
sb.Append("<tr>");
sb.Append("<td>1</td>");
sb.Append("<td>2</td>");
sb.Append("<td>3</td>");
sb.Append("<td>4</td>");
sb.Append("</tr>");
sb.Append("<table>");
HttpContext.Response.AddHeader("content-disposition", "attachment; filename=student_" + DateTime.Now.Year.ToString() + ".xls");
this.Response.ContentType = "application/vnd.ms-excel";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(sb.ToString());
return File(buffer, "application/vnd.ms-excel");
}
I have index.cshtml file as below
<input type="submit" value="Export To Excel" title="Export To excel" />
<script type="text/javascript">
$(".tt").click(function () {
$.ajax({
url: '/Home/ExportEx',
type: 'POST',
data: {},
success: function (data) { },
complete: function (data) { }
});
});
</script>
If I call using <a class="tt" href="#Url.Action("ExportEx", new { })">export</a> I can download csv file. But through $.ajax call i can not download.
Kindly help me in this.
Thanks in advance.

$('button').click(function () {
window.location.href = '/Home/ExportEx';
});

Related

jquery autocomplete with ASP.NET MVC

I am trying to get jQuery autocomplete in a textbox. But I don't seem to be able to display the data from my JsonResult in the view, I checked with firebug and verfied that the data is transferred from server, just doesn't disply in the TextBox. I don't get any errors.
Here's my code :
public JsonResult search(string term)
{
// string prefixText =SearchString;
var FamilyLastName = _repository.FamilySearch(term);
var data=FamilyLastName.ToList();
return Json(data);//.Select(x => new { label = x, ID = x }));
}
#using (Html.BeginForm())
{
<label for="SearchString">My Autocomplete:</label>
<input class="form-control" type="text" name="SearchString" id="SearchString" autocomplete="off" />
}
<script type="text/javascript">
$(document).ready(function () {
var param = { "searchstring": $("#SearchString").val() };
$("#SearchString").autocomplete({
autoFocus: true,
source: function (request, response) {
// call your Action
$.ajax({
url:'search?term=' + $("#SearchString").val(),
// data:"{'term':'" +$("#SearchString").val() + "'}",
dataType: 'json',
method: "post",
contentType: "application/json; charset=utf-8",
success: function (data) {
return{
label:data.FamilyLastName
};
},
select:
function (event, ui) {
$('#SearchString').val(ui.item.label);
return false;
},
});
},
minLength: 1,// requ

Ajax call on separate js file

I can use ajax call on *.cshtml file as below.It's working properly.
$.ajax({
url: '#Url.Action("GetAllBooks", "Book")',
cache: false,
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
self.Books(data); //Put the response in ObservableArray
}
});
But How can I call same method on seperate *.js file ?When I used above code it's not working?
CSHTML (I prefer the tag input):
#* without the attribute 'name' *#
<input type="hidden" value="#Url.Action("GetAllBooks", "Book")" id="UrlBookGetAllBooks" />
#* or *#
<div style="display:none;" data-url="#Url.Action("GetAllBooks", "Book")" id="UrlBookGetAllBooks"></div>
JS:
var url = $('#UrlBookGetAllBooks').val();
//or for tag div
var url = $('#UrlBookGetAllBooks').data('url');
$.ajax({
url: url,
cache: false,
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
self.Books(data); //Put the response in ObservableArray
}
});
HTML - Contains data- attributes
<div id="ExampleDiv"
data-url = "#Url.Action("Action", "Controller", new { area = "AreaName" })">
</div>
HTML - Option 2
<div id="ExampleDiv"
url-Val = "#Url.Action("Action", "Controller", new { area = "AreaName" })">
</div>
JQuery - Contains data- attributes
var Url_Value = $('#ExampleDiv').data('url');
JQuery - Option 2
var Url_Value = $('#ExampleDiv').attr('url-Val');
Ajax Call
$.ajax({
url: Url_Value,
cache: false,
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
self.Books(data); //Put the response in ObservableArray
}
});
For such solution, I recommends you to create a JavascriptController with a "JavascriptActionResult" or a new "JavascriptActionResult" on the BookController along with the view that outputs the desired javascript. That way you can write Javascript dynamically with razor and also have garantee that the Route Pattern behavior of your MVC will be followed. With all that set, the page would be:
<script type="text/javascript" src="#Url.Action("GetAllBooksJS","Book")"></script>
PS: There is not a native JavascriptActionResult in MVC, but you could extend the ActionResult to perform that or simple force a Content-Type in the classic ActionResult function.
Bellow is a working case that Ive made in MVC3.
Controller:
public class BookController : Controller
{
//
// GET: /Book/
public ActionResult Index()
{
return View();
}
public JsonResult GetAllBooks() {
return Json(new[] { new { name = "Book1" }, new { name = "Book2" } });
}
public ActionResult GetAllBooksJS()
{
Response.ContentType = "text/javascript";
return View();
}
}
Index View:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
<script type="text/javascript" src="#Url.Content("~/scripts/jquery-1.7.1.min.js")"> </script>
<script type="text/javascript" src="#Url.Action("GetAllBooksJS","Book")"></script>
</head>
<body>
<div>
<button>Get books ajax</button>
</div>
</body>
</html>
GetAllBooksJS View:
#{
Layout = null;
}
$(document).ready(function(){
$('button').on('click',function() {
GetBooksAjax();
});
});
function GetBooksAjax() {
$.ajax({
url: '#Url.Action("GetAllBooks","Book")',
type: 'POST',
dataType: 'json',
success: function(oJSON) {
$.each(oJSON,function(){
alert(this.name);
})
}
})
}
GetAllBooksJS View v2, In this second version the Javascript, as soon as it is loaded by the Index view, will engage the Ajax Call, I guess thats your case:
#{
Layout = null;
}
function GetBooksAjax() {
$.ajax({
url: '#Url.Action("GetAllBooks","Book")',
type: 'POST',
dataType: 'json',
success: function(oJSON) {
$.each(oJSON,function(){
alert(this.name);
})
}
})
}
GetBooksAjax();

Open dynamically generated PDF in Tab or iframe

Please help.
I am obviously no expert but using suggestions from this site, I think I am really close to doing the following
Be able to open a dynamically generated PDF in
a) a new Tab
b) an iframe
Hopefully, I just need a couple of lines of the correct syntax and I will be there.
I am dynamically generating the PDF in a controller using itextSharp
CONTROLLER
public FileStreamResult GetPdf()
{
...
return new FileStreamResult(Response.OutputStream, "application/pdf"){FileDownloadName = "download.pdf"};
}
VIEW
<input id="btnNewTab" type="button" value="New Tab" />
<input id="btnIframe" type="button" value="Iframe" />
<div id="pdfDiv"></div>
<script type="text/javascript">
$(function () {
$("#btnIframe").click(function () {
$.get('/PDFTest/GetPdf', function (pdf) {
alert(pdf.length); // Works as expected
// What do I need to put here to get the pdf to appear in a iframe
});
});
$("#btnNewTab").click(function () {
// asks me if I want to Open or Save the PDF.
// If I choose Open, the PDF opens in a completely new Window.
// Instead of the dialog, I just want the PDF to open in a new Tab
// I am probably going about this in completely the wrong way.
var HTML = "<iframe src='/PDFTest/GetPdf' style='width: 100%; height: 600px' ></iframe>";
$('#pdfDiv').html(HTML);
});
});
</script>
In response to your suggestion Darin, I changed the Controller to:
public FileStreamResult GetPdf(someInfo from View)
{
...
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "inline;test.pdf");
Response.Buffer = true;
Response.Clear();
Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
Response.OutputStream.Flush();
Response.End();
return new FileStreamResult(Response.OutputStream, "application/pdf");
}
Having done that, your suggestions worked fine but I realise that I did not explain my intentions clearly enough. I have therefore changed the VIEW to reflect what i am trying to do.
input id="btnNewTab" type="button" value="New Tab" />
<input id="btnIframe" type="button" value="Iframe" />
<iframe id="iframe"></iframe>
<div id="pdfDiv">
</div>
<script type="text/javascript">
$(function () {
$("#btnIframe").click(function () {
$.ajax({
url: '/PDFTest/GetPdf',
type: "GET",
data: json, // This line will not be a problem
dataType: "json",
contentType: "application/pdf", // This line might be a problem
success: function (pdf) {
// What to I need to need to do to display the PDF in the above iframe
$("#iframe").attr("src", pdf); // HTTP Error 400 - Bad Request.
}
});
});
$("#btnNewTab").click(function () {
$.ajax({
url: '/PDFTest/GetPdf',
type: "GET",
data: json, // This line will not be a problem
dataType: "json",
contentType: "application/pdf", // This line might be a problem
success: function (pdf) {
// What to I need to need to do to disply the PDF in a new window
}
});
});
});
</script>
Action:
public ActionResult GetPdf()
{
byte[] pdf = ...
Response.AppendHeader("Content-Disposition", "inline;test.pdf");
return File(pdf, "application/pdf");
}
To open in new Tab/Window:
#Html.ActionLink("view pdf", "getpdf", "somecontroller", null, new { target = "_blank" })
To open in an iframe your code looks fine. Just make sure to set the Content-Disposition header to inline.

Posting to action, mvc 3, not part of form

Can I post to action from view a filed of of my model ? Is is not part of the form. I just want to pass the myModel.someValue as argument to nextRelease action, hopefully without putting it anywhere in the form.
e.g.
View:
#model myModel
#using (Html.BeginForm("Search", "News", FormMethod.Get, new { id = "myform" }))
{
<div>myModel.someValue</div> //to show it has this field
<script type="text/javascript">
$('#nextbutton').click(function () {
$('#myform').attr("action", "/#controller.Language/news/nextRelease");
$("#submit").click();
});
</script>
}
Sure, you could use AJAX:
#model myModel
<script type="text/javascript">
$(function() {
$('#nextbutton').click(function () {
var url = '#Url.Action("NextRelease", "News")';
var dataToPost = #Html.Raw(Json.Encode(new { someValue = Model.SomeValue }));
$.post(url, dataToPost, function(result) {
alert('data successfully posted to server');
});
return false;
});
});
</script>
<button id="nextbutton">Next button</button>
or if you wanted to post not only a single property but the entire model:
var url = '#Url.Action("NextRelease", "News")';
var dataToPost = #Html.Raw(Json.Encode(Model));
$.ajax({
url: url,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(dataToPost),
success: function(result) {
alert('data successfully posted to server');
}
});

Is not the way I want PartialViewResult

I try something.I apologize in advance for my english.
My Action code;
public PartialViewResult showProduct()
{
var query = db.Categories.Where((c) => c.CategoryID == 4);
return PartialView("_EditCategory",query);
}
My view code:
#using (Ajax.BeginForm(
"showProduct",
new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "result"
}))
{
<input type="submit" value="Get" />
}
<div id="result">
</div>
When i pushed the submit button ( which value is get) the results return but in another page like http://localhost:57616/Home/showProduct but i want return to result div in index page.
Any one can help me?
So, how I handled this myself was something like this:
$(document).ready(function () {
var options = {
target: "#mytargetdiv",
url: '#Url.Action("Edit", "IceCream")',
};
$("#editIceCreamForm").submit(function () {
$(this).ajaxSubmit(options);
return false;
}
// other stuff
});
in other places, where I wanted to do in-place editing of things I'd do something like this:
<input type="button" id="someid" value="Edit" data-someid="#Model.SomeId"/>
and then some ajax like so:
$(function () {
$("#someid".click(function () {
var theId = $(this).data('someid');
$.ajax({
type: "GET",
data: "id=" + theId,
url: '#Url.Action("Edit", "Something")',
dataType: "html",
success: function (result) {
$('#targetdiv').html(result);
}
});
});
});
So, if you're not interested in using jQuery and want to use the MS Ajax stuff, are you including the MicrosoftAjax.js and MicrosoftMvcAjax.js files on the page? If you don't have those, I believe what will happen is it just does the default (non-Ajax) submit.

Resources