I have been up the wall and back again with this. The idea is that when a user clicks a link on a page, the controller method will prepare the data, save it to a memory stream and then serve the file to the user. This is my current code:
public ActionResult Export(int id1, int id2)
{
using (ExcelPackage excelPackage = new ExcelPackage())
{
ExcelWorksheet workSheet = excelPackage.Workbook.Worksheets.Add("Test1");
//Populate worksheet with data...
MemoryStream stream = new MemoryStream();
excelPackage.SaveAs(stream);
stream.Position = 0;
return File(stream, "application/vnd.ms-excel", "myfilename.xlsx");
}
}
My issue is that when this button is clicked, the user is not prompted to grab the file. I have stepped through the method and nothing seems off, but I am reasonably new to MVC and may be missing something.
Any assistance would be welcome.
--EDIT--
I should mention that for the button I am handling the click in a jquery.click function, and I am reaching the above method through AJAX. Would this be an issue in returning a file?
$(".export").click(function () {
var ID1 = '<%: Model.ID1%>';
var ID2= '<%: ViewData["ID2"] %>';
$.ajax({
url: '<%= Url.Action("Export", "Export") %>',
type: "GET",
data: { id1: ID1, id2: ID2},
async: false,
success: function () {
}
});
});
try next:
$(".export").click(function () {
var ID1 = '<%: Model.ID1%>';
var ID2= '<%: ViewData["ID2"] %>';
var url = '<%= Url.Action("Export", "Export") %>?id1'+ ID1+'$id2'+ID2; // format your url
window.location=url;
}
Not sure about url formatting but you got the point. This worked for me. Let me know if it works for you.
Related
I have tried many suggestions from stack overflow earlier threads, but the issue still do not seem to be resolving.
Client Side Code:
var file = document.getElementById('MainForm_main_panel_company_code_change_file').files[0];
var formData = new FormData();
formData.append("file", file);
data = '[0, {"data":{"args":"'+formData+'"}}]';
$.ajax({
url: 'Control/MainForm.main_panel.company_code_change/GetData',
type: 'POST',
data: data,
contentType: false,
processData: false,
dataType: 'json',
success: function (result) {
if (result.msg === undefined) {
JSMessage.show("Success", "Report Generated Successfully");
} else
JSMessage.show("Error", "Report Generation Failed:" +result.msg.text);
}
Note: If I don't mention data = '[0, {"data":{"args":"......., it throws error: 'data is required'
Server Side Code:
public class CompanyCodeChangeArg
{
public string args;
public CompanyCodeChangeArg()
{
F<IMNull<CompanyCodeChangeArg>>.Instance.SetNull(this);
}
}
[HttpPost]public string GetData(CompanyCodeChangeArg arg)
{
var file = System.Web.HttpContext.Current.Request.Files[0];
HttpPostedFileBase filebase = new HttpPostedFileWrapper(file);
var fileName = Path.GetFileName(filebase.FileName);
var path = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/Uploads/"), fileName);
filebase.SaveAs(path);
return "";
}
Please help me here, I need to upload the file using WebApi Method and JQuery AJAX,
Tried various suggestions on stack overflow but it did not worked
I have a form that contains different fields for user to fill in and also allow user to attach image. Below is my code to send data to the controller, I can see the image in my controller but I am not sure how to access rest of form data in controller:
$(function () {
var ajaxFormSubmit = function () {
var $form = $(this);
var data = new FormData();
var files = $("#File").get(0).files;
if (files.length > 0) { data.append("File", files[0]); }
else {
common.showNotification('warning', 'Please select file to upload.', 'top', 'right');
return false;
}
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: data,
processData: false,
dataType: "html",
contentType: false
};
$.ajax(options).done(function (data) {
$('#ProdList').html(data);
});
return false;
};
$("form[data-ajax='true']").submit(ajaxFormSubmit);
});
My controller :
public ActionResult Create(PostViewProduct postProduct)
{
//code......
}
PostViewProduct model shows only image fields with data rest showing null:
Do I have to add each field using formdata.append() or is there better way to send all the data to controller and then access the data in controller.
Thanks
Try this:
var data = new FormData($(this)[0]);
instead of var data = new FormData();
Try following, this will put the data in right format if all input is within the form.
data = $form.serialize();
You basically need to send the files in FormData along with other form element data.
$(function () {
var ajaxFormSubmit = function () {
var fdata = new FormData();
$('input[name="Image"]').each(function (a, b) {
var fileInput = $('input[name="Image"]')[a];
if (fileInput.files.length > 0) {
var file = fileInput.files[0];
fdata.append("Image", file);
}
});
// You can update the jquery selector to use a css class if you want
$("input[type='text'").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
var frmUrl = $(this).attr('action');
$.ajax({
type: 'post',
url: frmUrl,
data: fdata,
processData: false,
contentType: false,
success: function (e) {
console.log(e);
}
});
return false;
};
$("form[data-ajax='true']").submit(ajaxFormSubmit);
});
Assuming your view model has a property called Image of type HttpPostedFileBase for accepting the posted file and your form has an input for that
public class YourViewModel
{
public HttpPostedFileBase Image { set;get;}
//Your other existing properties
}
and your form has an file input tag with name "Image".
<input type="file" name="Image" />
I am using Kendo with MVC 5. I have several form inputs including a fileupload control. Onclick of a button I am building a json object with the values of the inputs and sending it through via an AJAX call.
I want to know how I can include the selected file from the file upload control in the json object that is sent. Here is the code for the upload control:
$(document).ready(function () {
$("#files").kendoUpload({
multiple: false
});
});
And then the ajax call sending the form data:
var ro = new Object();
// ...... //populate some properties
var jsonString = JSON.stringify(ro);
$.ajax({
url: '#Url.Action("Save", "Service")',
data: jsonString ,
type: 'POST',
dataType: 'json',
contentType: 'application/json',
});
The receiving controller action look like this:
public ActionResult Save(MyViewModel model)
{
var obj = //call something here then return resulting obj
return this.Json(obj, JsonRequestBehavior.AllowGet);
}
Any help is appreciated.
Try
$("#files").kendoUpload({
multiple: false,
async: {
saveUrl: '#Url.Action("Save", "Service")',
autoUpload: true
},
upload: function (e) {
var ro = new Object();
//......//populate some properties
var jsonString = JSON.stringify(ro);
e.data = jsonString;
}
});
In your controller:
public ActionResult Save(IEnumerable<HttpPostedFileBase> files, string model)
// string because you used JSON.stringify and it is a string, do not stringify, if you need an object
{
var js = new JavaScriptSerializer();
var objetModel = js.Deserialize<MyViewModel>(model);
var obj = //call something here then return resulting obj
return Json(obj, JsonRequestBehavior.AllowGet);
}
I did not test it - it is just to get you an idea how to pass an additional information along with the uploaded binary file
I have a facebook app that works in all other browsers but IE. Here is my javascript code:
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
window.fbAsyncInit = function() {
FB.init({
appId : '123456789', // App ID
channelUrl : 'http://test/channel.php', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse XFBML
oauth : true // turn on oauth
});
// Additional initialization code here
};
function start() {
//send initial AJAX request
var bike_var = $("select#bike").val();
var reason_var = $("textarea#reason").val();
var dataString = 'bike='+ bike_var + '&reason=' + reason_var;
$.ajax({
type: "POST",
url: "save.php",
data: dataString,
success: function(data) {
//set ID in the form
$("input#recordID").val(data);
doLogin();
}
});
}
function doLogin() {
//Do request to Facebook to get user details and then post to wall and the submit the form
FB.login(function(response) {
if (response.authResponse) {
getUserInfo();
} else {
alert("Sorry! We can't enter you into the competition unless you allow our Facebook app!");
}
}, {scope: 'email, publish_stream'});
}
function getUserInfo() {
FB.api('/me', function(info) {
$("input#name").val(info.name);
$("input#email").val(info.email);
$("input#FID").val(info.id);
var params = {};
params['message'] = $("textarea#reason").val();
params['name'] = 'Test';
params['description'] = '';
params['link'] = 'http://www.facebook.com/ChainReactionCycles';
params['picture'] = 'http://crc.test/img/logo.gif';
params['caption'] = 'Test';
postToWall(params);
});
}
function postToWall(param) {
FB.api('/me/feed', 'post', param, function(wall) {
if (!wall || wall.error) {
} else {
document.forms["comp-entry"].submit();
}
});
}
Here is code for my submit button that kicks off the code, currently working in all other browsers:
<input type="submit" name="submit_button" value="Enter Competition" onclick="start(); return false;">
In IE, this just goes to a blank page with the record ID of the new record, but in my database none of the required facebook fields are filled. The error in IE when i debug is 'SCRIPT5002: Function expected'. If anyone has any ideas i would be eternally grateful
I had the same error message on my script and googled for that error code, so I accidently stumbled across your question. your line of code, that kicks the error helped me, so I can help you now.
Obviously IE 9 does not like "start" as a function name. I had the same function in my code, and after I found that redundancy between my own code and yours, I replaced the function name, et voila, everything works fine now.
In the following code
var entryTemplate = document.getElementById('entryTemplate');
entryTemplate = entryTemplate.firstChild;
for (var ipost in posts)
{
var post = posts[ipost];
var clone = entryTemplate.cloneNode(true);
clone = $(clone);
if (post.imageURL)
{
var imgElement = document.createElement('img');
var largeImageURL = post.largeImageURL ? post.largeImageURL : post.imageURL;
imgElement.src = post.thumbPresent ? POST_THUMB_URL + '/' + post.postID : largeImageURL;
imgElement.alt = '';
clone.find('div.BlogImageURL a').attr('href', largeImageURL).text(largeImageURL);
clone.find('div.BlogImage a').attr('href', imgElement.src).append(imgElement);
// get bytesize
var postdata = 'inline_image_url=' + encodeURIComponent(post.imageURL);
postdata += '&linked_image_url=' + encodeURIComponent(post.largeImageURL);
$.ajax({
type: 'POST',
url: ASYNC_GET_BYTESIZE_URL,
data: postdata,
success: function(bytesize) {
clone.find('.BlogImageBytesize').html(bytesize);
}
});
}
else
{
clone.find('div.BlogImageURL').text('(This post contains no images)');
clone.find('div.BlogImage').remove();
}
$('#outputDiv').append(clone);
}
clone.find('.BlogImageBytesize').html(bytesize);
All ajax responses (bold line) modify the last clone, probably because the loop is finished when the first response arrives and clone points to the last clone.
How can I fix this?
Thanks.
Perhaps you could set clone as the context of your ajax call. (See docs here.) Then, I think it would work something like this:
$.ajax({
type: 'POST',
url: ASYNC_GET_BYTESIZE_URL,
data: postdata,
context: clone,
success: function(bytesize) {
$(this).find('.BlogImageBytesize').html(bytesize);
}
});
I don't know for sure if the context has to be a plain DOM element or if it can be a jQuery object, but hopefully this gets you on the right track.