Where do ajax headers go when making a server call? - asp.net

I am new to the web developer side and am trying to make sense of how AJAX headers work. We use .NET Framework MVC project with some methods on the controller that are called by our views to get some data.
Example of our view ajax call to the server:
jQuery.ajax({
type: "POST",
data: { "ElementPath": ElementPath },
dataType: "json",
headers: {
'VerificationToken': forgeryId
},
url: "" + BasePath + "/Home/GetAttributes",
});
The GetAttributes method on the server accepts a string as a parameter and returns a string of JSON objects. When I put a breakpoint on the method, the only thing I see in the string parameter is the contents of ElementPath, and nothing to do with headers. In my mind the server method would also have the contents of forgeryId. So what exactly is using the headers and how?

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.

Ajax call to ASP.NEt Web Api method. Parser error when it is done from HTTPS page

$.ajax({
url: "api/basket",
type: "GET",
dataType: "json",
error: function (request, status, error) {
alert(request.responseText);
},
success: function (data) {
Process(data);
}
});
I use ASP.NEN Web forms, .Net Framework 4.0, there is an ajax call above which I make . And when it is done from normal HTTP page it gives me data, But if I make this call being on HTTPS page it returns parserror "Unexpected token <"
What is wrong?
Your ajax request isn't returning JSON, it is returning HTML or XML. Thus, when jQuery attempts to parse the response, the first character is sees is < and it throws the parse error.
Use a debugging tool such as fiddler to see exactly what your request returns.

Why is an OPTIONS request sent to the server?

I use a simple jQuery.ajax method:
$.ajax({
type: "GET",
url: serviceUrl + '/GetAgentsGroupNameById',
contentType: "application/json; charset=utf-8",
data: { id: agentsGroupId },
async: false,
success: function (data) {
agentsGroupName = data["d"];
},
error: function (request, message) {
agentsGroupName = '';
}
});
The 'Get' request is sent and I get a well-formed json response from the server.
The problem is that I see in the developer tools that another request is generated to the same URL, with request method: OPTIONS, with an empty response, and I see an error:
OPTIONS http://localhost:1004/MobileService.asmx/GetSubscribedAgentsByUserId?userId=27 500 (Internal Server Error)
What is this OPTIONS request?
Why does it happen?
P.S. I mentioned that if I delete contentType: "application/json; charset=utf-8" (and add dataType: json or jsonp), no OPTIONS request is generated, but I don't get a well-formed json as a response (I get kinda xml document)
BTW: the service is asp.net c#:
[WebMethod]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public string GetAgentsGroupNameById(int id)
PLEASE LET ME KNOW IF YOU NEED ANY FURTHER DETAILS ABOUT THE REQUEST OR THE RESPONSE
Thanks from advance!!!
The OPTIONS request is because of the Cross origin resource sharing. It is basically the web browser asking the destination server whether it allows cross domain resource sharing.
In short, you cannot make json requests to a different domain than the domain that the page is being served from.
If you are only doing GET requests, you may want to look at JSONP which solves this issue. However, it only works with GET requests.
There have been a lot of questions on this, and there is a details answer here
Try switching your $.ajax 'Type' to use the POST verb rather than GET.

ASP.NET webservice responds with Internal Server Error (500) to post and get requests

The webservice code is simple:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void receiveOrder(string json) {
Context.Response.Write("ok");
}
And the jquery calling the webservice is as follows:
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: 'http://localhost:50730/GingerWeb.asmx/receiveOrder',
data: 'test', //JSON.stringify(webOrder),
dataType: "text",
success: function(data){
if(data === "ok")
orderPlaced();
}
});
And yet the chrome console reads in provocative red:
500 (Internal Server Error)
The problem is that ASMX web-service need to find all input parameters in the request. If at least one input parameter will be not found in the request to the server the web service failed with the status code 500 (Internal Server Error).
The reason is that you send the data in the wrong way. The name of the input parameter of the web method is json (see void receiveOrder(string json)). So the data option of the $.ajax should be in the form
data: JSON.stringify({json: webOrder})
if you use type: "POST" instead of data: JSON.stringify(webOrder) which you tried before. In the case in the body of the POST request will be json=theVlue instead of just theValue.
If you would use type: "GET" the format of data parameter should be changed to
data: {json: JSON.stringify(webOrder)}
The value of the dataType should be 'json'. After the changes the $.ajax should work.
Moreover I would recommend you to use relative paths in the url option. I mean to use '/GingerWeb.asmx/receiveOrder' instead of 'http://localhost:50730/GingerWeb.asmx/receiveOrder'. It will save you from same origin policy errors.
Hello Oleg: Your explanation is simple and to the point. I had a similar problem which your explanation solved. I am providing code snippet to help 'searchers' understand what I was facing and how the above helped solve. In short I am issuing a simple jquery (.ajax) from a aspx page. I have created a webservice that gets some data from backend (cache/db) and return's the same in json format.
JS CODE:
var parameters = "{'pageName':'" + sPage + "'}"
var request = $.ajax({
type: "POST",
url: "/NotificationWebService.asmx/GetNotification",
data: parameters,
contentType: "application/json; charset=utf-8",
dataType: "json"
});
ASP.NET Code Behind for Web Service
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetNotification(string pageName)
{
JavaScriptSerializer js = new JavaScriptSerializer();
Notification ns = NotificationCache.GetActiveNotificationForPage(pageName);
if (ns != null)
{
NotificationJSData nJSData = new NotificationJSData();
nJSData.Code = ns.Code;
nJSData.displayFreq = (short)ns.DisplayFreq;
nJSData.expiryDate = ns.ToDateStr;
return js.Serialize(nJSData);
}
return null;
}
It is ABSOLUTELY necessary to ensure that you match 'pageName' variable name specified in web service code with what is sent in your data parameter of the ajax request. I had them different and changed it to be the same, after spending hours, I finally found the right solution, thanks to this post. Also, in my case I am only passing a single "name:value" pair so I didn't even have to use some json De-serialization function to get the value, pageName above gives me only the value.

Problem retrieving XML data from an ASP.NET Web service

I am trying to call a Web service to retrieve some XML data from a database. The Ajax call works fine if I use a static file e.g. like this:
$.ajax({
type: "GET",
url: "test2.xml",
data: buildXMLDataRequestObject(),
dataType: "xml",
success: getXMLDataSucceeded,
error: getXMLDataFailed
});
but fails when I try to call the Web service e.g. like this:
$.ajax({
type: "POST",
url: "Services/CheckOutService.svc/GetXMLData",
data: buildXMLDataRequestObject(),
dataType: "xml",
success: getXMLDataSucceeded,
error: getXMLDataFailed
});
The error I get is:
"The incoming message has an
unexpected message format 'Raw'. The
expected message formats for the
operation are 'Xml', 'Json'. This can
be because a WebContentTypeMapper has
not been configured on the binding.
See the documentation of
WebContentTypeMapper for more
details."
The GetXMLData method looks like this:
// Interface
[OperationContract]
[WebInvoke(ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
string GetXMLData(XMLDataRequest request);
...
// Implementation
public string GetXMLData(XMLDataRequest request)
{
request.ShopperId = ShopperId;
return checkOutManager.GetXMLData(request);
}
The GetXMLData method has been configured to return XML and the Ajax call has its datatype set as XML so I'm very confused as to what is causing the error.
EDIT: If I alter the $.ajax() call slightly so that the contentType is specified I get this error:
The data at the root level is invalid.
Line 1, position 1.
I've tried contentType: "text/xml" and contentType: "application/xml" and both give the same error.
EDIT: Yesterday (Aug 30th) I noticed that the service call would succeed if I omitted the data parameter of the ajax call. I guess there is something about the JSON object that is causing a problem. For now I have implemented this functionality on the server side of the application but I do intend to revisit this when I get some time.
My first guess would be that the content type was wrong. What do you see when you look at the stream using Fiddler or similar?

Resources