How to create the annotation from the form? - dynamics-crm

var note = Object();
note["notetext"] = "test";
note["subject"] = "Закрытие обращения";
note["incidentid#odata.bind"] = `/incidents(FC8F144E-06E7-E711-80C7-0050569B0E28)`;
$.ajax( {
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: 'json',
url: 'https://crmw.test.ru/testdb/api/data/v8.2/annotations',
async: true,
data: JSON.stringify( note ),
beforeSend: function ( XMLHttpRequest )
{
XMLHttpRequest.setRequestHeader( "Accept", "application/json" );
XMLHttpRequest.setRequestHeader( "OData-MaxVersion", "4.0" );
XMLHttpRequest.setRequestHeader( "OData-Version", "4.0" );
},
success: function ( data, textStatus, XmlHttpRequest )
{
let result = data;
alert( "Record created successfully" );
},
error: function ( XmlHttpRequest, textStatus, errorThrown )
{
alert("ошибка"+ XmlHttpRequest + textStatus + errorThrown);
}
} );
I need to send the text from the form to a note in circulation. What am I doing wrong?
I need please add some more details

The problem is with the single valued navigation property, it should be objectid_incident#odata.bind instead of incidentid#odata.bind
Change this line
note["incidentid#odata.bind"] = `/incidents(FC8F144E-06E7-E711-80C7-0050569B0E28)`;
like below, then it will work. Read more
note["objectid_incident#odata.bind"] = "/incidents(FC8F144E-06E7-E711-80C7-0050569B0E28)";
Reference
You can build & test queries using CRM REST Builder without syntax issues.

You probably have to add inverted commas to below line
note["incidentid#odata.bind"] ="/incidents(FC8F144E-06E7-E711-80C7-0050569B0E28)";
Here is the below Code I tried and worked well for me.
var entity = {};
entity.subject = "Test from WEbapi 3";
entity.filename = "File Name 123";
entity["objectid_incident#odata.bind"] = "/incidents(C86A8897-D94F-E911-A82F-000D3A385A1C)";
var req = new XMLHttpRequest();
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.1/annotations", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 204) {
var uri = this.getResponseHeader("OData-EntityId");
var regExp = /\(([^)]+)\)/;
var matches = regExp.exec(uri);
var newEntityId = matches[1];
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(entity));

Related

Bad request error when calling a custom action from JS in CRM V9

I created a custom action in my CRM online V9 with 2 parameters an entity reference to contact and a string.
I checked that the schema name is correct (upper and lower case) and even tried to use rest builder to generate the code but I keep getting a "Bad Request" error.
Here is my code:
var parameters = {};
var contact = {};
contact.primarykeyid = "49A0E5B9-88DF-E311-B8E5-6C3BE5A8B200";//I added an hard coded value for testing
contact["#odata.type"] = "Microsoft.Dynamics.CRM.contact";
parameters.Contact = contact;
parameters.Text = "Some Text";
var req = new XMLHttpRequest();
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/new_CreateSMSrecord", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(parameters));
OK, I managed to find the problem
I changed the code of the contact parameter and that solved the issue,
here is my updated code:
var parameters = {};
parameters.Contact = { "contactid": "49A0E5B9-88DF-E311-B8E5-6C3BE5A8B200", "#odata.type": "Microsoft.Dynamics.CRM.contact" }
parameters.Text = "I'm from JS";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: Xrm.Page.context.getClientUrl() + "/api/data/v9.0/new_CreateSMSrecord",
data: JSON.stringify(parameters),
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("OData-MaxVersion", "4.0");
XMLHttpRequest.setRequestHeader("OData-Version", "4.0");
XMLHttpRequest.setRequestHeader("Accept", "application/json");
},
async: false,
success: function (data, textStatus, xhr) {
var results = data;
},
error: function (xhr, textStatus, errorThrown) {
Xrm.Utility.alertDialog(textStatus + " " + errorThrown);
}
});

Getting blank pdf from ajax call returning HttpResponseMessage in webapp

I am returning HttpResponseMessage from web api and use this in ajax call but getting blank pdf.
my ajax call is
function downloadPDF()
{
$.ajax({
type: "POST",
crossDomain: true,
data: JSON.stringify(UserData),
url: rootUrl + "api/WebAPI/Export",
//dataType: "native",
contentType: "application/json",
//responseType: 'arraybuffer',
//contentType: "application/pdf",
headers: headers,
success: function (data) {
//document.write(data);
alert(data.size);
var blob = new Blob([data]);
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "Dossier_" + new Date() + ".pdf";
link.click();
}
}
Convert your HttpResponseMessage(which should be Base64String) to Array Buffer using this function :
function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}
And then call this function after converting to Array Buffer :
function saveByteArray(pdfName, byte) {
var blob = new Blob([byte], { type: "application/pdf" });
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
var fileName = pdfName + ".pdf";
link.download = fileName;
link.click();
};
So your whole ajax call will look like this :
function downloadPDF()
{
$.ajax({
type: "POST",
crossDomain: true,
data: JSON.stringify(UserData),
url: rootUrl + "api/WebAPI/Export",
//dataType: "native",
contentType: "application/json",
//responseType: 'arraybuffer',
//contentType: "application/pdf",
headers: headers,
success: function (data) {
//document.write(data);
alert(data.size);
var bytes = base64ToArrayBuffer(data);
saveByteArray("Dossier_" + new Date(), bytes);
}
}

jquery $.ajax call for MVC actionresult which returns JSON triggers .error block

I have the following $.ajax post call. It would go through the action being called but then it would trigger the "error" block of the function even before the actionresult finishes. Also, it seems to reload the whole page after every pass.
var pnameVal = '<%: this.ModelCodeValueHelper().ModelCode%>';
var eidVal = '<%: ViewBag.EventId %>';
var dataV = $('input[ name = "__RequestVerificationToken"]').val();
var urlVal = '<%: Url.Action("New") %>';
alert('url > ' + urlVal);
alert('pname - ' + pnameVal + ' eid - ' + eidVal + ' dataV = ' + dataV);
$.ajax({
url: urlVal,
//dataType: "JSONP",
//contentType: "application/json; charset=utf-8",
type: "POST",
async: true,
data: { __RequestVerificationToken: dataV, pname: pnameVal, eId: eidVal },
success: function (data) {
alert('successssesss');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest);
alert(textStatus);
alert(errorThrown);
alert('dammit');
}
})
.done(function (result) {
if (result.Success) {
alert(result.Message);
}
else if (result.Message) {
alert(' alert' + result.Message);
}
alert('done final');
//$('#search-btn').text('SEARCH');
waitOff();
});
This is the action
[HttpPost]
public ActionResult New(string pname, int eid)
{
var response = new ChangeResults { }; // this is a viewmodel class
Mat newMat = new Mat { "some stuff properties" };
Event eve = context.Events.FirstOrDefault(e => e.Id == eid);
List<Mat> mats = new List<Mat>();
try
{
eve.Mats.Add(newMat);
icdb.SaveChanges();
mats = icdb.Mats.Where(m => m.EventId == eid).ToList();
response.Success = true;
response.Message = "YES! Success!";
response.Content = mats; // this is an object type
}
catch (Exception ex)
{
response.Success = false;
response.Message = ex.Message;
response.Content = ex.Message; // this is an object type
}
return Json(response);
}
Btw, on fiddler the raw data would return the following message:
{"Success":true,"Message":"Added new Mat.","Content":[]}
And then it would reload the whole page again. I want to do an ajax call to just show added mats without having to load the whole thing. But it's not happening atm.
Thoughts?
You probably need to add e.preventDefault() in your handler, at the beginning (I am guessing that this ajax call is made on click, which is handled somewhere, that is the handler I am talking about).

Javascript post jsonObject with Image Binary

I have a HTML form for filling the personal profile, which includes String and Images. And I need to post all these data as JsonObject with one backend api call, and the backend requires the image file sent as binary data. Here is my Json Data as follow:
var profile = {
"userId" : email_Id,
"profile.name" : "TML David",
"profile.profilePicture" : profilePhotoData,
"profile.galleryImageOne" : profileGalleryImage1Data,
"profile.referenceQuote" : "Reference Quote"
};
and, profilePhotoData, profileGalleryImage1Data, profileGalleryImage2Data, profileGalleryImage3Data are all image Binary data(Base64).
And here is my post function:
function APICallCreateProfile(profile){
var requestUrl = BASE_URL + API_URL_CREAT_PROFILE;
$.ajax({
url: requestUrl,
type: 'POST',
data: profile,
dataType:DATA_TYPE,
contentType: CONTENT_TYPE_MEDIA,
cache:false,
processData:false,
timeabout:API_CALL_TIMEOUTS,
success: function (response) {
console.log("response " + JSON.stringify(response));
var success = response.success;
var objectData = response.data;
if(success){
alert('CreateProfile Success!\n' + JSON.stringify(objectData));
}else{
alert('CreateProfile Faild!\n'+ data.text);
}
},
error: function(data){
console.log( "error" +JSON.stringify(data));
},
failure:APIDefaultErrorHandler
})
.done(function() { console.log( "second success" ); })
.always(function() { console.log( "complete" ); });
return false;
}
But still got failed, I checked the server side, and it complains about the "no multipart boundary was found".
Can anyone help me with this, thanks:)
Updates:
var DATA_TYPE = "json";
var CONTENT_TYPE_MEDIA = "multipart/form-data";
I think I found the solution with vineet help. I am using XMLHttpRequest, and didn't set the requestHeader, but it works, very strange. But hope this following can help
function APICallCreateProfile(formData){
var requestUrl = BASE_URL + API_URL_CREAT_PROFILE;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function()
{
if (xhr.readyState==4 && xhr.status==200){
console.log( "profile:" + xhr.responseText);
}else if (xhr.readyState==500){
console.log( "error:" + xhr.responseText);
}
}
xhr.open('POST', requestUrl, true);
// xhr.setRequestHeader("Content-Type","multipart/form-data; boundary=----WebKitFormBoundarynA5hzSDsRj7UJtNa");
xhr.send(formData);
return false;
}
Why to reinvent the wheel. Just use Jquery Form Plugin, here. It has example for multipart upload as well.
You just need to set input type as file. You will receive files as input stream at server (off course they will be multipart)

How do I update foreign key with odata json

Expected behavior: User clicks on Register button and record is created in related entity. This has worked up til now but now we have requirement to update the foreign key based on a lookup on the current form. How do I accomplish this? The pasted code below throws error in browser "Error on the creation of record; Error – Bad Request"
// JScript source code
CreateButton = function () {
var fieldTable = crmForm.all.new_registerbutton_d;
var html = "<TABLE border=0 cellSpacing=0 cellPadding=0><TBODY><TR><TD width=0px>" + fieldTable.innerHTML + "</TD><TD width=200><INPUT style='BACKGROUND-COLOR: #d8e8ff' onclick=Button_OnClick() value='Register' type=button></TD></TR></TBODY></TABLE>";
fieldTable.innerHTML = html;
document.all.new_registerbutton.style.display = 'none';
crmForm.all.new_registerbutton_c.innerText = "";
}
Button_OnClick = function () {
//var new_se_registration = new Object();
var invitationName = Xrm.Page.getAttribute("new_name").getValue();
//new_se_registration.new_name = invitationName;
var invitationGUID = Xrm.Page.data.entity.getId().replace('{', '').replace('}', '');
alert(invitationGUID);
var value = new Array();
value[0] = new Object();
value[0].id = invitationGUID;
value[0].name = invitationName;
//var invitation = {
//id: invitationGUID, name: invitationName, entityType: "new_se_registration"
//};
//var invitation= { Id: invitationGUID, LogicalName: "new_se_registration", Name: invitationName };
//value[0].entityType = Xrm.Page.data.entity.getEntityType();
//new_se_registration.new_new_se_invitation_new_se_registid.setValue([{ id: invitationGUID, name: invitationName, entityType: "new_se_registration"}]);
//new_se_registration.new_new_se_invitation_new_se_registid = invitation;
//new_se_registration.new_eventname= Xrm.Page.getAttribute("new_eventname").getValue();
//new_invitationid is the Event id
var lookupItem = new Array;
lookupItem = crmForm.all.new_invitationid.DataValue;
var eventname = lookupItem[0].name;
//new_se_registration.new_eventname = eventname;
lookupItem = crmForm.all.new_invitationid.DataValue;
var new_se_registration = {
new_new_se_invitation_new_se_registid: {
__metadata: { type: "Microsoft.Crm.Sdk.Data.Services.EntityReference" },
Id: invitationGUID,
LogicalName: invitationName
},
new_name: invitationName,
new_eventname: eventname
};
//alert ( eventname);
// end Ek - adding event name
//deleteRecord(new_se_registration.new_name, "new_se_registrationSet");
var reg = Xrm.Page.getAttribute("new_registered").getValue();
if (reg == null) {
reg = "N";
}
if (reg != "Y") {
//Xrm.Page.getAttribute("new_registered").setValue("Y");
//alert(reg);
//return;
createRecord(new_se_registration, "new_se_registrationSet", RegisterCompleted, null);
Xrm.Page.getAttribute("new_registered").setValue("Y");
//Xrm.Page.data.entity.attributes.get("new_registered").setSubmitMode("always");
//Xrm.Page.data.entity.save();
}
else {
alert("\"" + Xrm.Page.getAttribute("new_name").getValue() + "\" has been registered already.");
}
}
function RegisterCompleted(data, textStatus, XmlHttpRequest) {
var new_se_registration = data;
Xrm.Page.data.entity.save();
alert("\"" + Xrm.Page.getAttribute("new_name").getValue() + "\" has been registered successfully.");
}
function checkDuplicate() {
alert("test");
}
function deleteRecord(id, odataSetName) {
var serverUrl = Xrm.Page.context.getServerUrl();
var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: serverUrl + ODATA_ENDPOINT + "/" + odataSetName + "(guid'" + id + "')",
beforeSend: function (XMLHttpRequest) {
//XMLHttpRequest.setRequestHeader("Accept", "application/json");
XMLHttpRequest.setRequestHeader("X-HTTP-Method", "DELETE");
},
success: function (data, textStatus, XmlHttpRequest) {
alert("Record deleted successfully!");
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
alert("Error while deletion – " + errorThrown);
}
});
}
function createRecord(entityObject, odataSetName, successCallback, errorCallback) {
var jsonEntity = window.JSON.stringify(entityObject);
var serverUrl = Xrm.Page.context.getServerUrl();
var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: serverUrl + ODATA_ENDPOINT + "/" + odataSetName,
data: jsonEntity,
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Accept", "application/json");
},
success: function (data, textStatus, XmlHttpRequest) {
if (successCallback) {
successCallback(data.d, textStatus, XmlHttpRequest);
}
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
if (errorCallback)
errorCallback(XmlHttpRequest, textStatus, errorThrown);
else
alert("Error on the creation of record; Error – " + errorThrown);
}
});
}
Solved. Case sensitivity. Was using wrong case for new_new_se_invitation_new_se_registId.
var new_se_registration = {
new_new_se_invitation_new_se_regist**I**d: {
__metadata: { type: "Microsoft.Crm.Sdk.Data.Services.EntityReference" },
Id: invitationGUID,
LogicalName: invitationName
},
new_name: invitationName,
new_eventname: eventname
};

Resources