How do I make a simple http response to a stream - c#

I'm trying to write a simple http server as a part of an application. It needs to respond to Http requests submitted with ajax on 127.0.0.1:someport with a simple text response. A javascript app will poll (or eventually longpoll) for information on the local users actions.
At the moment I've got an httpListener that calls the following as part of its callback processing:
private void ProcessRequest(HttpListenerContext context)
{
var stream = context.Response.OutputStream;
var resp = Encoding.UTF8.GetBytes("This is a test response" + DateTime.Now.ToShortTimeString() + "\r\n\r\n");
stream.Write(resp, 0, resp.Length);
stream.Close();
}
Which provides a result if called from the browser, but an error if called with $.ajax.
What is the minimum I need to return to get a sucess response to a query such as
$.ajax({
url: 'http://127.0.0.1:12345/',
dataType: 'text',
success: function (data) {
$('#res').html(data);
},
error: function(jqXHR, textStatus, errorThrown)
{
alert(textStatus);
}
}
);
Edit:
I believe I have avoided the cross site scripting issues by running
netsh http add urlacl url=http://*:12345/app user=domain\user
and can trace that the ProcessRequest is called

I suspect that your web service works fine. If you're calling it from a file URL, however, your document will not be able to call any URLs hosted under localhost:12345 because it's considered cross-domain. Try hosting the HTML and JavaScript under the same web site; you may see more success doing so.

Related

which cookies/headers should I set?

I should get a protected page from external site, if I call it directly, I get an error:
Bad Request
Postman:
But if I call a login page with valid credentials via Postman:
and then recall THE SAME resource page from the same Postman I got the protected page!:
I have to get the same page on website. I try to implement it by the following way:
var loginXml = "<Request><MsgType>Authenticate</MsgType><SubMsgType>Login</SubMsgType><UserID>my_login</UserID><passwordNotEncrypted>my_password</passwordNotEncrypted></Request>";
$.ajax(
{
url: 'https://address/browserservices.aspx/login',
type: 'POST',
contentType: 'text/xml',
datatype: 'text',
//xhrFields: {
// withCredentials: true
//},
//crossDomain: true,
data: loginXml,
success: function (output, status, xhr) {
alert(xhr.getResponseHeader("Set-Cookie"));
$.ajax({
url: "https://address/RemoteSupport.aspx?id=GUID&pltFrmType=Android&agentversion=13.46",
type: 'GET',
xhrFields: { withCredentials: true },
//crossDomain: true,
success: function (x) { },
error: function (xhr, textStatus) { alert(xhr.status); }
});
},
})
but I get Bad Request again.
Which headers/cookies should I pass to page to open protected page, like it's in Postman?
ADDED 28/01/19
Postman "Cookie" tab after success login request (fail login request has the same):
and "Headers" tab:
as I see, all access-control-allow header are available. What should I pass via ajax?
Based on the information that you have supplied there are two likely scenarios.
Firstly, the cookie that is set by the external site is HttpOnly. This is easy enough to check in Postman, by clicking on the the Cookies tab.
The second option is a little more complex, but the external server has to set the Access Control headers correctly. Again there is a Headers tab to view these. More info on cross domain ajax and headers in this question: Why is jquery's .ajax() method not sending my session cookie?
Finally worth noting, your browser will automatically add a header to indicate that it is an ajax request. You could try adding the X-Requested-With: XMLHttpRequest header in Postman and seeing how it differs from your examples. The external server may well be configured to respond differently to ajax requests than to browser or server-server api requests.
Update
Your Postman update shows that both of those scenarios are true. Unfortunately this means that you cannot achieve your desired result with JavaScript. HttpOnly = true means that the browser will never allow the script on your page to access the cookie.
At this point your best bet is probably to write a little proxy method on your own site that makes the request server to server and then returns the result to your JavaScript code. This should bypass all the above issues albeit you need to make 2 requests instead of 1 for the data.
Take a look at this answer for some code
Struggling trying to get cookie out of response with HttpClient in .net 4.5

Ajax error - errorThrown in ASP.NET MVC application

I am writing an asp.net MVC application that will compliment another application that I have written. In my old application, I send errors from the controller to the client like so:
return new HttpStatusCodeResult(400, "Whatever went wrong.")
Then, on my client side the ajax error looks a little like this:
error: function (jqXHR, textStatus, errorThrown) {
redAlert(errorThrown);
}
This all works perfectly. Whatever message I put in on the controller side will pop up on the client side.
Now, I have tried to do the same thing with this new application. However, errorThrown has nothing in it every time.
I have no idea where to start looking so any help or guidance will be much appreciated.
Thanks!
EDIT 1
After talking through some stuff with Shyju, it seems that HttpStatusCodeResult is not sending the message back in the header in the new application. Still trying to work this out.
Edit 2
After some testing, I have found that the Custom Error message doesn't get sent through using SSL. Why would this be an issue and how can I solve this? I need to use SSL as the application requires Work Account Authentication.
When your server code returns a 400 bad request response from your web api controller, the message text you are sending will be in the response from the server as
{"Message":"Whatever went wrong."}
Now the $.ajax will use this response and create a js object from that and set it to the responseJSON property of the jqXHR object. So you may simply access that.
$.ajax({
url: 'yourApiEndpoint'
}).done(function (data) {
console.log(data);
}).fail(function (jqXHR, textStatus, errorThrown) {
if (jqXHR.responseJSON) {
alert(jqXHR.responseJSON.Message);
}
});
When you return HttpStatusCodeResult from an MVC controller action method, IIS will return the markup for the 400 page. So the response is basically the HTML markup. The response headers will have the status code and the message and the $.ajax method will set the status message you send from server to the statusText property of the xhr object.
.fail(function (jqXHR, textStatus, errorThrown) {
if (jqXHR.statusText) {
alert(jqXHR.statusText);
}
});

POST call not returning a result from REST API calling async function

We need to capture any client side errors happening in one of our third party web apps.
To do so, I have written an API Post call within one of our API controllers.
I used the below code in my API:
(EnableCors is a part of nuget packages as system.web.cors which enables cors for API calls):
[EnableCors(origins: "/the client address that will call this API method", headers: "*", methods: "OPTIONS, POST, GET, PUT")]
[System.Web.Http.HttpPost]
public HttpResponseMessage RecordLogMessage(EventLogSaveCommand eventLog)
{
var result = await _mediator.SendAsync(eventLog);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
It is a POST method and I'm sending the command request to mediator's async message handler, the client call in chrome dev tools returns the "Provisional headers are shown", I suspected it might be addons that I installed on my Chrome browser, so I tried it in firefox and IE as well, they both return "Pending" status for the POST call and it seems that it is waiting for a return status code form host server.
While the event log has been inserted into data base and action is actually finished, but it's not able to return the OK (or created code, I tried both) status code to the client.
After searching on internet, I noticed that RESTFull API POST does not treat the async calls in the same way as sync calls so I had to replace the response code to "SeeOthers":
return Request.CreateResponse(HttpStatusCode.SeeOther, result);
But this did not help, as it caused even the mediator did not save the data in the database.
The second way I tried, I changed the mediator handler as a sync call, so I used mediator.Send(eventLog) and returned response status code as:
return Request.CreateResponse(HttpStatusCode.OK, result);
This worked fine, client got the OK status code in respond.
But I want to know how can I use the mediator's async call and what is the problem with the result code, why is it not able to return the result even though it has successfully finished the command.
Also here is how I am calling this from client:
var jsonData = JSON.stringify({message:"Test message", Uri:"Test url", source: "Test Source" , columnNo: "Test columnNo", error: "Test Error", lineNo: "Test Line No"});
$.ajax({
type: "POST",
url: 'https://Myhost.com/api/CustomEventLog/RecordLogMessage/',
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: false,
success: function(response){
console.log("Error recorded in log table with id: "+ response);
// alert(response);
}
});
Ok, For anyone who might be interested, I changed my POST call to be async call as well as below:
[EnableCors(origins: "*", headers: "*", methods: "OPTIONS, POST, GET, PUT")]
[System.Web.Http.HttpPost]
public async Task<HttpResponseMessage> RecordLogMessage(EventLogSaveCommand eventLog)
{
//var result = _mediator.Send(eventLog);
//return Request.CreateResponse(HttpStatusCode.OK, result);
var result = await _mediator.SendAsync(eventLog);
return Request.CreateResponse(HttpStatusCode.SeeOther, result);
}
This worked fine and client call had the result and new log was created as well.
Thanks

Error thrown while performing ajax call to web api

I have the following basic code. I tried to debug this code but the javascript is very painful to debug, and I do not know where it is failing:
jQuery.support.cors = true;
var packet = {
Image: imageAsString,
PhnType: phoneType,
PhnMdl: phoneManufacturer
};
$.ajax({
url: "https://molecheckerservices2.azurewebsites.net/api/Testing/SubmitTestingData",
type: "POST",
dataType: "json",
data: JSON.stringify({ packet }),
success: function(data, textStatus, xhr) {
alert('yes');
window.localStorage.setItem("dataObject", JSON.stringify(data));
window.location = "results.html";
},
error: function (xhr, textStatus, errorThrown) {
alert('no');
window.localStorage.setItem("dataObject", JSON.stringify([.33, .33, .33]));
window.location = "results.html";
}
it gives me back an alert no, which corresponds with a failure. Additionally as I debug I see in my Javascript console that the error:
Failed to load resource: the server responded with a status of 400 (Bad Request)
Pops up. I tried to look up what this mean but I would be incredibly grateful for any problem specific advice!
Open up Fiddler and manually POST to your endpoint. If you do that, you will see the same error message I saw:
{"message":"No API version was specified in the request, this request needs to specify a ZUMO-API-VERSION of '2.0.0'. For more information and supported clients see: http://go.microsoft.com/fwlink/?LinkId=690568#2.0.0"}
It has a handy-dandy link in there for you. Also, here is a SO answer that possibly applies to you.
I did add the header mentioned above, resent the request and I received that sweet 200 response from your service, so I'm pretty sure that's your issue.
P.S. If you don't want random strangers inserting data into your app like I just did, you should secure your service or at least obfuscate the URL when mentioning it in public.

AJAX requests from jquery in android application to WCF Service always fails

I have an application where I fetch a list of requests made by the user based on the idNo provided. The android application uses AJAX to make a request to a .NET WCF Service which in turn returns a IEnumerable of DTO for that request.
Following is the AJAX Code:
$.ajax({
url: baseURL + "RequestStatusList/"+idNo,
cache : false,
type : "GET",
dataType : "json",
contentType : "application/json; charset=utf-8",
crossdomain : true,
success : function(data, tst, xhr) {
//do something here
},
error: function (xhr, tst, err) {
alert(' Please Try Again ' + xhr.status);
}
});
A similar piece of code works in another page in the application, where only the process in success is different, rest all is same.
Here every time the request fails and enters the error section and displays undefined/0 as error. No details about error, hence i cannot get what maybe the problem.
When I debug the server side code I get proper value in the parameter passed and a IEnumerable is formed and returned. What fails is the client side code after successful execution of server code.
Please Help.
Thanks in advance.

Categories

Resources