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
Related
I have a form with some fields and file upload, rendering as a partial view using ajax in asp.net MVC. when submitting the form, I want to pass all the data to the controller. But if I use $("form").serialize(), it is not passing the selected file to the controller. So I am using formData() to pass the data to the controller. Till this point, everything works fine.
But after adding captcha using CaptchaMvc, it not reaching the controller. Even if I enter valid captcha, it is invalid in the controller.
This is how I send data to the controller using the ajax and formData
var data = new FormData();
var vidFile = null;
if ($("#FileUpload")[0].files.length > 0)
vidFile = $("#FileUpload")[0].files[0];
data.append("detail", $("#detail").val());
data.append("name", $("#name").val());
data.append("FileUpload", vidFile);
$.ajax({
url: "/home/submitData",
type: "POST",
contentType: false,
processData:false,
data: data,
success: function (response) {
if (response.success == true) {
} else {
}
}
});
Is there any way to pass the captcha as well to the controller?
Why can't you validate using different controller function, as follows:
At the time of submission, validate the captcha first, and depending on the result, call another controller function to submit data or show the error.
var submitData = function(){
var data = new FormData();
var vidFile = null;
if ($("#FileUpload")[0].files.length > 0)
vidFile = $("#FileUpload")[0].files[0];
data.append("detail", $("#detail").val());
data.append("name", $("#name").val());
data.append("FileUpload", vidFile);
$.ajax({
url: "/home/submitData",
type: "POST",
contentType: false,
processData:false,
data: data,
success: function (response) {
if (response.success == true) {
//Success
} else {
//Submission failed
}
}
});
}
var validateCaptcha = function(){
$.ajax({
url: "/home/validateCaptcha",
type: "POST",
data: $("form").serialize(),
success: function (response) {
if (response.success == true) {
submitData();
} else {
alert("Invalid Captcha entry");
}
}
});
}
$("form").submit(function(e){
validateCaptcha();
});
Can anybody help me to find what is wrong with my codes for passing form data and Listbox data to controller by ajax?
Here is the ajax code:
$("#btnGetData").click(function () {
var button1 = "getdata";
var listItms = $('#ChooseRight').val(); // this is Lisbox field in Razor view
var formData = $('#GenForm').serialize(); //the Form ID of razor view
var wildcardprodtype = $('#WildCardProdType').val();
$.ajax({
type: 'POST',
url: '/Report/LongRunningProcess', //controller name
data: JSON.stringify({
button: button1,
viewModel: formData,
ChooseRight: listItms,
WildCardProdType: wildcardprodtype
}),
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
success: function (data) {
}
});
Here is the controller, in debug, I can see the data of "button", WildCardProdType are passed properly, but not the data of viewModel and ChooseRight list. Any reason why?
public ActionResult LongRunningProcess(string button, ReportViewModel viewModel, List<string> ChooseRight, string WildCardProdType)
{
....
here is the #HtmlBegin form header:
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "GenForm" } ))
{
By the way, the current razor view use ReportViewModel as this:
#model MVCPROD.Models.ViewModels.ReportViewModel
Use serializeArray() instead serialize() so that you can include more items in the form serialized array.
$("#btnGetData").click(function () {
var button1 = "getdata";
var listItms = $('#ChooseRight').val();
var wildcardprodtype = $('#WildCardProdType').val();
var formData = $('#GenForm').serializeArray();
//Below three lines are not required if ChooseRight, WildCardProdType elements are inside the form
formData.push({ name: 'button', value: button1 });
formData.push({ name: 'listItms', value: listItms });
formData.push({ name: 'wildcardprodtype', wildcardprodtype });
$.post(
'/Account/LongRunningProcess',
formData,
function (response) {
}
);
});
In my asp mvc project i've got an ajax call that posts the value of a dropdown list and i want the session to be set with this value.
$('#dropDownMenu').on('click', 'li', function () {
var txt = $('#schoolButtons').text();
data = {session: txt};
var requestValue = JSON.stringify(data);
$.ajax({
url: '#Url.Action("SetSession")',
type: 'POST',
data: "requestValue="+requestValue ,
}).success(function (data, textStatus, jqXHR) {
});
});
public ActionResult SetSession(string requestValue)
{
var sessionVal = Convert.ToString(requestValue);
if (sessionVal==null)
{
Debug.WriteLine("session is null");
}
Session["key"] = sessionVal;
return Json(requestValue);
}
When I output the value of the session i'm getting the string {"session":"State School"} when all i want is "State School". I know in the function data is set to {session: txt} but how do i just extract that txt?
Regards,
Mike.
To read the JSON value you need to read it this way
var requestValue = data.session
Since you pass it as a string into the function and want to read it in the function, this is what I sugggest you do. You need to convert the string to JSON and extract the value.
public ActionResult SetSession(string requestValue)
{
var JSONData = JSON.parse(requestValue);
var sessionVal = JSONData.session;
...
...
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" />
$.ajax({
type: 'GET',
dataType: 'image/jpeg',
url: '/Home/GetImage/' + img ,
success: function (data) {
i = new Image();
i.src = data;
$('#imageresult').append(i);
},
error: function () {
alert('error');
},
});
[HttpGet]
public ActionResult GetImage(string img)
{
string imageFile = System.Web.HttpContext.Current.Server.MapPath("~/Profile/Small/" );
var path = Path.Combine(imageFile, img );
var srcImage = Image.FromFile(path);
var stream = new MemoryStream();
srcImage.Save(stream, ImageFormat.Jpeg);
return File(stream.ToArray(), "image/jpeg");
}
It always falls into error function. If i remove dataType, then it doesn't fall into error function but it just shows long strings in the view. Why doesn't that work and show image in view?
You can do something Like this:
public ActionResult GetImage(string img)
{
string imageFile = System.Web.HttpContext.Current.Server.MapPath("~/Profile/Small/" );
var path = Path.Combine(imageFile, img );
var srcImage = Image.FromFile(path);
var stream = new MemoryStream();
srcImage.Save(stream, ImageFormat.Jpeg);
return Json(Convert.ToBase64String(stream.ToArray()), JsonRequestBehavior.AllowGet);
}
and the Ajax call:
$.ajax({
type: 'GET',
url: '#Url.Action("GetImage", "Home")',
success: function (data) {
$("#ItemPreview").attr('src', 'data:image/png;base64,' + data);
},
error: function () {
alert('error');
},
});
and the view:
<img id="ItemPreview" src="" />
of course you can append img dynamically, then bind its source after.
You are confusing the URL of an image with its actual content (the graphic bytes).
The /GetImage call returns the bytes, but you can never put data bytes in the i.src attribute because that attribute needs to be fed a URL.
It might work if you forget about the Ajax call and just use i.src = '/Home/GetImage/' + img;.