AJAX POST request on IE fails with error "No Transport"? - ajax

I'm trying to make an AJAX request to a public service
Here's the code:
$.ajax({
url : "http://api.geonames.org/citiesJSON",
type : 'POST',
cache : false,
dataType : 'json',
data : {
username: "demo",
north:10,
south: 10,
east:10,
west:10}
}).done(function(data) {
alert("Success: " + JSON.stringify(data));
}).fail(function(a, b, c, d) {
alert("Failure: "
+ JSON.stringify(a) + " "
+ JSON.stringify(b) + " "
+ JSON.stringify(c) + " "
+ JSON.stringify(d) );
});
You may try it in this link: http://jsfiddle.net/hDXq3/
The response is retrieved successfully on Chrome & Firefox, and the output is as follows:
But for IE, the fails alerting:
Failure: {"readyState":0,"status":0,"statusText":"No Transport"} "error" "No Transport" undefined
Why it's not working on IE ? and how to fix this ?

Here's the solution for those who are interested:
if (!jQuery.support.cors && window.XDomainRequest) {
var httpRegEx = /^https?:\/\//i;
var getOrPostRegEx = /^get|post$/i;
var sameSchemeRegEx = new RegExp('^'+location.protocol, 'i');
var xmlRegEx = /\/xml/i;
// ajaxTransport exists in jQuery 1.5+
jQuery.ajaxTransport('text html xml json', function(options, userOptions, jqXHR){
// XDomainRequests must be: asynchronous, GET or POST methods, HTTP or HTTPS protocol, and same scheme as calling page
if (options.crossDomain && options.async && getOrPostRegEx.test(options.type) && httpRegEx.test(userOptions.url) && sameSchemeRegEx.test(userOptions.url)) {
var xdr = null;
var userType = (userOptions.dataType||'').toLowerCase();
return {
send: function(headers, complete){
xdr = new XDomainRequest();
if (/^\d+$/.test(userOptions.timeout)) {
xdr.timeout = userOptions.timeout;
}
xdr.ontimeout = function(){
complete(500, 'timeout');
};
xdr.onload = function(){
var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '\r\nContent-Type: ' + xdr.contentType;
var status = {
code: 200,
message: 'success'
};
var responses = {
text: xdr.responseText
};
try {
if (userType === 'json') {
try {
responses.json = JSON.parse(xdr.responseText);
} catch(e) {
status.code = 500;
status.message = 'parseerror';
//throw 'Invalid JSON: ' + xdr.responseText;
}
} else if ((userType === 'xml') || ((userType !== 'text') && xmlRegEx.test(xdr.contentType))) {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = false;
try {
doc.loadXML(xdr.responseText);
} catch(e) {
doc = undefined;
}
if (!doc || !doc.documentElement || doc.getElementsByTagName('parsererror').length) {
status.code = 500;
status.message = 'parseerror';
throw 'Invalid XML: ' + xdr.responseText;
}
responses.xml = doc;
}
} catch(parseMessage) {
throw parseMessage;
} finally {
complete(status.code, status.message, responses, allResponseHeaders);
}
};
xdr.onerror = function(){
complete(500, 'error', {
text: xdr.responseText
});
};
xdr.open(options.type, options.url);
//xdr.send(userOptions.data);
xdr.send();
},
abort: function(){
if (xdr) {
xdr.abort();
}
}
};
}
});
};
jQuery.support.cors = true;
$.ajax({
url : "http://api.geonames.org/citiesJSON",
crossDomain: true,
type : 'POST',
cache : false,
dataType : 'json',
data : {
username: "demo",
north:10,
south: 10,
east:10,
west:10}
}).done(function(data) {
alert("Success: " + JSON.stringify(data));
}).fail(function(a, b, c, d) {
alert("Failure: "
+ JSON.stringify(a) + " "
+ JSON.stringify(b) + " "
+ JSON.stringify(c) + " "
+ JSON.stringify(d) );
});
You may try it in this link: http://jsfiddle.net/bjW8t/4/

Just include the jQuery ajaxTransport extension that uses XDomainRequest for IE8+.

Related

Unable to call any API from onAppointmentSend? Is this a limtation? Codes working on web outlook but not for Desktop Outlook

these are similar issues posted online
Relative fetch or XHR in a UI-Less Outlook add-in on Windows
How to make a http request in Outlook add-ins?
Officejs - Addin Outlook - SmartAlerts
Add-in built on jQuery framework works well on web-based outlook but doesn't on Desktop App
Outlook OnNewMessageCompose event not firing in Windows client
In outlook add-ins make salesforce oauth2 auth request getting CORS error
Common JavaScript function for Outlook Add-ins
React fetch not working with localhost endpoint with spring boot backend but ok with dummy JSON data
What is the easiest way to integrate Outlook web add-in into an existing ASP.NET Core 6 application?
Outlook Addin getting CORS when making request to ewsURL
if (_contextInfo.platform == "PC") {
console.log("PC");
Office.context.mailbox.item.subject.setAsync("Set by: New", { "asyncContext": event },
function (asyncResultPC) {
if (asyncResultPC.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultPC.error));
}
asyncResult.asyncContext.completed();
});
$.when(GetToken()).done(function () {
Office.context.mailbox.item.subject.setAsync("GetToken" + objResourceCurrent.token, { "asyncContext": event },
function (asyncResultToken) {
if (asyncResultToken.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultToken.error));
}
asyncResult.asyncContext.completed();
});
/*if (isNotNull(originalAppointment)) {
SetResourceAvailabilityByDatetimeRequest(originalAppointment);
if (objResourceCurrent.token != "" && objResourceCurrent.availabilityCriteria.length > 0) {
GetResourceAvailabilityByDatetime();
}
}*/
});
event.completed({ allowEvent: false, errorMessage: "From Desktop" });
}
else if (_contextInfo.platform == "OfficeOnline") {
console.log("OfficeOnline");
Office.context.mailbox.item.start.getAsync((asyncResultStartDt) => {
if (asyncResultStartDt.status !== Office.AsyncResultStatus.Succeeded) {
console.error(`Start Error:: ${asyncResultStartDt.error.message}`);
event.completed();
return;
}
originalAppointment.start = convertDateCS(asyncResultStartDt.value);
Office.context.mailbox.item.end.getAsync(function (asyncResultEndDt) {
if (asyncResultEndDt.status !== Office.AsyncResultStatus.Succeeded) {
console.error(`End Error:: ${asyncResultEndDt.error.message}`);
event.completed();
return;
}
originalAppointment.end = convertDateCS(asyncResultEndDt.value);
Office.context.mailbox.item.sessionData.getAsync("bookingObject", function (asyncResultBO) {
if (asyncResultBO.status !== Office.AsyncResultStatus.Succeeded) {
console.error(`BO Error:: ${asyncResultBO.error.message}`);
event.completed();
return;
}
const bookingObjectAllData = JSON.parse(asyncResultBO.value);
$.each(bookingObjectAllData["Office365AddInBookingItem"], function (index, item) { if (item.IsAddon == false) { ResourceIds = ResourceIds + item.ResourceId + ","; } });
originalAppointment.ResourceIds = ResourceIds;
result = checkRoomAvailabilityOutlook(originalAppointment.ResourceIds, originalAppointment.start, originalAppointment.end);
if (result) {
$.each(result, function (id, item) {
if (item.Value) {
availableRooms.push(item.Key)
}
else {
unAvailableRooms.push(item.Key)
}
});
}
else {
event.completed({ allowEvent: false, errorMessage: "checkRoomAvailabilityOutlook API Responsed with No Data" });
}
if (unAvailableRooms.length > 0) {
$.each(bookingObjectAllData["Office365AddInBookingItem"], function (index, item) {
if ($.inArray(item.ResourceId, unAvailableRooms) !== -1)
unavailableEmails = unavailableEmails !== '' ? unavailableEmails + ', ' + item.ResourceEmailId : item.ResourceEmailId;
});
event.completed({ allowEvent: false, errorMessage: "Unavailable room(s): " + unavailableEmails });
}
else {
if (availableRooms.length > 0) {
$.each(bookingObjectAllData["Office365AddInBookingItem"], function (index, item) {
if ($.inArray(item.ResourceId, availableRooms) !== -1)
availableEmails = availableEmails !== '' ? availableEmails + ', ' + item.ResourceEmailId : item.ResourceEmailId;
});
}
}
var itemId = Office.context.mailbox.item.itemId;
if (itemId === null || itemId == undefined) {
Office.context.mailbox.item.saveAsync(function (asyncResultSave) {
if (asyncResultSave.status !== Office.AsyncResultStatus.Succeeded) {
console.error(`End Error:: ${asyncResultSave.error.message}`);
event.completed();
return;
}
bookingObjectAllData.ExchangeReferenceNumber = asyncResultSave.value;
createSaveBookingRequest(bookingObjectAllData, originalAppointment);
saveBooking(bookingObj);
console.log(JSON.stringify(bookingObjectAllData));
event.completed({ allowEvent: true, errorMessage: "ItemId: " + asyncResultSave.value });
});
}
else {
console.log("Item already saved");
}
});
});
});
}
I tried XMLHttpRequest and fetch. both fails.
function GetToken() {
return $.ajax({
cache: false,
type: "POST",
contentType: "application/json",
url: "https://xyz/xyz/token",
data: {
username: "abc...",
password: "r6COP...",
grant_type: "password",
},
success: function (result) {
objResourceCurrent.token = result.access_token;
},
error: function (error) {
console.log("GetToken Error ", error);
}
});
}
Update
My above issue is still not resolved however As a test, I am able to call this open weather API. It working just fine with Windows Desktop/Web Outlook's OnSend or timeChange event handlers.
function onAppointmentSendHandler(event) {
console.log("onAppointmentSendHandler");
const _contextInfo = Office.context.diagnostics;
if (_contextInfo.platform == "PC") {
var url = 'https://api.openweathermap.org/data/2.5/weather?lat=28.644800&lon=77.216721&appid=efc8b889e4d57fbcc6fb2b523d2558c8';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.send();
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
console.log(request.responseText);
const myObj = JSON.parse(request.responseText)
var _Dtext = "From Desktop: City: " + myObj.name + ", Temp: " + myObj.main.temp + "f";
Office.context.mailbox.item.subject.setAsync(_Dtext, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
event.completed({ allowEvent: false });
});
}
else {
console.log("Problem retrieving data PC");
console.log(this.responseXML);
}
}
}
}
else if (_contextInfo.platform == "OfficeOnline") {
console.log("Office Online");
var url = 'https://api.openweathermap.org/data/2.5/weather?lat=28.474388&lon=77.503990&appid=efc8b889e4d57fbcc6fb2b523d2558c8';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.send();
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
//console.log(request.responseText);
const myObj = JSON.parse(request.responseText)
var _Otext = "From Online: City: " + myObj.name + ", Temp: " + myObj.main.temp + "f";
Office.context.mailbox.item.subject.setAsync(_Otext, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
event.completed({ allowEvent: false });
});
}
else {
console.log("Problem retrieving data Office Online");
console.log(this.responseXML);
}
}
}
}
}
function onAppointmentTimeChangedHandler(event) {
console.log("onAppointmentTimeChangedHandler");
var url = 'https://api.openweathermap.org/data/2.5/weather?lat=23.669296&lon=86.151115&appid=efc8b889e4d57fbcc6fb2b523d2558c8';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.send();
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
console.log(request.responseText);
const myObj = JSON.parse(request.responseText)
var _text = "From Time Change: City: " + myObj.name + ", Temp: " + myObj.main.temp + "f";
Office.context.mailbox.item.subject.setAsync(_text, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
});
}
else {
console.log("Problem retrieving data");
console.log(this.responseXML);
}
}
}
}
Office.actions.associate("onAppointmentTimeChangedHandler", onAppointmentTimeChangedHandler);
Office.actions.associate("onAppointmentSendHandler", onAppointmentSendHandler);
Update 2 I am testing another API with 3 fields Subject, StartDate and End Date. Please note: This below code runs perfectly on Web outlook for OnSend/TimeChange events but not for Desktop Outlook OnSend /TimeChange events. And I do not get any error message or something.
Any help is much appriciated.
function onAppointmentSendHandler(event) {
console.log("onAppointmentSendHandler");
const _contextInfo = Office.context.diagnostics;
if (_contextInfo.platform == "PC") {
var obj = JSON.stringify({
Subject: "Azure Desktop 1",
StartDate: "03/02/2023",
EndDate: "03/31/2023"
});
username = "admin1";
password = "pass#123";
var url = 'https://externalwebapi.azurewebsites.net/api/save';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
request.send(obj);
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
console.log(request.responseText);
var _Dtext = "Azure Desktop 1";
Office.context.mailbox.item.subject.setAsync(_Dtext, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject1: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
event.completed({ allowEvent: false });
});
}
else {
console.log("Problem retrieving data PC");
console.log(this.responseXML);
}
}
}
}
else if (_contextInfo.platform == "OfficeOnline") {
console.log("Office Online");
var obj = JSON.stringify({
Subject: "Azure WebSite 1",
StartDate: "02/02/2023",
EndDate: "02/28/2023"
});
//console.log(obj);
username = "admin1";
password = "pass#123";
var url = 'https://externalwebapi.azurewebsites.net/api/save';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
request.send(obj);
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
console.log(request.responseText);
var _Dtext = "Azure WebSite 1";
Office.context.mailbox.item.subject.setAsync(_Dtext, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
event.completed({ allowEvent: false });
});
}
else {
console.log("Problem retrieving data Web");
console.log(this.responseXML);
}
}
}
}
}
function onAppointmentTimeChangedHandler(event) {
console.log("onAppointmentTimeChangedHandler");
var obj = JSON.stringify({
Subject: "Azure Time",
StartDate: "02/02/2023",
EndDate: "02/28/2023"
});
username = "admin1";
password = "pass#123";
var url = 'https://externalwebapi.azurewebsites.net/api/save';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
request.send(obj);
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
console.log(request.responseText);
var _Dtext = "Azure Time";
Office.context.mailbox.item.subject.setAsync(_Dtext, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
event.completed({ allowEvent: false });
});
}
else {
console.log("Problem retrieving data Web");
console.log(this.responseXML);
}
}
}
}
Office.actions.associate("onAppointmentTimeChangedHandler", onAppointmentTimeChangedHandler);
Office.actions.associate("onAppointmentSendHandler", onAppointmentSendHandler);
REST API calls are supported and can be made from the onSend event handlers (callbacks). You just need to make sure that CORS is addressed in the add-in. The very first link in your post contains the valid answer to your case.
The same-origin policy enforced by the browser prevents a script loaded from one domain from getting or manipulating properties of a webpage from another domain. This means that, by default, the domain of a requested URL must be the same as the domain of the current webpage. For example, this policy will prevent a webpage in one domain from making XmlHttpRequest web-service calls to a domain other than the one where it is hosted.
Because Office Add-ins are hosted in a browser control, the same-origin policy applies to script running in their web pages as well.
The same-origin policy can be an unnecessary handicap in many situations, such as when a web application hosts content and APIs across multiple subdomains. There are a few common techniques for securely overcoming same-origin policy enforcement. The Addressing same-origin policy limitations in Office Add-ins article can only provide the briefest introduction to some of them.

nativescript-background-http issue

I tried implementing image upload page for my app, but unfortunately the request is not reaching the server. I double checked this using tcpdump on the server side. The code doesnt seem to process beyond session.uploadFile in sendImages function
Please let me know if there is any issue with the code
var imageSource = require("image-source");
var frameModule = require("ui/frame");
var Observable = require("data/observable").Observable;
var fromObject = require("data/observable").fromObject;
var ObservableArray = require("data/observable-array").ObservableArray;
var platformModule = require("platform");
var permissions = require("nativescript-permissions");
var imagepickerModule = require("nativescript-imagepicker");
var bghttpModule = require("nativescript-background-http");
var session = bghttpModule.session("image-upload");
var fs = require("file-system");
var page;
var imageName;
var counter = 0;
function pageLoaded(args) {
page = args.object;
}
function onSelectSingleTap(args) {
var context = imagepickerModule.create({
mode: "single"
});
if (platformModule.device.os === "Android" && platformModule.device.sdkVersion >= 23) {
permissions.requestPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE, "I need these permissions to read from storage")
.then(function () {
console.log("Permissions granted!");
startSelection(context);
})
.catch(function () {
console.log("Uh oh, no permissions - plan B time!");
});
} else {
startSelection(context);
}
}
function sendImages(uri, fileUri) {
imageName = extractImageName(fileUri);
var request = {
url: "http://maskingIpForPost:8081/mobilepic/ctk/uploadpic",
method: "POST",
headers: {
"Content-Type": "application/octet-stream",
"file-Name": imageName,
"uid": 30
},
description: "{ 'uploading': " + imageName + " }"
};
var task = session.uploadFile(fileUri, request);
task.on("progress", progress);
task.on("error", error);
task.on("complete", complete);
task.on("responded", responded);
function responded(e) {
console.log("eventName: " + e.eventName);
console.log("data: " + e.data);
}
function progress(e) {
console.log("currentBytes: " + e.currentBytes);
console.log("totalBytes: " + e.totalBytes);
console.log("eventName: " + e.eventName);
}
function error(e) {
console.log("eventName: " + e.eventName);
console.log("eventName: " + e.responseCode);
console.log("eventName: " + e.response);
}
function complete(e) {
console.log("eventName: " + e.eventName);
console.log("response: " + e.responseCode);
}
return task;
}
function startSelection(context) {
context
.authorize()
.then(function () {
return context.present();
})
.then(function (selection) {
selection.forEach(function (selected_item) {
var localPath = null;
if (platformModule.device.os === "Android") {
localPath = selected_item._android;
} else {
// selected_item.ios for iOS is PHAsset and not path - so we are creating own path
let folder = fs.knownFolders.documents();
let path = fs.path.join(folder.path, "Test" + counter + ".png");
//let saved = imagesource.saveToFile(path, "png");
localPath = path;
}
alert("final path " + localPath);
if (localPath) {
var task = sendImages("Image" + counter + ".png", localPath);
//mainViewModel.get("items").push(fromObject({ thumb: imagesource, uri: "Image" + counter + ".png", uploadTask: task }));
}
counter++;
});
}).catch(function (e) {
console.log(e.eventName);
});
}
function extractImageName(fileUri) {
var pattern = /[^/]*$/;
var imageName = fileUri.match(pattern);
return imageName;
}
exports.pageLoaded = pageLoaded;
exports.onSelectSingleTap = onSelectSingleTap;
On Further research found the following
net.gotev.uploadservice.UploadService is undefined in background-http.android.js. At this moment i am not sure what this means. Would appreciate if anyone has idea about this
You need to change the following line in your code.
var session = bghttpModule.session("image-upload");
It has to be file upload
var session = bghttpModule.session("file-upload");
Just tested your code by using Azure Blob Storage PUT url at my side and got the below response.
ActivityManager: START u0 {act=android.intent.action.OPEN_DOCUMENT typ=image/* cmp=com.android.documentsui/.DocumentsActivity (has extras)} from pid 2835
JS: currentBytes: 4096
JS: totalBytes: 25220
JS: eventName: progress
JS: currentBytes: 25220
JS: totalBytes: 25220
JS: eventName: progress
JS: currentBytes: 25220
JS: totalBytes: 25220
JS: eventName: progress
JS: eventName: responded
JS: data:
JS: eventName: complete
JS: response: 201
thanks for the quick response, i tried running it on a emulator and i faced the above mentioned issue, i tried the same by connecting a device and it worked just fine.

AJAX error return ModelState Error

On my Create page I am using ajax and calling my api controller when creating a person:
<script>
$(document).ready(function() {
var newUrl = '#Url.Action("Index", "PersonInformations")';
var settings = {};
settings.baseUri = '#Request.ApplicationPath';
var infoGetUrl = "";
if (settings.baseUri === "/ProjectNameOnServer") {
infoGetUrl = settings.baseUri + "/api/personinformations/";
} else {
infoGetUrl = settings.baseUri + "api/personinformations/";
}
$("#Create-Btn").on("click",
function(e) {
$("form").validate({
submitHandler: function () {
e.preventDefault();
$.ajax({
method: "POST",
url: infoGetUrl,
data: $("form").serialize(),
success: function () {
toastr.options = {
onHidden: function () {
window.location.href = newUrl;
},
timeOut: 3000
}
toastr.success("Individual successfully created.");
},
error: function (jqXHR, textStatus, errorThrown) {
var status = capitalizeFirstLetter(textStatus);
var error = $.parseJSON(jqXHR.responseText);
//console.log(jqXHR.responseText);
toastr.error(status + " - " + error.message);
}
});
}
});
});
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
});
</script>
Here is the method in my PersonInformations API controller:
[ResponseType(typeof(PersonInformation))]
public IHttpActionResult PostPersonInformation(PersonInformation personInformation)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var lstOfPersons = db.PersonInformations.Where(x => x.deleted == false).ToList();
if (lstOfPersons.Any(
x =>
x.FirstName == personInformation.FirstName && x.LastName == personInformation.LastName &&
x.AId == personInformation.AgencyId && x.ID != personInformation.ID))
{
ModelState.AddModelError("", "This person already exists!");
return BadRequest(ModelState);
}
if (
lstOfPersons.Any(
x => x.Email.ToLower() == personInformation.Email.ToLower() && x.ID != personInformation.ID))
{
ModelState.AddModelError(personInformation.Email, "This email already exists!");
return BadRequest(ModelState);
}
personInformation.FirstName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(personInformation.FirstName);
personInformation.LastName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(personInformation.LastName);
db.PersonInformation.Add(personInformation);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = personInformation.ID }, personInformation);
}
Now when I test this and purposely enter an email that already exists, the ajax request errors out but returns the message:
Error - The Request is invalid
but when I use console.log(jqXHR.responseText)
I get this:
Create
{
"$id": "1",
"message": "The request is invalid.",
"modelState": {
"$id": "2",
"test#test.com": [
"This email already exists!"
]
}
}
How do I get the "This email already exists!" as the error message?
I just figured this out. I know that the modelState was an array type, and the 2nd value was the actual email address entered.
So I edited my button.click event to this:
$("#Create-Btn").on("click",
function(e) {
$("form").validate({
submitHandler: function () {
e.preventDefault();
var emailValue = $("#Email").val();
$.ajax({
method: "POST",
url: infoGetUrl,
data: $("form").serialize(),
success: function () {
toastr.options = {
onHidden: function () {
window.location.href = newUrl;
},
timeOut: 3000
}
toastr.success("Individual successfully created.");
},
error: function (jqXHR, textStatus, errorThrown) {
var status = capitalizeFirstLetter(textStatus);
var error = $.parseJSON(jqXHR.responseText);
toastr.error(status + " - " + error.modelState[emailValue]);
}
});
}
});
});
Find the error message via array bracket notation along with getting the actual value of the email trying to be submitted did the trick.

Parse cloud code afterSave gets triggered twice

I have a aftersave on Parse cloud code. I have made changes to the table once but the aftersave hook triggers twice
1st Update (Actual update)
Input: {"object":{"addedBy":"tt","albumTitle":"ggh","approved":true,
"createdAt":"2015-12-14T03:07:27.253Z","image":
{"__type":"File","name":"tfss-e26ec608-5a0b-46a2-91db-33590139c4b3-
newImage.jpg","url":"http://files.parsetfss.com/0accbdba-e3f2-493d-
ac70-1c6bccc367b9/tfss-e26ec608-5a0b-46a2-91db-33590139c4b3-
newImage.jpg"},"objectId":"p4pLO70gQY","updatedAt":"2015-12-
14T03:07:37.733Z"}}
2nd Update (Shouldn't happen)
Input: {"object":{"addedBy":"tt","albumTitle":"ggh","approved":true,
"createdAt":"2015-12-14T03:07:27.253Z","image":
{"__type":"File","name":"tfss-e26ec608-5a0b-46a2-91db-33590139c4b3-
newImage.jpg","url":"http://files.parsetfss.com/0accbdba-e3f2-493d-
ac70-1c6bccc367b9/tfss-e26ec608-5a0b-46a2-91db-33590139c4b3-
newImage.jpg"},"objectId":"p4pLO70gQY","updatedAt":"2015-12-
14T03:07:38.038Z"}}
The only difference between the two updates is the updatedAt time. Will aftersave be triggered even if the update time changes?
How can I avoid the second aftersave execution?
Here is my cloud code :
Parse.Cloud.afterSave("Photos", function (request) {
var albumNameA = "";
var publicUser = "";
var albumOwner = "";
var photoUniqueId = "";
var isApproved = "";
albumNameA = request.object.get("albumTitle");
publicUser = request.object.get("addedBy");
photoUniqueId = request.object.id;
isApproved = request.object.get("approved");
if (request.object.get("createdAt").getTime() == request.object.get("updatedAt").getTime()) {
var getAlbumOwner = new Parse.Object.extend("Albums");
var q3 = new Parse.Query(getAlbumOwner);
q3.equalTo("title", albumNameA);
q3.first({
success: function (results) {
console.log("Checking for Creator name " + results.get("creatorName"));
albumOwner = results.get("creatorName");
console.log("Uploading a Photo Final " + albumNameA + "-by-" + publicUser + "--ownedby--" + albumOwner);
console.log("Uploading a Photo" + albumNameA + "-by-" + publicUser + "--" + photoUniqueId + "--" + isApproved);
var install = new Parse.Object.extend("Installation");
var q2 = new Parse.Query(install);
q2.equalTo("privacy", privateUserNo);
q2.equalTo("username", albumOwner);
q2.find({
success: function (results) {
if (!isApproved) {
Parse.Push.send({
where: q2, // Set our Installation query
data: {
alert: "New Photo uploaded by " + publicUser + " ,waiting for approval"
}
}, {
success: function () {
// Push was successful
console.log("Push success");
},
error: function (error) {
// Handle error
console.log("Push error");
}
})
}
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});
} else if (!(request.object.get("createdAt").getTime() == request.object.get("updatedAt").getTime())) {
console.log("all case scenarios");
var getAlbumOwner1 = new Parse.Object.extend("Albums");
var q6 = new Parse.Query(getAlbumOwner1);
q6.equalTo("title", albumNameA);
q6.first({
success: function (results) {
albumOwner = results.get("creatorName");
var sendApproval = new Parse.Object.extend("Photos");
var q4 = new Parse.Query(sendApproval);
q4.descending("updatedAt");
q4.first({
success: function (results) {
var objectIDNeeded = results.id;
var isChanged = results.get("approved");
var currentUpdateTime = results.get("updatedTime");
console.log("Your Photo, " + publicUser + " ,has been approved by " + albumOwner);
var install = new Parse.Object.extend("Installation");
var q5 = new Parse.Query(install);
q5.equalTo("privacy", privateUserNo);
q5.equalTo("username", publicUser);
q5.find({
success: function (results) {
Parse.Push.send({
where: q5, // Set our Installation query
data: {
alert: "Your Photo has been approved by " + albumOwner
}
}, {
success: function () {
// Push was successful
console.log("Push success");
},
error: function (error) {
// Handle error
console.log("Push error");
}
})
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});
}
});

Error in jquery.handleErrors when using IE

I use this AJAX jQuery plugin in our site. When I test it using IE, I'm getting this error ( Object doesn't support property or method 'handleError') that pertains to this line:
jQuery.handleError(s, xml, null, e);
I'm using 1.7.1 version of jQuery. How can I replace it?
Here's the full code
jQuery.extend({
createUploadIframe: function (id, uri) {
//create frame
var frameId = 'jUploadFrame' + id;
var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"';
if (window.ActiveXObject) {
if (typeof uri == 'boolean') {
iframeHtml += ' src="' + 'javascript:false' + '"';
} else if (typeof uri == 'string') {
iframeHtml += ' src="' + uri + '"';
}
}
iframeHtml += ' />';
jQuery(iframeHtml).appendTo(document.body);
return jQuery('#' + frameId).get(0);
},
createUploadForm: function (id, fileElementId, data) {
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
var form = jQuery('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
if (data) {
for (var i in data) {
jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
}
}
var oldElement = jQuery('#' + fileElementId);
var newElement = jQuery(oldElement).clone();
jQuery(oldElement).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(oldElement).appendTo(form);
//set attributes
jQuery(form).css('position', 'absolute');
jQuery(form).css('top', '-1200px');
jQuery(form).css('left', '-1200px');
jQuery(form).appendTo('body');
return form;
},
ajaxFileUpload: function (s) {
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
s = jQuery.extend({}, jQuery.ajaxSettings, s);
var id = new Date().getTime()
var form = jQuery.createUploadForm(id, s.fileElementId, (typeof (s.data) == 'undefined' ? false : s.data));
var io = jQuery.createUploadIframe(id, s.secureuri);
var frameId = 'jUploadFrame' + id;
var formId = 'jUploadForm' + id;
// Watch for a new set of requests
if (s.global && !jQuery.active++) {
jQuery.event.trigger("ajaxStart");
}
var requestDone = false;
// Create the request object
var xml = {}
if (s.global) jQuery.event.trigger("ajaxSend", [xml, s]);
// Wait for a response to come back
var uploadCallback = function (isTimeout) {
var io = document.getElementById(frameId);
try {
if (io.contentWindow) {
xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : null;
xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
} else if (io.contentDocument) {
xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML : null;
xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
}
} catch (e) {
jQuery.handleError(s, xml, null, e);
}
if (xml || isTimeout == "timeout") {
requestDone = true;
var status;
try {
status = isTimeout != "timeout" ? "success" : "error";
// Make sure that the request was successful or notmodified
if (status != "error") {
// process the data (runs the xml through httpData regardless of callback)
var data = jQuery.uploadHttpData(xml, s.dataType);
// If a local callback was specified, fire it and pass it the data
if (s.success) s.success(data, status);
// Fire the global callback
if (s.global) jQuery.event.trigger("ajaxSuccess", [xml, s]);
} else jQuery.handleError(s, xml, status);
} catch (e) {
status = "error";
jQuery.handleError(s, xml, status, e);
}
// The request was completed
if (s.global) jQuery.event.trigger("ajaxComplete", [xml, s]);
// Handle the global AJAX counter
if (s.global && !--jQuery.active) jQuery.event.trigger("ajaxStop");
// Process result
if (s.complete) s.complete(xml, status);
jQuery(io).unbind()
setTimeout(function () {
try {
jQuery(io).remove();
jQuery(form).remove();
} catch (e) {
jQuery.handleError(s, xml, null, e);
}
}, 100)
xml = null
}
}
// Timeout checker
if (s.timeout > 0) {
setTimeout(function () {
// Check to see if the request is still happening
if (!requestDone) uploadCallback("timeout");
}, s.timeout);
}
try {
var form = jQuery('#' + formId);
jQuery(form).attr('action', s.url);
jQuery(form).attr('method', 'POST');
jQuery(form).attr('target', frameId);
if (form.encoding) {
jQuery(form).attr('encoding', 'multipart/form-data');
} else {
jQuery(form).attr('enctype', 'multipart/form-data');
}
jQuery(form).submit();
} catch (e) {
jQuery.handleError(s, xml, null, e);
}
jQuery('#' + frameId).load(uploadCallback);
return {
abort: function () {}
};
},
uploadHttpData: function (r, type) {
var data = !type;
data = type == "xml" || data ? r.responseXML : r.responseText;
// If the type is "script", eval it in global context
if (type == "script") jQuery.globalEval(data);
// Get the JavaScript object, if JSON is used.
if (type == "json") eval("data = " + data);
// evaluate scripts within html
if (type == "html") jQuery("<div>").html(data).evalScripts();
return data;
}
})
handleError was removed from jQuery in 1.5. Are you sure it's working in firefox etc.?
See: When was handleError removed from jQuery?

Resources