Server Returns Bad Request 400 On REST POST CALL, even though uri is correct - rest

I am trying to add an option label and option value to an optionset field(new_contractserving) found on an entity called new_servingtime. Not sure if I am doing this correctly, but the server throws a 400 Bad request, what's the issue?!
var entity = {
"new_contractserving": String(OptionValue),
"new_contractserving#OData.Community.Display.V1.FormattedValue": String(OptionText)
};
var reqJSON = new XMLHttpRequest();
reqJSON.open("POST", url + "/api/data/v8.2/new_servingtimes", false);
reqJSON.setRequestHeader("OData-MaxVersion", "4.0");
reqJSON.setRequestHeader("OData-Version", "4.0");
reqJSON.setRequestHeader("Accept", "application/json");
reqJSON.setRequestHeader("Content-Type", "application/json; charset=utf-8");
reqJSON.onreadystatechange = function () {
if (this.readyState === 4) {
reqJSON.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 + ": Third Request!");
return;
}
}
};
reqJSON.send(entity);

HTTP 400 means bad data. If it was "URI not found" it would have been a HTTP 404
HTTP 400 on a POST usually means, your request (requestbody) failed some validation on the server side or it did not confine to the format which server is expecting

You should be using InsertOptionValue Action to add new option to the existing picklist attribute in an entity.
CRM REST Builder is the best choice to compose such requests & test.
The request you have written can be used to set attribute value in a record, but still it’s incomplete. Read this blog to understand how you can execute webapi action.

Related

I wana have my application to fetch a html web page but i keep getting -400 whatever i try monkey c / garmin connect

even this exemple i found on the site of garmin has the same problem
https://developer.garmin.com/connect-iq/core-topics/https/
import Toybox.System;
import Toybox.Communications;
import Toybox.Lang;
class JsonTransaction {
// set up the response callback function
function onReceive(responseCode as Number, data as Dictionary?) as Void {
if (responseCode == 200) {
System.println("Request Successful"); // print success
} else {
System.println("Response: " + responseCode); // print response code
}
}
function makeRequest() as Void {
var url = "https://www.garmin.com"; // set the url
var params = { // set the parameters
"definedParams" => "123456789abcdefg"
};
var options = { // set the options
:method => Communications.HTTP_REQUEST_METHOD_GET, // set HTTP method
:headers => { // set headers
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_URL_ENCODED},
// set response type
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_URL_ENCODED
};
var responseCallback = method(:onReceive); // set responseCallback to
// onReceive() method
// Make the Communications.makeWebRequest() call
Communications.makeWebRequest(url, params, options, method(:onReceive));
}
}
can some one please tel me what i am doing wrong
The return code -400 means "Response body data is invalid for the request type." according to the SDK specification.
You are requesting a response type of Communications.HTTP_RESPONSE_CONTENT_TYPE_URL_ENCODED but in your question you state that you are expecting HTML to be returned, which almost certainly can't be parsed as URL encoded form parameters.
The SDK does not seem to support HTML response types. Even if you omit the expected response type, the server will probably still send "application/html" and the SDK states that "If the Content-Type header from the response is not one of the known HTTP_RESPONSE_CONTENT_TYPE_* types, an error will occur", so I guess you're out of luck.
Maybe you can try to request HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN in order to get the server to return text instead of HTML, which you then could use somehow?

Adding API key to header for WCF service to check

I am implementing an api key for a basic web service I have. I am using an implementation found here: https://blogs.msdn.microsoft.com/rjacobs/2010/06/14/how-to-do-api-key-verification-for-rest-services-in-net-4/
I know I have it all implemented and setup correctly on the service side but I am not sure how to pass the API key from my client. When I debug the web service upon request I don't get anything returned for my HttpRequestMessage query string. Here is code:
Web service auth manager:
public string GetAPIKey(OperationContext oc)
{
// get the request
var request = oc.RequestContext.RequestMessage;
// get HTTP request message
var requestProp = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
// get the actual query string
NameValueCollection queryParams = HttpUtility.ParseQueryString(requestProp.QueryString);
// return APIKey if there, NameValueCollection returns null if not present
return queryParams[APIKEY];
}
Client consumption (the part that matters):
using (WebClient client = new WebClient())
{
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("APIKey","my_generated_key");
client.Encoding = Encoding.UTF8;
Console.WriteLine(client.UploadString("http://my_local_host/my.svc/myCall", "POST", data));
}
During debug, the web service is always getting empty queryParams in the NameValueCollection because the query string is empty. How do I add to that query string during the request made from the client?
Solved. The solution was to not try to pull from the HttpRequestMessageProprty.QueryString but to just pull from the headers.
Code:
public string GetAPIKey(OperationContext oc)
{
// get the request
var request = oc.RequestContext.RequestMessage;
// get HTTP request message
var requestProp = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
// get the actual query string
NameValueCollection queryParams = requestProp.Headers;
// return APIKey if there, NameValueCollection returns null if not present
return queryParams["APIKey"];
}

How to post JSON to a URL using the Servoy Framework

The Servoy Framework does not support standard methods of calling a URL (eg: AJAX, JQuery, etc.). How does one go about posting a JSON object to a URL?
The Servoy JavaScript framework relies on the http plugin (included as aprt of Servoy) to make HTTP Posts.
Here is some sample code of how to post JSON to an API using Servoy. I have also included some basic error handling. Refer to the code comments for explanations of what the code is doing:
var sURL = 'http://www.example.com/myapipath/';
var oJSON = {"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]};
var sClient = plugins.http.createNewHttpClient(); // HTTP plugin object
var sPoster = sClient.createPostRequest(sURL); // Post request object
sPoster.addHeader('content-type','application/json'); // required for JSON to be parsed as JSON
sPoster.setBodyContent(JSON.stringify(oJSON));
application.output('Executing HTTP POST request and waiting for response from '+sURL, LOGGINGLEVEL.INFO);
var sResponse = null;
var sResponseData = "";
var nHttpStatusCode = 0;
var sCaughtException = '';
try {
nHttpStatusCode = (sResponse = sPoster.executeRequest()).getStatusCode(); // POST JSON request to API
}
catch (e) {
// This handles the case when the domain called does not exist or the server is down, etc.
// in this case there will be no HTTP status code returned so we must handle this differently
// to prevent the Servoy application from crashing
sCaughtException = e['rhinoException'].getMessage();
if (-1 != sCaughtException.indexOf('TypeError: Cannot call method "getStatusCode"')) {
application.output('WARNING: Could not determine HTTP status code. The server might be down or its URL might be invalid.', LOGGINGLEVEL.WARNING);
}
else {
application.output('WARNING: caught unknown HTTP POST exception: '+sCaughtException, LOGGINGLEVEL.WARNING);
}
}
// SUCCESS!:
if (200 == nHttpStatusCode) { // HTTP Ready Status
sResponseData = sResponse.getResponseBody(); // Get the server's response text
application.output('Successful, response received from server:',LOGGINGLEVEL.INFO);
application.output(sResponseData, LOGGINGLEVEL.INFO);
// put your code to handle a successful response from the server here
}
else {
// insert your code to handle various standard HTTP error codes (404 page not found, 403 Forbidden, etc.)
}

Error 400 on SOQL Query via REST

I'm trying to do a "select * from accounts" query on salesforce via their rest API and I'm getting an ERROR 400 Bad Request. All of my rest calls seem to be working but I can't introduce a query. Can someone take a look at the code and let me know what they think?
The value that getSOQLQuery() is returning is:
url/services/data/v28.0/query?q=select+*+from+Account
HttpClient httpclient = new DefaultHttpClient();
HttpGet get = new HttpGet(getSOQLQuery());
System.out.println(getSOQLQuery());
get.setHeader("Authorization", "OAuth " + auth.getAuthToken());
get.setHeader("content-type", "application/json");
HttpResponse result = httpclient.execute(get);
String json = EntityUtils.toString(result.getEntity(), "UTF-8");
JSONParser parser = new JSONParser();
Object resultObject = parser.parse(json);
Object obj = resultObject.toString();
if(result.getStatusLine().getStatusCode() == 200) {
resultSet = obj;
System.out.println("DONE");
}else{
System.out.println("Error!");
System.out.println(result);
}
Thanks!
SOQL doesn't support select * you have to explicitly name the fields you want to query, e.g. select id,name from account. You can use the describe resource to find all the field names if you want to dynamically build the select list.
Also if you examine the response body of the 400 response, there'll be a detailed error message.

SugarCRM REST API Session expires frequently

I use REST API in JavaScript. When I request REST API multiple times, it returns(response) invalid session id, but I am providing a valid session id, because I have pulled data with this session id.
Anyone came across this issue?
function sugarLogin(url, user, password) {
var request = new XMLHttpRequest();
var params = {
user_auth: {
user_name: user,
password: password
},
name_value_list: [{
name: 'notifyonsave',
value: 'true'
}]
};
var json = $.toJSON(params);
var crm_api = url;
request.open("POST", crm_api, true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
var response = request.responseText;
var response_obj = jQuery.parseJSON(response);
if (response_obj) {
if (response_obj.name && response_obj.name == "Invalid Login") {
//invalid login
ProcessingFlag = 3;
} else {
session_id = response_obj.id;
ProcessingFlag = 1;
}
}
} else if (request.readyState == 4 && request.status == 404) {
ProcessingFlag = 2;
}
}
request.send("method=login&input_type=JSON&response_type=JSON&rest_data=" + json);}
I have used above code to login and set session_id (global scope)
and then using this session id I am calling search_by_module function of REST API.
It is working fine but if made multiple requests frequently then it says invalid session id.
Although I have tried to call login function again before making search_by_module call.
Main issue is when I tried calling other REST function after response returned from search_by_module and rendered HTML, it says me invalid session. I can't figure out why session expires immediately while we know that on server session expires after 24 minutes (server where our sugar instance hosted)
I bet you're getting this because of item number 3 :
1/ Defined an error callback that checks for that particular response -invalid login- and calls the login function. Reading your code, I guess this is ProcessingFlag = 3; job.
2/ make sure the login function updates the session_id correctly and globally so that future function calls will get the correct value.
3/ make sure you're passing that new session_id to all your subsequent calls as FIRST parameter in all you rest_data. I got caught on this and lost many hours only to find out that SugarCRM DOESN'T support named parameters in its rest_data (is it poorely implemented function-arguments-wise ?) This is because I was adding session_id as last parameter and all of my REST calls were returning invalid ID.