I am trying to apply some changes to my client side JavaSript objects from an ODataController based service after making a PATCH call using JayData. How do I view the HTTP response (200) after making a PATCH request? I don't see where the JayData API exposes the response. My code looks something like this:
var deferred = $q.defer();
self.context.ready.then(function (cxt) {
myAwesomeEntity.entityState = $data.EntityState.Modified;
cxt.myAwesomeEntitys.attach(myAwesomeEntity, true);
// HACK update the TimeStamp reference to trick JayData into including it in the HTTP PATCH request.
var temp = myAwesomeEntity.Timestamp;
myAwesomeEntity.Timestamp = [];
myAwesomeEntity.Timestamp = temp;
cxt.saveChanges().then(function (data) {
deferred.resolve(data); // Shouldn't data be the HTTP Patch response? It's actually "3".
}, function (error) {
//Handle error here...
});
});
return deferred.promise;
The HTTP Patch (200) response looks something like:
{
"odata.metadata": "http://localhost:21171/odata/$metadata#MyAwesomeEntity/#Element",
"odata.type": "MyNamespace.MyAwesomeEntity",
"odata.id": "http://localhost:21171/odata/MyAwesomeEntity(guid'14812a96-8da1-4202-b8c7-a5697774ae4b')",
"SomeCollection#odata.navigationLinkUrl": "http://localhost:21171/odata/MyAwesomeEntity(guid'14812a96-8da1-4202-b8c7-a5697774ae4b')/SomeCollection",
"Timestamp#odata.type": "Edm.Binary",
"Timestamp": "AAAAAAJxWhg="
}
The JayData oDataProvider returns the count of the number of items affected. I modified it to return the actual items modified.
Related
I have built a simple Api that returns a few places with associated data, and everything works fine, but i have a more specific research method that also is working fine in testing phase using Postman. I've made a few requests in my web application and they receive expected result, but now I've come to the point where I need to call this method I made, which returns proper response on Postman but 404 on my web application when I log the response message.
This is how I make my request:
<script>
function getCities() {
var selectedRegion = document.getElementById("region_select").value;
$.ajax({
type: "GET",
url: '#Url.Action("ShowCitiesByRegion", "ClientTourism")',
accepts: "/",
data: {
regionId: selectedRegion
},
success: function (data) {
$('#city_select_div').html(data);
},
failure: function (response) {
console.log(response.responseText);
},
});
console.log(selectedRegion);
}
</script>
This request calls up my controller, which looks like this:
public async Task<IActionResult> ShowCitiesByRegion(int regionId)
{
System.Diagnostics.Debug.WriteLine("ID DA REGIAO-" + regionId);
List<City> cities = new List<City>();
HttpClient httpClient = _api.Initial();
HttpResponseMessage httpResponseMessage = await httpClient.GetAsync("api/Cities/region_cities/region=" + regionId);
if (httpResponseMessage.IsSuccessStatusCode)
{
var response = httpResponseMessage.Content.ReadAsStringAsync().Result;
cities = JsonConvert.DeserializeObject<List<City>>(response);
System.Diagnostics.Debug.WriteLine("Cidades-" + cities);
}
else
{
System.Diagnostics.Debug.WriteLine("Erro" + httpResponseMessage);
}
return PartialView(cities);
}
This controller calls up the api and it never gets a SuccessStatusCode.
My API console run never indicates it is receiving the request, except when its coming from Postman.
I've narrowed the problem to the request making, although I checked every variable and every data is passing through view to controller as expected. It returns this response message:
Cant seem to figure why I am always getting 404 while doing this request from my web application.
Try to write the complete url in httpclient:
"https://hostname/api/Cities/region_cities/region=" + regionId
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().
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).
I am trying to make a POST request.
Here my code:
var myModel = new MydModel({
content: "ciao"
});
console.log(myModel.get("content")); // "ciao"
myModel.save();
If I look to the network activity it looks like this:
The response part {id:0, content:"", ……}
In the header part: Request Payload {"content":"ciao"}
Here my model:
define([], function () {
var MyModel = Backbone.Model.extend({
url: function url ()
{
return "http://localhost/users";
}
});
return MyModel;
});
Is it my problem or is it in the server part?
send/receive vs request/response
a server receives requests and sends responses
a client sends requests and receives responses
in short
if {id:0, content:"", ……} (the response) is wrong, it's your server
if {"content":"asdasdsa"} (the request) is wrong, it's your client
There is little problem with receiving JSON-payload that "Backbone-client" sends to your Apache-server.
All you need to do is to manually parse JSON-payload from input on the server side ("php://input", for PHP), like this:
if($_SERVER['REQUEST_METHOD'] == 'PUT' || $_SERVER['REQUEST_METHOD'] == 'POST') {
$postStr = file_get_contents("php://input");
//json_decode throws error or returns null if input is invalid json
try {
$json = json_decode($postStr, true);
if(empty($json)) {
throw new Exception("Not valid json");
}
//must not be json, try query str instead
} catch(Errfor $e) {
$postVars = parse_str($postStr);
foreach($postVars as $key=>$data) {
$_POST[$key] = $data;
}
}
}
Full explanation you can find here:
http://colinbookman.com/2014/04/08/php-puts-posts-and-backbone-js/
I'm currently developing a Firefox add-on(using https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/ ) that consumes an API where the return data is in xml.
My problem is that I need to parse the returned data, and would like to do that using a xml object.
Since the request module only supports JSON and Text ( https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/packages/addon-kit/docs/request.html#Response ) I need to convert the response.text to XML.
The code looks like this:
var Request = require('request').Request
.......
var req = Request({
url: https://to-the-api.com,
content: {
op: 'get-the-data-op',
password: "super-sec",
user: "username"
},
onComplete: function (response) {
dataAsText = response.text;
console.log("output: " + dataAsText);
}
});
req.post();
I have tried to user (new DOMParser).parseFromString(response.text, 'text/xml') but unfortunately it just fails with a error like ReferenceError: DOMParser is not defined
The question is if anyone of you guys have been able to create a Xml object inside a Firefox add-on, and if so, how?
Looks like the capability to parse response as xml was present, but has been removed. check out this bugzilla reference
Can't you use a normal XMLHttpRequest if you want to process the response as XML?
If DOMParser is unavailable you can try E4X:
var xml = new XML(response.text);
alert(xml.children().length());
You want to use the XMLHttpRequest object to handle your xhr request. Then when you get a response back access the responseXML object of the request variable. In the responseXML you'll have the documentElement and can use the querySelectorAll or querySelector to find elements you want. In each element you want just grab the textContent you need.
Here's an example to get you going (this looks for the 'xmls' element in the response):
var request = new require("xhr").XMLHttpRequest();
request.open('GET', 'https://to-the-api.com', true);
request.onreadystatechange = function (aEvt) {
if (request.readyState == 4) {
if(request.status == 200) {
var xmls = request.responseXML.documentElement.querySelectorAll("xmls");
for (var i = 0; i < xmls.length; i++) {
console.log("xml", i, xmls[i], xmls[i].textContent);
}
}
else {
console.log('Error', request.responseText);
}
}
};
request.send(null);