I'm creating mvc 4 application where I call a function in controller from a js file using ajax.
When I call the function from ajax, its calling the respective function properly. But neither success nor error function is not firing . Could someone help me out to correct my mistake?
I would like to read the data from database convert it to json format and write it into a .js file and thereafter success function to be fired off. Help me to solve this. Thanks in advance.
Here is my Code.
$.ajax({
//url: '#Url.Action("getJsonData","Home")',
url: "Home/getJsonHugeData1",
//data: "{}",
type: "GET",
//contentType: 'application/json',
//dataType: "json",
success: function () {
alert();
alert('success getJsonHugeData');
loaddata(data);
},
error:function(){
alert('error');
}
});
Controller:
public JsonResult getJsonHugeData()
{
var users = GetUsersHugeData();
string json = "var dataSource=";
json += JsonConvert.SerializeObject(users.ToArray());
System.IO.File.WriteAllText(Server.MapPath("/Scripts/NewData.js"), json);
return Json(users, JsonRequestBehavior.AllowGet);
}
private List<UserModel> GetUsersHugeData()
{
var usersList = new List<UserModel>();
UserModel user;
List<dummyData> data = new List<dummyData>();
using (Database1Entities dataEntity = new Database1Entities())
{
data = dataEntity.dummyDatas.ToList();
}
for (int i = 0; i < data.Count; i++)
{
user = new UserModel
{
ID = data[i].Id,
ProductName = data[i].ProductName,
Revenue = data[i].Revenue,
InYear = data[i].InYear.Year
};
usersList.Add(user);
}
}
I believe your browser will block the file downloaded via ajax, this is because JavaScript cannot interact with disk. If you want to get this working, you will have to do so using a form post.
#using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { id = "DownloadForm" }))
{
... form data would be here if you had any...
<button type="submit">Download</button>
}
You would then return a FileStreamResult with the contents of the file to be downloaded.
public ActionResult Action(FormModel model)
{
// Do work to get data for file and then return your file result to the browser.
return new FileStreamResult(new MemoryStream(fileData), "text/csv") // set the document type that is valid for your file
{
FileDownloadName = "users.csv"
};
}
I ran all of your code except for the following since you didn't provide the UserModel and dummydata classes in your question:
private List<UserModel> GetUsersHugeData()
{
var usersList = new List<UserModel>();
UserModel user;
List<dummyData> data = new List<dummyData>();
using (Database1Entities dataEntity = new Database1Entities())
{
data = dataEntity.dummyDatas.ToList();
}
for (int i = 0; i < data.Count; i++)
{
user = new UserModel
{
ID = data[i].Id,
ProductName = data[i].ProductName,
Revenue = data[i].Revenue,
InYear = data[i].InYear.Year
};
usersList.Add(user);
}
}
The end result was that you had a typo in your ajax 'url' parameter. Also, if you are going to check for errors, set your function to
function(jqxhr, status, error) {
alert(error);
}
to check the error being thrown.
Related
I've got working code in JQuery Ajax, however I've been told I have to use Native JS code to use it, and I'm not very familiar with using native JS for ajax, and most of the internet examples are basic ones. Basically, I have this object:
var Narudzba =
{
SifraNarudzbe: "AAA",
DatumNarudzbe: "",
Osigurano: document.getElementById("checkOsiguranje").value,
BrzaDostava: document.getElementById("checkBrza").value,
KlijentId: document.getElementById("klijentid").value,
Adresa: AdresaVar,
StatusNarudzbeID: 2,
Primaoc: PrimaocVar,
VrijemeIsporuke: null,
CijenaNarudzbe: UkupnaCijena,
NacinPlacanja: parseInt(document.getElementById("NacinPlacanja_Select").value)
};
Which I'm trying to post to my Controller. Here's how my working code in Jquery Ajax looks:
$.ajax({
url: "/klijentarea/klijent/SnimiNarudzbu",
data: Narudzba,
type: 'POST',
success: function (data) {
for (var i = 0; i < stavke_niz.length; i++) {
stavke_niz[i].NarudzbeId = parseInt(data);
}
stavke_niz = JSON.stringify(stavke_niz);
$.ajax({
url: "/klijentarea/klijent/SnimiStavke",
type: "POST",
dataType: "json",
data: stavke_niz,
contentType: 'application/json',
success: function (data) {
if (data === true) {
var id = document.getElementById("klijentid").value;
window.location.href = '/KlijentArea/Klijent?id=' + id;
}
}
});
}
});
Basically, it creates an order (Narudzba) with all sorts of details, posts it to this controller:
[HttpPost]
public int SnimiNarudzbu(Narudzbe Narudzba)
{
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var stringChars = new char[8];
var random = new Random();
for (int i = 0; i < stringChars.Length; i++)
{
stringChars[i] = chars[random.Next(chars.Length)];
}
var finalString = new String(stringChars);
Narudzba.SifraNarudzbe = finalString;
Narudzba.DatumNarudzbe = DateTime.Now;
ctx.Primaoci.Add(Narudzba.Primaoc);
ctx.Naruzbee.Add(Narudzba);
ctx.SaveChanges();
int newid = Narudzba.Id;
return newid;
}
Then I use the returned new ID, and assign it to all the objects inside stavke_niz, which is an array of order listings which gets created elsewhere in the code, and require OrderID before being added to database (I can add that code as well if necessary). Then the array with the updated OrderIDs gets sent to this controller:
[HttpPost]
public string SnimiStavke(IEnumerable<StavkaNarudzbe> stavke_niz)
{
if (stavke_niz != null)
{
ctx.StavkeNarudzbi.AddRange(stavke_niz);
ctx.SaveChanges();
return "true";
}
return "false";
}
Which successfully accepts the JSON posted with AJAX and adds the stuff to the database. Now, when I try to post in Native, like so:
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status === 200 && this.readyState === 4)
{
alert(this.getAllResponseHeaders());
}
};
xhr.open('POST', '/klijentarea/klijent/SnimiNarudzbu', true);
xhr.send(Narudzba);
All of the values inside "Narudzba" are null, despite the object clearly having all the right values before being posted to controller. Help would be greatly appreciated.
You are missing Content-Type setting in your xhr request.
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
This should solve your problem.
Hope this helps!
Whilst debugging, using Unit Tests, the function returns the expected data, however when the same function is called from JavaScript, the function is hit but then doesn't return any data.
This function that I'm calling that's in the dll is hanging, but only when it is called by a function that has been called by a JS request, why would this be?
EDIT:
As in comments, my best guess is that it is something to do with a thread being in use, but I don't know, as the function itself is working, just not when called from a C# function called by AJAX.
AJAX call :
function getOnHoldTickets() {
$.ajax({
type: "GET",
url: "/cloud/getTicketCount/",
dataType: "json",
success: function (data) {
onHoldHandler(data);
},
failure: function () {
alert("getOnHoldTickets failled");
}
});
}
Controller :
// api gets hit from the JS call
[Route("cloud/getTicketCount")]
public List<UberTicket> getTicketCount()
{
var tickets = Dashboard.getTODTickets("On Hold");
return tickets;
}
[TestMethod] // calls the same method as JS
public void supportTicketTesting()
{
var openTickets = Dashboard.getTODTickets("On Hold");
var check = openTickets != null;
}
// method calling the dll
public static List<UberTicket> getTODTickets(string type)
{
var tickets = UberAPI.getTODTickets(type);
return tickets;
}
DLL Method:
// the method within the dll that's hanging when called by a function invoked by JS
public static async Task<RootObjectClass<T>> genericGet<T>(string function, string parameters)
{
try
{
// create credentials to pass to httpClient
var httpClientCredentials = new HttpClientHandler()
{
Credentials = new NetworkCredential(uberAPIUser, uberAPIPass)
};
using (var client = new HttpClient(httpClientCredentials))
{
// unsure if the headers are being passed in correctly - getting good response though
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded");
var response = await client.GetAsync(ubersmithURL + function + parameters);
var result = await response.Content.ReadAsStringAsync();
// remove nulls from json
result = Regex.Replace(result, ":null,", ":\"\",");
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var success = JsonConvert.DeserializeObject<RootObjectClass<T>>(result);
return success;
}
}
catch(Exception ex)
{
// log error
}
return new RootObjectClass<T>();
}
While this might not be addressing the issue fully, you should not be returning C# Data types as JavaScript won't be able to parse them and will result in an error similar to this in the worst case
System.Collections.Generic.List`1[...]
Like I said in my comment, you should return a JsonResult from your controller to retrieve the data in JS.
[Route("cloud/getTicketCount")]
public JsonResult getTicketCount()
{
var tickets = Dashboard.getTODTickets("On Hold");
return Json(tickets ,JsonRequestBehavior.AllowGet);
}
Understanding JsonRequestBehavior.AllowGet
and your Ajax call
$.ajax({
type: "GET",
url: "/cloud/getTicketCount/",
dataType: "json"
})
.done(function(data){
console.log(data);
})
.fail(function(xhr){
console.log(xhr.responseText);
});
Edit:
I believe this is a deadlock issue you have. Perfect answer elaborating the issue is here.
Trying to save a file to a db. I am using formData via javascript to append the file and adding this as a post object via ajax. for some reason nothing gets sent.
What am I doing wrong?
HTML
<input type="file" style="display: none;" class="btn btn-primary uploadFile">
script:
$(".saveImage")
.on("click",
function() {
var files = $(".uploadFile");
var data = new FormData();
data = $.OverWatch.worker.uploadFileHandler.addUploadFiles(files, data);
$.OverWatch.worker.postUserData("/Administration/AddUserImage", data, function () {
alert("done");
});
});
Functions above look like:
addUploadFiles: function (files, data) {
$.each(files, function (i, v) {
var file = $(this).data("files");
data.append("file", file);
});
return data;
}
postUserData:
postUserData: function(url, data, callback) {
$.LoadingOverlay("show");
$.ajax({
url: url,
type: 'POST',
data: data,
cache: false,
processData: false,
contentType: false,
dataType: "HTML",
success: function(data) {
if (callback) {
callback(data);
$.LoadingOverlay("hide");
}
},
error: function(event, jqxhr, settings, thrownError) {
//$.helpers.errorHandler($("#fileDialogErrors"), event.responseText);
var h;
$.LoadingOverlay("hide");
}
});
},
backend:
public ActionResult AddUserImage()
{
if (Request.Files.Count != 0)
{
//save
}
return null;
}
edit:
var files = $(".uploadFile");
returns:
Your var file = $(this).data("files"); line of code would be returning undefined (unless you have some other javascript adding a data value, but you cannot add files to data so it in any case it would not be returning a file).
Change your loop to
$.each(files, function (i, v) {
for (i = 0; i < v.files.length; i++) {
var file = v.files[i];
data.append("file", file);
}
});
However, you can simplify this by using var data = new FormData($('form').get(0)); which will serialize all you form controls including file inputs to FormData (refer how to append whole set of model to formdata and obtain it in MVC for more information).
I also recommend you change your method signature to
public ActionResult AddUserImage(IEnumerable<HttpPostedFileBase> files)
and let the DefaultModelBinder do its magic.
you can directly get file from controller when called using Request.Files
//(Request) HttpRequestBase object for the current HTTP request
if (Request.Files.Count > 0)//// Is image is uplaod by browse button
{
var inputStream = Request.Files[0].InputStream;
using (var binaryReader = new BinaryReader(inputStream))
{
var ImageBytes = binaryReader .ReadBytes(Request.Files[0].ContentLength); // same as you can get multiple file also
}
var fileExtension = Path.GetExtension(Request.Files[0].FileName);
}
thanks.
I haven't done it with jQuery but just learned how to do it myself yesterday using plain old javascript... the following worked for me. If you want to stick with jquery maybe you can translate the functions to what you need:
var formElement = document.querySelector("form");
var payload = new FormData(formElement);
function onStateChange(ev) {
// Check if the request is finished
if (ev.target.readyState == 4) {
editor.busy(false);
if (ev.target.status == '200') {
// Save was successful, notify the user with a flash
} else {
// Save failed, notify the user with a flash
}
}
};
xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', onStateChange);
xhr.open('POST', '/posts');
xhr.send(payload);
Maybe see if using the above code works for you (it just targets a form that you have on the same page), and then you can troubleshoot whether it's your script that's the problem or a backend / communication problem.
I use jquery (ajax) to connect to a web service which returns string , it is not working with me. it always go to error function. here is my web service :
[HttpGet]
[ActionName("GetImage")]
public string GetImage(string base64String, string imgName,string reqTitle , string reqSubject, string reqStatus,string Creator , DateTime creationdate )
{
try
{
using (PhMobAppEntities context = new PhMobAppEntities())
{
ClaimsApproval _ca = new ClaimsApproval();
_ca.imageBasestrg = base64String;
_ca.imageName = imgName;
_ca.Creator = Creator;
_ca.CreationTime = creationdate;
_ca.ReqStatus = reqStatus;
_ca.ReqTitle = reqTitle;
_ca.ReqSubject = reqSubject;
context.ClaimsApprovals.Add(_ca);
context.SaveChanges();
return "Success";
}
}
catch (DbEntityValidationException ex)
{
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
var fullErrorMessage = string.Join("; ", errorMessages);
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
}
and here is my js code :
$("#sendphoto").click(function () {
var url = "http://41.128.183.109:1212/api/Data/GetImage";
var data = {
imgName: "test"
};
$.ajax({
url: url,
type: 'Get',
data: data,
success: function (data) {
alert("Success");
},
error: function (data) {
alert("Please Check Your Internet Connection");
}
});
});
It is running ok when i tested my web service in advanced rest client ,please advice .
I tried connecting to your web service and I get the following response:
{"$id":"1","Message":"No HTTP resource was found that matches the request URI 'http://41.128.183.109:1212/api/Data/GetImage'."}
I think what you have is an internal problem with your c# code, probably with your routing. Your javascript call is probably working fine, but you are passing only one parameter, "test" while you have many more in your declaration.
What http response code are you getting?
I asked a question to fill in the model data on the client, into arrays.
Add items to JSON objects
Now my problem is how to post it to the controller. I have tried this:
public ActionResult ItemRequest (Model1 model)
{
////
}
but it never gets there.
I'm trying with an AJAX request to send it:
function sendRequest() {
jsonData.items = itemArray;
$.ajax({
url: '#Url.Action("ItemRequest")',
type: 'POST',
data: JSON.stringify(jsonData),
///// and so on
}
But the action result is never invoked. I can drop the 'JSON.stringify' and it makes no difference. Any ideas on how to post this object to the controller?
If I make a psuedo model in JS it works fine, but I don't want to have to make this model, I'd rather use the model passed to the page.
function itemModel () {
var self = this;
this.itemNumber = $("#itemNumberId").val();
/// etc.
self.items = [];
}
function itemsModel () {
var self = this;
this.itemNumber = $("#itemNumberId").val();
/// etc
}
then
var itemCount = 0;
function addItem() {
var newItem = new itemModel();
newItem.items[itemCount] = newItem;
/// etc
}
This works fine.
I send the array itemModel the same way with a JSON.stringify directly into the controller method
public ActionResult ItemRequest(ItemModel model)
We are using this to send Data to API controller Methods on our internal test sides:
It's probably not the prettiest solution, but it can be used on any page.
What data should be sent:
$("#btnSend").click(function () {call("controller/method", {ParamName: $("#field").val()}); });
To send the data to a controller:
$(document).ready(function () {
var call = function (method, requestData, resultHandler) {
var url = method.substring(0, 1) == "/api/" + method;
$.ajax({
url: url,
dataType: 'json',
data: JSON.stringify(requestData),
type: 'POST',
contentType: 'application/json',
success: function (data) {
var isSuccess = data.Status == "success";
$("#jsonResponse").val(FormatJSON(data));
if (isSuccess && jQuery.isFunction(resultHandler)) {
resultHandler(data);
}
}
});
};