Delete entry from database with WinJS and OData - odata

I'm trying to delete an entry from the database by odata. I get the error message
{"error":{"code":"","message":{"lang":"en-US","value":"Bad Request - Error in query syntax."}}}
my code:
function deleteMonthEntry() {
var item = actMonthEntries.getItem(listIndex);
var queryString = "Stundens(" + item.data.datensatz_id + ")?$format=json";
var requestUrl = serviceUrl + queryString;
WinJS.xhr({
type: "delete",
url: requestUrl,
headers: {
"Content-type": "application/json"
}
}).done(
function complete(response) {
},
function (error) {
console.log(error);
}
);
}
My request URL looks like this:
requestUrl = "http://localhost:51893/TimeSheetWebservice.svc/Stundens(305233)?$format=json"
Thanks
Marlowe

At least I found the solution:
I've entered an filter request to my service like this:
TimeSheetWebservice.svc/Stundens?$filter=datensatz_id eq 305221
this returned the correct entry with this link:
TimeSheetWebservice.svc/Stundens(305221M)
So if I enter a M after the ID, everything works fin. But I have no idea where this M comes from.
Can anyone tell me the reason for this M? It does not belong to the ID. The ID is this
305221
Marlowe

Are you sure the server you're talking to supports the $format query option? Many don't. I would try removing that part of the request URI, and instead modify your headers value to specify an Accept header:
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
}
For servers where $format is allowed, giving it a json value is equivalent to providing an Accept header with the application/json MIME type.
In general, for a DELETE operation, the Accept header or $format value only matters for error cases. With a successful DELETE, the response payload body will be empty, so there's no need for the server to know about your format preference.

Related

IBM DataPower - How to handle HTML Response from openurl?

I tried looking for the solution in the forum but I was unable to find something similar to what I'm trying to achieve. I have a gateway script in an MPG which kinda looks like this:
session.INPUT.readAsJSON(function (error, json) {
if (error){
throw error;
} else {
var SAMLResponse = json['SAMLResponse'];
var RelayState = json['RelayState'];
var urlopen = require('urlopen');
var options = {
target: 'https://************.com/e32d32der2tj90g8h4',
method: 'POST',
headers: { 'HEADER_NAME' : 'VALUE'},
contentType: 'application/json',
timeout: 60,
sslClientProfile: 'ClientProfile',
data: {"SAMLResponse": SAMLResponse, "RelayState": RelayState}
};
urlopen.open(options, function(error, response) {
if (error) {
session.output.write("urlopen error: "+JSON.stringify(error));
} else {
var responseStatusCode = response.statusCode;
var responseReasonPhrase = response.reasonPhrase;
response.readAsBuffer(function(error, responseData){
if (error){
throw error;
} else {
session.output.write(responseData);
console.log(responseData);
}
});
}
});
}
});
I'm doing a POST request and the response I get from the urlopen function is an HTML page, how to I display the contents of that page in my browser? I need that to initiate a process flow. am I going in the wrong direction here? what's the best way to POST to a URI and display it's response in DataPower?
with regards to my experience with DataPower, I just started learning, So I might not be familiar with many of the concepts.
Thanks in Advance!
session.INPUT.readAsJSON() would indicate that you are receiving JSON data as the input (from the POST).
Since you are building this in a Multi-Protocol Gateway (MPGW) you need to set the Response type to non-xml if the response is HTML and if there is no backend call being made (other than the url-open()) you also must set the skip-backside=1 variable.
Is the scenario as:
JSON HTTP Request -> [MPGW] -> url-open() -> Backend server --|
HTTP Response <-----------------------------------------|
Or:
JSON HTTP Request -> [MPGW] -> url-open() --| (skip-backside)
HTTP Response <------------------------|
If there is no backend call I would recommend building this in a XML Firewall (XMLFW) service instead and set it to "loopback" and non-xml.
If there is a backend and that is where you are sending your HTML from the url-open() then only MPGW Response type needs to be set to non-xml.
If it is the second option the you can just set the payload and headers in GWS and just call the target (https://************.com/e32d32der2tj90g8h4) as teh MPGW backside connection, no need for the url-open().

Why the "Authorization" field in Http Headers in Alamofire set automatically?

I want to send my apiKey in headers in Alamofire to my web service.But no matter how many times I test it,I still cant to get the value of apiKey in my web service.
My web service always return this error,cause cant get the apiKey in the header.
{
"error": true,
"message": "Api key is missing"
}
This is how I make the request,I think I didnt do anything wrong,but the web service still cant get the value of apiKey.
let My_URL = "My_url"
let params : [String : Any]=["param1":value1,"param2":value2]
let headers : HTTPHeaders = [
"Content-Type":"application/x-www-form-urlencoded",
"authorization" : apiKey //<--this is the value I need to
get in header of web service
]
Alamofire.request(MY_URL,method: .post ,parameters : params ,headers:headers).responseJSON {
response in
debugPrint(response)
}
My web service currently is serving for Android and Web version.Both running well,but I really no idea why the ApiKey in headers cant get it from webservice.
Totally no idea what is going wrong..Somebody please help!!!!
EDIT
I attach the result from debugPrint here,please take a look and let me know what is the problem,I suspect the problem is cause by the "Authorization" tag in the result below,the "Authorization" field is not the field I set,and the value as well,is not the value I want as well.
But why is this happen?? And how to solve this problem?
[Response]: <NSHTTPURLResponse: 0x60c00003d4c0> { URL: http://My_URL} { Status Code: 400, Headers {
"Access-Control-Allow-Headers" = (
Authorization
);
"Access-Control-Allow-Methods" = (
"GET, POST, PUT, DELETE, OPTIONS"
);
"Access-Control-Allow-Origin" = (
"*"
);
Authorization = ( // <--why this authorization appear
16ebe49c51039ddfbb09e5df8519e755 //this is not the value I set
);
Connection = (
close
);
"Content-Length" = (
45
);
"Content-Type" = (
"application/json"
);
Date = (
"Sun, 14 Dec 2017 14:20:59 GMT"
);
Server = (
"Apach(Ubuntu)"
);
"X-Powered-By" = (
"PHP/5.5.9-1"
);
} }
EDIT:
To solve the problem above,I read this following question
iOS Alamofire Incorrect Authorization Header
How to disable the URLCache completely with Alamofire
Therefore,I modify my request as below,but the problem still the same,the result of debugPrint is still same as above.
let configuration = URLSessionConfiguration.default
configuration.urlCache = nil
let sessionManager = Alamofire.SessionManager(configuration: configuration)
let params : [String : Any]=["param1":value1,"param2":value2]
let headers : HTTPHeaders = [
"Content-Type":"application/x-www-form-urlencoded",
"authorization" : apiKey //<--this is the value I need to
get in header of web service
]
sessionManager.request(MY_URL,method: .post ,parameters : params ,headers:headers).responseJSON {
response in
debugPrint(response)
}.session.finishTasksAndInvalidate()
I know this question was asked long time ago, but to solving other persons issue I answer it.
Removing Authorization header value is not a bug make by alamofire lib. This key and some other keys are NSURLSession reserved key, so according to apple document value of these keys may change. To avoid this issue you must change the header name to something like Authorization-App or any other key confirmed by your API team.

ActionDispatch::ParamsParser::ParseError for String Request Payload

I'm receiving a standard request from an API. It looks something like this :
It's content type and length is :
But when this hits my Rails server, Rails responds with
The reason I'm bringing this up, is because the same request seems to work on SCORM Cloud's server. If I upload the exact same content to them, and watch it in the debugger, I see it send out an application/json statement with the same Request payload, but with no unexpected token error.
Does a Rails application/json request have to be written a certain way that differs from other servers? Is there a proper way to rewrite this line in Rack Middleware to prevent this error?
Update
The javascript :
function _TCDriver_XHR_request (lrs, url, method, data, callback, ignore404, extraHeaders) {
_TCDriver_Log("_TCDriver_XHR_request: " + url);
var xhr,
finished = false,
xDomainRequest = false,
ieXDomain = false,
ieModeRequest,
title,
ticks = ['/', '-', '\\', '|'],
location = window.location,
urlParts,
urlPort,
result,
extended,
until,
fullUrl = lrs.endpoint + url
;
urlParts = fullUrl.toLowerCase().match(/^(.+):\/\/([^:\/]*):?(\d+)?(\/.*)?$/);
// add extended LMS-specified values to the URL
if (lrs.extended !== undefined) {
extended = [];
for (var prop in lrs.extended) {
if(lrs.extended[prop] != null && lrs.extended[prop].length > 0){
extended.push(prop + "=" + encodeURIComponent(lrs.extended[prop]));
}
}
if (extended.length > 0) {
fullUrl += (fullUrl.indexOf("?") > -1 ? "&" : "?") + extended.join("&");
}
}
//Consolidate headers
var headers = {};
headers["Content-Type"] = "application/json";
headers["Authorization"] = lrs.auth;
if (extraHeaders !== null) {
for (var headerName in extraHeaders) {
headers[headerName] = extraHeaders[headerName];
}
}
//See if this really is a cross domain
xDomainRequest = (location.protocol.toLowerCase() !== urlParts[1] || location.hostname.toLowerCase() !== urlParts[2]);
if (! xDomainRequest) {
urlPort = (urlParts[3] === null ? ( urlParts[1] === 'http' ? '80' : '443') : urlParts[3]);
xDomainRequest = (urlPort === location.port);
}
//If it's not cross domain or we're not using IE, use the usual XmlHttpRequest
if (! xDomainRequest || typeof XDomainRequest === 'undefined') {
_TCDriver_Log("_TCDriver_XHR_request using XMLHttpRequest");
xhr = new XMLHttpRequest();
xhr.open(method, fullUrl, callback != null);
for (var headerName in headers) {
xhr.setRequestHeader(headerName, headers[headerName]);
}
}
//Otherwise, use IE's XDomainRequest object
else {
_TCDriver_Log("_TCDriver_XHR_request using XDomainRequest");
ieXDomain = true;
ieModeRequest = _TCDriver_GetIEModeRequest(method, fullUrl, headers, data);
xhr = new XDomainRequest ();
xhr.open(ieModeRequest.method, ieModeRequest.url);
}
Rails is being "helpful" here and assuming that the client is correctly using "Content-Type" and passing a value that actually matches that content type. In other words, the payload in the request has to be parseable JSON, and the value being passed is not valid JSON.
Which is an entirely reasonable thing for it to do when you are implementing an in house API that isn't intended for maximum interoperability. What Rails doesn't know is that an LRS' document storage is supposed to be "dumb" and basically allow the client to shove whatever it wants in and get whatever it wants out, which is why SCORM Cloud accepts the request, basically it just stores the content type and the contents, and then regurgitates them as is on request.
The code you pasted is from a very old library that has poor implementation of Content-Type headers. If this code is found anywhere other than in a relatively old version of a piece of content from one of the major e-learning authoring tools then it should be updated to use a recent version of TinCanJS and improve the content type handling.
As far as making this work on Rails, sorry I don't have that much experience with it. Presumably there is a switch or something to turn off automatic request body parsing, at least that's what most other frameworks I've used have.
Does a Rails application/json request have to be written a certain way that differs from other servers?
Not that I know of no.
Is there a proper way to rewrite this line in Rack Middleware to prevent this error?
There might a way yes, maybe even without rack middlewares, although it's quite hard to help you without an actual request to work with.

Meteor - Parse Data from Incoming HTTP Request

For outgoing HTTP requests (using meteor.http.call) I can define params and/or data. The results are then available (via results.content).
How do I access and parse the body/contents/data of incoming HTTP requests?
Using iron-router, I have got as far as this:
Router.map(function () {
this.route('httpTest', {
path: '/httpTest',
action: function () {
var request = this.request;
var response = this.response;
console.log('request_body: '+ request.body);
// request.body does not work. what should it be????
N.B. I understand that I CAN access query parameters, but I want to access form data and/or json data from the body of an incoming http request.
The request is an incoming http message, which is a Readable Stream, so you can get the data of the request by reading from that stream.
The following should work (but I haven't tested it):
var readable = this.request;
var alldata = "";
readable.on('data', function(chunk) {
alldata += chunk;
})
readable.on('end', function() {
console.log('do something with alldata');
});
It may not be working because of the missing where: 'server'. Here is a working example:
Router.map(function() {
this.route('test', {
where: 'server',
action: function() {
console.log(this.request.body.make);
console.log(this.request.body.model);
this.response.writeHead(200, {'Content-Type': 'text/html'});
this.response.end('hello!\n');
}
});
});
From the command line I can hit this route with:
curl -X POST -H "Content-Type: application/json" -d '{"make":"honda","model":"civic"}' http://localhost:3000/test
Which prints the expected honda and civic in the server's terminal. It looks like this.request.body is already parsed so you can access any variables directly which is nice if your input is json.
To read the raw body, without having Node.js JSON-ify it, in a synchronous way, I used this:
Router.route("my/api", function() {
var rawBody = "";
var chunk;
while ((chunk = this.request.read()) !== null) {
rawBody += chunk;
}
}, { where: "server" });
(the asynch way proposed in another answer here didn't worked for me, although it should as per Node.js documentation).

Xhrpost not hitting the controller(url)

I am trying to post data to mvc controller and i am unsuccessful doing so..hope i get any help...here is the xhrpost call
var reqObj =
{
Id: dojo.byId("Id").value,
Password: dojo.byId("Password").value
};
console.log(reqObj );
var xhrArgs = {
url: '~/FormController/ValidateRequest',
postData: reqObj ,
handleAs: "json",
headers: { "Content-Type": "application/json", "Accept": "application/json"},
load: function (data) {
alert(data);
}
}
var deffered = dXhr.post(xhrArgs);
console.log(deffered);
}
I could not even see a post call in firebug....what might be the problem..any clues?
Thanks in advance.
I see a couple issues:
First you populate reqObj with the values you want to post, however, you put "request" into your xhrArgs.
Second, you will need to convert reqObj to json (dojo.toJson), since you are handling the post as json.
Also, I don't see a reference to the dojo.xhrPost method? Are you using sometype of framework that encapsulates that?

Resources