How to call node.js REST API from .NET - asp.net

If I put the jquery code below within the script tag within a html page and drag the html page into a web browser the call to the API specified in the URL is made and I get back a response in JSON format. So this works good.
The reason I want to use .NET for calling the rest API that is made in node.js is because I want to use the unit test utility that exist in visual studio.
So when I start the unit test the call to the REST API made in node.js should be made and then I can check whatever I want in the returned json format by using the assert.AreEqual.
I have googled a lot and there is several example about
Unit Testing Controllers in ASP.NET Web API 2 but I don't want to unit test controller. I only want to call the REST API(made in node.js) when I start my unit test.
I assume to use .NET in the way I want is probably quite rare.
If it's not possible to use .NET and unit test in the way that I want here
I will use another test framework.
I hope to get some help from here.
Hope you understand what I mean.
$.ajax({
type: 'GET',
url: 'http://10.1.23.168:3000/api/v1/users/1',
dataType: 'json',
async: false,
headers: {
'Authorization': 'Basic ' + btoa('DEFAULT/user:password')
},
success: function(response) {
//your success code
console.log(response);
},
error: function (err) {
//your error code
console.log(err);
}
});
Many thanks

Basically what you need to do is to call node.js' API from your C# test code in a same way you call it using jQuery. There are several ways to do it:
Use HttpWebRequest class https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest%28v=vs.110%29.aspx
Use HttpClient class https://msdn.microsoft.com/en-us/library/system.net.http.httpclient%28v=vs.118%29.aspx It's more "RESTable" since it exposes methods to call HTTP methods like GET, PUT, POST and DELETE methods directly.
3rd party software http://restsharp.org/
Generally I recommend approach #2.

Here's the example source with all the rest of the code.
Another resource is the docs.
This code snippet should be enough to get you where you need.
using(var client = newHttpClient())
{
client.BaseAddress = newUri("http://localhost:55587/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(newMediaTypeWithQualityHeaderValue("application/json"));
//GET Method
HttpResponseMessage response = awaitclient.GetAsync("api/Department/1");
if (response.IsSuccessStatusCode)
{
Departmentdepartment = awaitresponse.Content.ReadAsAsync < Department > ();
Console.WriteLine("Id:{0}\tName:{1}", department.DepartmentId, department.DepartmentName);
Console.WriteLine("No of Employee in Department: {0}", department.Employees.Count);
}
else
{
Console.WriteLine("Internal server Error");
}
}

Related

How to call server api decorated with ValidateAntiForgeryToken using Httpclientfactory Typed clients?

I am trying to incorporate a Edit Form page using GetAsync and PostAsync using typed httpclient. Everything works except my code doesn't call API actions with ValidateAntiForgeryToken. Most of the examples online do not address httpcontent used by httpclientfactory and instead use httpresponse. I am aware that the antiforgery token is missing on my request. How do I attach it to the request header? How do I retrieve it from the view? I want to use as less Javascript as possible. Here's a snippet of my Post request service.
Edit: For what it's worth, my api is dot net core and client is dot net core mvc.
var response = await _httpclient.PostAsync("api/edit/" + id, httpcontent);
response.EnsureSuccessStatusCode(); ```
In the MVC Edit view page, it will use a hidden file (named __RequestVerificationToken) to store the ValidateAntiForgeryToken, you can use F12 developer tools to check it.
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
After modifying the data, you could use JQuery to get the updated data, then use JQuery ajax to call the API method with the ValidateAntiForgeryToken. You can refer the sample code in my reply:
if we customize antiforgery options in Startup.ConfigureServices, such as: custom the Header Name for the RequestVerificationToken.
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN"); //configure the antiforgery service to look for the X-CSRF-TOKEN header. To prevent the cross-site request forgery.
Then, we could use the following script:
$.ajax({
type: "POST",
url: "/Survey/Create",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: { "CategoryName": $("#CategoryName").val(), "CategoryID": $("#CategoryID").val() },
success: function (response) {
alert(response);
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
Besides, you can also refer Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core.

Best way to intercept XHR request on page with Puppeteer and return mock response

I need to be able to intercept XHR requests on page loaded with Puppeteer and return mock responses in order to organize backendless testing for my web app. What's the best way to do this?
It seems that the way to go is request.respond() indeed, but still, I couldn't find a concrete example in the web on how to use it. The way I did it was like this:
// Intercept API response and pass mock data for Puppeteer
await page.setRequestInterception(true);
page.on('request', request => {
if (request.url() === constants.API) {
request.respond({
content: 'application/json',
headers: {"Access-Control-Allow-Origin": "*"},
body: JSON.stringify(constants.biddersMock)
});
}
else {
request.continue();
}
});
What happens here exactly?
Firstly, all requests are intercepted with page.setRequestInterception()
Then, for each request I look for the one I am interested in, by matching it by URL with if (request.url() === constants.API) where constants.API is just the endpoint I need to match.
If found, I pass my own response with request.respond(), otherwise I just let the request continue with request.continue()
Two more points:
constants.biddersMock above is an array
CORS header is important or access to your mock data will not be allowed
Please comment or refer to resources with better example(s).
Well. In the newest puppeteer,it provide the request.respond() method to handle this situation.
If anyone is interested I ended up creating special app build for my testing needs, which adds Pretender to the page. And I communicate with Pretender server using Puppeteer's evaluate method.
This is not ideal, but I couldn't find a way to achieve what I need with Puppeteer only. There is a way to intercept requests with Puppeteer, but seems to be no way to provide fake response for a given request.
UPDATE:
As X Rene mentioned there is now native support for this in Puppeteer v0.13.0 using request.respond() method. I'm going to rewrite my tests to use it instead of Pretender, since this will simplify many things for me.
UPDATE 2:
There is pptr-mock-server available now to accomplish this. Internally it relies on request interception and request.respond() method. Library is pretty minimal, and may not fit your needs, but it at least provides an example how to implement backendless testing using Puppeteer. Disclaimer: I'm an author of it.
I created a library that uses Puppeteer's page.on('request') and page.on('response') to record and respond with mocked requests.
https://github.com/axiomhq/puppeteer-request-intercepter
npm install puppeteer-request-intercepter
const puppeteer = require('puppeteer');
const { initFixtureRouter } = require('puppeteer-request-intercepter');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Intercept and respond with mocked data.
const fixtureRouter = await initFixtureRouter(page, { baseUrl: 'https://news.ycombinator.com' });
fixtureRouter.route('GET', '/y18.gif', 'y18.gif', { contentType: 'image/gif' });
await page.goto('https://news.ycombinator.com', { waitUntil: 'networkidle2' });
await page.pdf({ path: 'hn.pdf', format: 'A4' });
await browser.close();
})();
You may want to try out Mockiavelli - request mocking library for Puppeteer. It was build exactly for backendless testing of webapps. It integrates best with jest and jest-puppeteer, but works with any testing library.

AngularJS $httpBackend asynchronous response

I'm trying to mock the back-end for an AngularJS(1.3.8)-app with ngMockE2E as replacement until the back-end code has been written.
I'm using already existing services that also query other data, however they return a promise. I am aware that ngMockE2E is supposed to be synchronous, however I wanted to see if there's a way to do it asynchronously first.
Looking around the web I found this and put the mocking-related code into its own seperate module to see if this approach works.
$httpBackend.whenAsync('projects/').respond(function (promise, headers, status) {
var deferred = $q.defer();
_getProjectIndex().then(function (result) {
deferred.resolve(result);
},
function (statusCode) {
console.log(statusCode);
deferred.reject(statusCode);
});
return deferred.promise;
});
When I try to run $httpBackend.whenAsync() the request just seems to 404. Checking the same request with $httpBackend.whenGET() I receive the promise containing the data I requested.
What am I doing wrong?

How does Angular know there was an error on an $http request?

How does the $http function of Angular "know" the response was an error in an ASP.NET request? I'm looking at the response headers but don't see anything that looks relevant.
I have this service in Angular:
service.getStuff = function () {
return $http({
method: 'GET',
url: './GetJsonData.aspx?RequestType=Stuff'
//That asp.net page returns json on success, but a regular
//asp.net error page on failure. I know there's better ways,
//but ignore that, that's not the question here.
});
}
and I use it like this:
$scope.reloadData = function () {
MyService.getStuff().success(function (response) {
alert("good");
})
.error(function (response) {
alert("bad");
});
};
That asp.net page is (correctly) throwing an exception on bad input and angular is (correctly) recognizing it as an error. But I can't figure out it knows there was an error. Is there some header that's it looking for? In the success case I receive json and in the failure case i receieve HTML, so as a human; but the angular code doesn't know that. So how is it recognizing this was an error?
It uses the HTTP status codes. This is standard behavior for restful clients and services.

Express.js get http method in controller

I am building a registration form (passport-local as authentication, forms as form helper).
Because the registration only knows GET and POST I would like to do the whole handling in one function.
With other words I am searching after something like:
exports.register = function(req, res){
if (req.isPost) {
// do form handling
}
res.render('user/registration.html.swig', { form: form.toHTML() });
};
The answer was quite easy
exports.register = function(req, res) {
if (req.method == "POST") {
// do form handling
}
res.render('user/registration.html.swig', { form: form.toHTML() });
};
But I searched a long time for this approach in the express guide.
Finally the node documentation has such detailed information:
http://nodejs.org/api/http.html#http_http_request_options_callback
Now you can use a package in npm => "method-override", which provides a middle-ware layer that overrides the "req.method" property.
Basically your client can send a POST request with a modified "req.method", something like /registration/passportID?_method=PUT.
The
?_method=XXXXX
portion is for the middle-ware to identify that this is an undercover PUT request.
The flow is that the client sends a POST req with data to your server side, and the middle-ware translates the req and run the corresponding "app.put..." route.
I think this is a way of compromise. For more info: method-override

Resources