Sending object to a controller in asp.net mvc using ajax - c#

I have issue with sending object contains array to a controller
this is my js code
var messageId = 0;
function DraftMessage()
{
var to = [];
var i = 0;
$('#to option:selected').each(function (index, element) {
to[i++] = $(element).val();
});
console.log(to);
$.ajax({
type: "POST",
url: "#Url.Action("DraftMessage", "Activities")",
datatype: "json",
traditional: true,
async: false,
data: { "id": messageId, "To": to, "Title": $("#title").val(), "Project": $("#project").val(), "AreaId": $("#areaId").val(), "Body": $("#messageBody").val() },
beforeSend: function () { }
}).done(function (Id) {
console.log(Id);
messageId = Id;
});
}
$("input, select, textarea").change(function () { DraftMessage(); });
var contents = $('.note-editable').html();
$(".compose-message").on("blur", ".note-editable", function () {
if (contents != $(this).html()) {
DraftMessage();
contents = $(this).html();
}
});
and this is my controller side
public int DraftMessage(message draftMessage, HttpPostedFileBase[] files = null)
{
return new MessageActions().DraftMessage(draftMessage);
}
my issue is that the ajax request always send the to array as null, I do not know what is wrong so could anyone help me to resolve this issue.

Can you change your request and use
dataType: "json",
contentType: "application/json;charset=utf-8",
This should work. Please let me know.

Try this. Push your object to array and send it as Json.
array.push({yourobject datas here})
$.ajax({
type: "POST",
url: '/DraftMessage/Activities',
contentType: 'application/json',
data: JSON.stringify(array),
success: function (d) {
..
},
error: function (xhr, textStatus, errorThrown) {
console.log(errorThrown);
}
});
Convert your controller function's return type to JSonResult.
Hope helps.

do you want upload file using ajax ?!!
use the normal usage of form not the Ajax.BeginForm then in form submit event
write your code like this:
$('#Form').submit(function () {
var xhr = new XMLHttpRequest();
var fd = new FormData();
var file = $('#Image').val();
if (file) {
var fname = $('#Image')[0].files[0].name;
if (CheckFile(file)) {
var uploadFile = document.getElementById('Image').files[0];
var myArray = [];
myArray.push(uploadFile);
if (myArray.length > 0) {
for (var i = 0; i < myArray.length; i = i + 1) {
fd.append("File1", myArray[i]);
}
}
}
else {
return false;
}
}
fd.append("ID", messageId);
fd.append("Title", $('#Title').val());
fd.append("Project", $('#Project').val());
fd.append("AreaId", $('#AreaId').val());
fd.append("Body", $('#messageBody').val());
var form = $('#Form');
var token = $('input[name="__RequestVerificationToken"]', form).val();
fd.append("__RequestVerificationToken", token);
xhr.open("POST", "/ControllerName/Action/", true);
xhr.send(fd);
xhr.addEventListener("load", function (event) {
if (event.target.response != "OK") {
OnFail(event.target.response);
}
else {
OnSuccess(event);
}
}, false);
return false;
})
server side in controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult actionName(Model pModel){
HttpPostedFileBase File = Request.Files["File1"];
if (File != null && File.ContentLength != 0){
//do what you want
return Content("OK");
}
else{
Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
return Content("Error Messages", System.Net.Mime.MediaTypeNames.Text.Plain);
}
}

You can try a different approach. You can serialize your entire form by doing something like this:
var formdata = $("#frmEmailInfo").serialize();
and then post it to the Controller:
$.ajax(
{
type: "POST",
data: formdata,
dataType: 'json',...

Related

JQuery ajax success never run

i have this jquery code, sending items to controller and download from controller, everything is fine
downloads is fine, i check response from in Chrome Network Tab is okay. but success function never run after process done. (i'm using async:false; already)
$(document).on('click', '#baslat', function (e) {
var token = $("#token").val();
var islemler = [];
var secililer = [];
$.each($("input[class='cc']:checked"), function () {
var islem = {};
islem.IslemTuru = $(this).attr("id");
islemler.push(islem);
});
$.each($("tr[class='sec']"), function () {
if ($(this).children('td:eq(1)').children("input[type='checkbox']").prop('checked')) {
var beyan = {};
beyan.Id = $(this).attr("id");
beyan.TahakkukId = $(this).data("id");
beyan.KisaKod = $(this).children('td:eq(2)').html();
beyan.BeyannameTuru = $(this).children('td:eq(4)').html();
beyan.Ay = $(this).children('td:eq(5)').html().substring(8, 10);
beyan.Yil = $(this).children('td:eq(5)').html().substring(11, 16);
secililer.push(beyan);
}
});
$.ajax({
url: '/Ebeyan/BeyanAl',
type: "POST",
dataType: "string",
async: false,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ secililer, islemler, token }),
success: function (data) {
$("#mesaj").html(data);
alert("done.");
}
});
});
The controller is here. I have to use Thread.Sleep (1000) in the method. because the server on which I want to download files wants 1 second to pass between each request.
public async Task<string> BeyanAl(List<Beyanname> secililer, List<Islem> islemler, string token)
{
bool indir = true;
bool yazdir = false;
bool gonder = false;
foreach (var islem in islemler)
{
if (islem.IslemTuru =="cbyazdir")
{
yazdir = true;
}
if (islem.IslemTuru == "cbgonder")
{
gonder= true;
}
}
foreach (var GelenBeyan in secililer)
{
string YolAdi = YolHazirla(GelenBeyan);
string DosyaAdi = DosyaAdiHazirla(GelenBeyan);
await dosyaindir(token, YolAdi + "/" + DosyaAdi, "Beyan", GelenBeyan.Id, "");
await dosyaindir(token, YolAdi + "/" + DosyaAdi, "Tahakkuk", GelenBeyan.Id, GelenBeyan.TahakkukId);
}
return "İndirildi";
}
here is chrome response screens
r1
r2
There is no 'string' data type in ajax datatypes make it json or text
$.ajax({
url: '/Ebeyan/BeyanAl',
type: "POST",
dataType: "string", <-- make it json or text
async: false,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ secililer, islemler, token }),
success: function (data) {
$("#mesaj").html(data);
alert("done.");
}
});

jQuery AJAX Not Calling A C# Function In ASP.NET MVC

Basically, I am trying to call controller from views using jQuery ajax but it's not calling controller.
What I have to do is passing my token value from registration page to controller so that I will use its value for user registration.
< script type = "text/javascript" >
document.getElementById('LoginWithAmazon').onclick = function() {
options = {
scope: 'profile'
};
amazon.Login.authorize(options,
function(response) {
if (response.error) {
alert('oauth error ' + response.error);
return;
}
GetProfileInfo(response.access_token);
});
function GetProfileInfo(token) {
$.ajax({
type: 'GET',
url: '/Account/ProfileInfo',
data: {
token: 'abc'
},
cache: false,
success: function(result) {
alert(result);
}
});
}
function receiveResponse(response) {
if (response != null) {
for (var i = 0; i < response.length; i++) {
alert(response[i].Data);
}
}
}
return false;
};
< /script>/
Here below is my controller code
public JsonResult ProfileInfo(string token) {
return Json("test", JsonRequestBehavior.AllowGet);
}
I need to pass the token value from registration page to my controller
Try to change this in the controller
return Json("test", JsonRequestBehavior.AllowGet);
into
enter code herereturn Json(new { value="test" }, JsonRequestBehavior.AllowGet);
and change your js to be like this
$.ajax({
type: 'GET',
url: '/Account/ProfileInfo',
data: JSON.stringify({
token: 'abc'
}),
cache: false,
success: function(result) {
alert(result);
}
});
Finally, i have solved the problem.I am unable to call the account controller so i have used my home controller for this purpose.Here below is the code that i have used for calling controller :
<script type="text/javascript">
document.getElementById('LoginWithAmazon').onclick = function() {
options = { scope : 'profile' };
amazon.Login.authorize(options, function(response) {
if ( response.error ) {
alert('oauth error ' + response.error);
return;
}
GetProfileInfo(response.access_token);
});
function GetProfileInfo(token)
{
var url = "/home/ProfileInfo?token=" + token;
var request = $.ajax({
url: url,
method: "GET",
dataType: "json"
});
request.done(function (msg) {
var data = [];
alert(msg);
});
request.fail(function (jqXHR, textStatus) {
});
}
}
</script>

MVC Redirecting Action using Json

Purpose: The code written is suppose to save all the contents using Json and re direct to action.
Problem:
The current redirect using Json does not allow the redirection as suppose.
return new JsonResult { Data = new { status = status } };
The code is below for reference: Looking for suggestions:
View Code
$.ajax({
url: '/SA/Save',
type: "POST",
data: JSON.stringify(data),
dataType: "JSON",
contentType: "application/json",
success: function (d) {
//check is successfully save to database
if (d.status == true) {
//will send status from server side
alert('Successfully done.');
window.location.href = d.Url;
//clear form
t = [];
d = [];
r = [];
$('#SN').val('');
$('#SA').val('');
$('#t').empty();
$('#d').empty();
$('#r').empty();
}
else {
alert('Failed');
}
$('#submit').val('Save');
},
});
Controller
public JsonResult Save(SAVM O,)
{
bool status = false;
var userId = User.Identity.GetUserId();
if (ModelState.IsValid)
{
SA s = new SA
{
}
_db.SA.Add(O)
_db.SaveChanges();
status = true;
}
else
{
status = false
}
return new JsonResult { Data = new { status = status } };
}
Here want to redirect like this:
return RedirectToAction("F", "SA");
but using JsonResult
Solution
View
$.ajax({
url: '/SA/Save',
type: "POST",
data: JSON.stringify(data),
dataType: "JSON",
contentType: "application/json",
success: function (d) {
window.location.href = d.Url;
})
} });
Controller
public JsonResult Save(SAVM O,)
{
var userId = User.Identity.GetUserId();
if (ModelState.IsValid)
{
SA s = new SA
{
}
_db.SA.Add(O)
_db.SaveChanges();
return Json(new { Url = "F/SA" });
}
You have a couple of options here, you decide which one you prefer based on your requirements.
Do not use AJAX. AJAX requests are meant for data required for the current page. You should use a synchronous request for the redirection.
Return the URL to which the client should redirect on the success event:
return Json(new { url = "/F/SA" });
And then:
success: function (d)
{
window.location.url = d.url;
}
Return the already rendered View and load it to the current page:
return View("some view...");
And then:
success: function (d)
{
$("#someElement").html(d);
}

How to send anti forgery token with Ajax file upload?

I'm trying to upload file(s) with an ajax call and validate the anti forgery token. I've had a look around and built a method to validate the anti forgery token on the controller. However whenever I have #Html.AntiForgeryToken on the view, my files do not get populated. Even though it validates the anti forgery token. It doesn't seem to be getting sent with the request but I'm unsure why.
ajaxSendOverride:
$(document).ready(function () {
var securityToken = $('[name=__RequestVerificationToken]').val();
$(document).ajaxSend(function (event, request, opt) {
if (opt.hasContent && securityToken) { // handle all verbs with content
var tokenParam = "__RequestVerificationToken=" + encodeURIComponent(securityToken);
opt.data = opt.data ? [opt.data, tokenParam].join("&") : tokenParam;
// ensure Content-Type header is present!
if (opt.contentType !== false || typeof event.contentType !== 'undefined') {
request.setRequestHeader("Content-Type", opt.contentType);
}
}
});
});
Ajax:
$(document).on("submit", "[data-upload-contract-form]", function (e) {
e.preventDefault();
var formData = new FormData($('[data-upload-contract-form]')[0]);
if ($('[data-upload-file]').val() != "") {
$.ajax({
url: $(this).attr('action'),
data: formData,
type: 'POST',
processData: false,
contentType: false,
headers: {
'__RequestVerificationToken': $('[name=__RequestVerificationToken]').val()
},
success: function (data) {
if (data.Success === true) {
$('[data-contract-error-message]').text();
ReturnDataTableForUploadFile($('[data-upload-file-supplier-contract-id]').val());
table.ajax.reload();
}
else {
$('[data-contract-error-message]').show();
$('[data-contract-error-message]').text(data.ResponseText);
}
}
})
.fail(function () {
$('[data-contract-error-message]').show();
$('[data-contract-error-message]').text("Something went wrong uploading your file, please try again.");
});
}
else {
$('[data-contract-error-message]').show();
$('[data-contract-error-message]').text("No contract to upload");
}
});
Validation:
public sealed class AuthorizeAntiForgeryToken : System.Web.Mvc.FilterAttribute, System.Web.Mvc.IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
var httpContext = filterContext.HttpContext;
var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
AntiForgery.Validate(cookie != null ? cookie.Value : null,
httpContext.Request.Headers["__RequestVerificationToken"]);
}
}
Controller:
public async Task<JsonResult> UploadContract(UploadContract model)
{
if (ModelState.IsValid)
{
try
{
foreach (var item in model.Contracts)
{
string filePath = WebConfigurationManager.AppSettings["SupplierContractPath"] + GetSelectedClientId() + "\\" + item.FileName;
_supplierFileManager.UploadFile(item, filePath);
await _supplierFileManager.SaveContractToDatabase(model.SupplierContractID, item.FileName);
}
return Json(new { Success = true });
}
catch (Exception e)
{
return Json(new { Success = false, ResponseText = e.Message });
}
}
else
{
string errorMessage = "";
foreach (var item in ModelState.Values.SelectMany(r => r.Errors))
{
errorMessage += "<p>" + item.ErrorMessage + "</p>";
}
return Json(new { Success = false, ResponseText = errorMessage });
}
}
How can I send my files with the anti forgery token?
I ran into this problem myself today and ran into this question without an answer. The links to other answers didn't work, but after a while I found the solution.
The anti-forgery token has to be in a form field, not a header. It also has to be the first field in the form data. So to solve it, do:
$(document).on("submit", "[data-upload-contract-form]", function (e) {
e.preventDefault();
var formData = new FormData();
formData.append('__RequestVerificationToken', $('[name=__RequestVerificationToken]').val());
formData.append('file', $('[data-upload-contract-form]')[0]);
if ($('[data-upload-file]').val() != "") {
$.ajax({
url: $(this).attr('action'),
data: formData,
type: 'POST',
processData: false,
contentType: false,
success: function (data) {
if (data.Success === true) {
$('[data-contract-error-message]').text();
ReturnDataTableForUploadFile($('[data-upload-file-supplier-contract-id]').val());
table.ajax.reload();
}
else {
$('[data-contract-error-message]').show();
$('[data-contract-error-message]').text(data.ResponseText);
}
}
})
.fail(function () {
$('[data-contract-error-message]').show();
$('[data-contract-error-message]').text("Something went wrong uploading your file, please try again.");
});
}
else {
$('[data-contract-error-message]').show();
$('[data-contract-error-message]').text("No contract to upload");
}
});
My own function (using jQuery) which works fine: (it's not complete, but at least it reports back it received the file ;))
<script type="text/javascript">
function uploadFileThroughForm(messageId) {
var form = $('#addAttachmentForm');
if (form.valid()) {
var files = $('#filenameToUpload').prop('files');
if (files.length > 0) {
if (window.FormData !== undefined) {
var formData = new FormData();
formData.append("__RequestVerificationToken", $('#addAttachmentForm input[name=__RequestVerificationToken]').val());
formData.append("file", files[0]);
$.ajax({
type: "POST",
url: '#ApplicationAdapter.GetVirtualRoot()Attachment/Add/' + messageId,
contentType: false,
processData: false,
data: formData,
success: function(result) {
alert(result.responseMessage);
},
error: function(xhr) {
alert(xhr.responseText);
}
});
} else {
alert("This browser doesn't support HTML5 file uploads!");
}
}
}
}
</script>
Hope this helps, even if it's been a while since you asked this question!

MVC post with data and return json data

I have a controle like this
public JsonResult GetSizes(long Id)
{
try
{
//get some data and filter y Id
}
catch (Exception ex) { }
return Json(//data);
}
I need to get that by following json by ajax request
var sizes = [];
$.ajax({
type: 'POST',
async: false,
data: { 'Id': selectedId },
url: "/<Controler name>/GetSizes",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
error: function (xhr) {
alert('Error: ' + xhr.statusText);
return false;
},
success: function (result) {
if (result.Result != null) {
if (result.Result.length > 0) {
sizes = result;
}
}
}
});
But this give me an Server error. How can i fix this.
replace your
url: "/<Controler name>/GetSizes",
by
url: "#Url.Action("GetSizes", "Controller_Name"),
and is you Ajax will have to be
async: false?
then try to use this as your Action
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetSizes(long Id)
{
try
{
//get some data and filter y Id
}
catch (Exception ex) { }
return Json(//data);
}
Also, try to put a break point on your action and see in debug mode if your Ajax reaches your Action.
this my demo, you can do the same:
$.ajax({
url: '#Url.Action("CheckCity", "BookingStarts")',
data: { packageId: packageid, cityId: valuecities[valuecities.length - 1] },
type: 'POST',
dataType: 'json',
success:
function(result) {
if (result.Status == true) {
$('#CheckoutDateHotel_#item.CityId').val(result.Date);
}
}
});
in controller :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CheckCity(int packageId, int cityId)
{
var packageCityModel = PackageDetails.GetPackageCitiesByPackageId(packageId).OfType<HMSService.PackageCity>();
var package = new PackageReservationMasterDal();
var itemPackage = package.GetPackageDetailByPackageId(packageId);
var result = "";
var city = packageCityModel.FirstOrDefault(x => x.CityId == cityId);
if (city != null)
{
result = itemPackage.TravelDateFrom.AddDays(city.NoOfNights).ToShortDateString();
}
return Json(new { Status = true, Date = result });
}
See the problem here is that you have not stringified your Data Transfer Object(DTO).
A cleaner approach will be this.
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/json3/3.3.0/json3.js"></script>
<script type="text/javascript">
var sizes = [];
var DTO = { 'Id': selectedId };
$.ajax({
type: 'POST',
async: false,
data: JSON.stringify(DTO),
url: "#Url.Action("GetSizes", "Home")",
dataType: 'json',
contentType: 'application/json'
}).done(function(result) {
if (result.Result != null) {
if (result.Result.length > 0) {
sizes = result;
}
}
}).fail(function(xhr) {
alert('Error: ' + xhr.statusText);
return false;
});
</script>
Please note the use of
JSON.stringify
#Url.Action helper
jqXHR.done(function( data, textStatus, jqXHR ) {});
jqXHR.fail(function( jqXHR, textStatus, errorThrown ) {});
Also you are using async=false which I guess is to grab all the sizes before exiting from the function. jQuery.deferred will be an interesting read.

Categories