I have a hard Microsoft Visual Studio 2008, I want to make cross domain query from your web service to a WCF service, but it does not work.
Ajax code on a web page:
$.ajax (
url: "http:/сите.com/ApplicationController.svc/HelloPost/"
type: "POST",
dataType: "json",
contentType: "application/json",
success: function (data) {
alert (data);
},
error: function (jqXHR, textStatus, errorThrown) {
alert (jqXHR textStatus errorThrown);<br/>
}
});
But my WCF service:
[OperationContract]
[WebInvoke (Method = "POST", UriTemplate = "HelloPost /", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
[JSONPBehavior (callback = "callback")]
String GetPostHello (Stream data);
public String GetPostHello (Stream data)
{
HttpContext.Current.Response.AddHeader ("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader ("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader ("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader ("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End ();
return null;
}
return "Hello";
}
When a GET request with the domain it works, but try to make a POST request returns this header:
Content-Type application/json
Accept application/json, text/javascript, */*;q=0.01
Help, what could be the problem! Thank you!
For POST requests to be made cross-domain by browsers which support CORS (which is what you're using with the Access-Control headers), prior to the request the browser first sends a preflight request, which is a HTTP OPTIONS request, asking the server whether is ok to send the POST request to it. You can either add another operation which responds to the OPTIONS request, or you can implement full CORS support for WCF - it's not too simple, but I've wrote about it on http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx with the steps required to make this work.
Related
I am migrating an Ionic v1 application to Ionic v2. In one of my methods I make a call to a WCF service. In AngularJS I do it like this:
$http({
method: 'POST',
url: url,
data: JSON.stringify({ dato: 11 }),
dataType: "json",
contentType: "application/x-www-form-urlencoded"
})
And in Angular2 like this:
let data = JSON.stringify({ dato: 11 });
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded'});
let options = new RequestOptions({ headers: headers });
this.http.post(url, data, options)
.subscribe(data => {
console.log(data);
}, error => {
console.log("Error");
});
However, I receive from my C# service an error and says that the format I send to my functions is 'RAW' while waiting for it to send JSON with Angular 2
This error occurred to me in AngularJS but it was solved by adding the code I previously left in this post.
EDIT
My WCF service :
[OperationContract]
[WebInvoke(UriTemplate = "/GetCaptaciones", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat=WebMessageFormat.Json , BodyStyle = WebMessageBodyStyle.Wrapped)]
List<Captacion> GetCaptaciones(int id_captador);
AND
let data = JSON.stringify({ id_captador: 11 });
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this.http.post(url + "/GetCaptaciones", data, options).subscribe(data => {
console.log(data);
});
Not working,
But if I test from POSTMAN this works
This:
let data = JSON.stringify({ dato: 11 });
and this:
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded'});
are terribly contradictory and inconsistent.
Please try to be consistent when you make an HTTP request against a web server about how you are going to encode the request. So if intend to send a JSON body make sure that you specify the proper Content-Type request header, so that the server would know how to process this payload:
let headers = new Headers({ 'Content-Type': 'application/json'});
In addition to what Darin has said I would say you are not using BodyStyle = WebMessageBodyStyle.Wrapped correctly.
See your wcf method expects a single parameter so you could go ahead without wrappedrequest property.
[OperationContract]
[WebInvoke(UriTemplate = "/GetCaptaciones", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat=WebMessageFormat.Json)]
List<Captacion> GetCaptaciones(int id_captador);
Wrapped request means there should be some wrapper object on top of the input properties which WCF method takes as argument.
So something like this
var input =
{
"CaptacionesInput":
{
"id_captador": 11
}
};
Now wcf method becomes like
List<Captacion> GetCaptaciones(CaptacionesInputType CaptacionesInput);
I'm new here, so sorry if I'm making some mistake with the post...
I'm trying to use angularjs with ASP.NET Web Forms, and everything was going well until I need to make a request to the c# webmethods. I searched here and on other pages for the solution and didnt found anything.
Let's go to te problem: My request just return my Default.aspx html code, and not my JSON. In fact, my request doesn't call my webmethod...
app.controller('CtrlBoletos',function($scope, FactoryBoleto) {
$scope.selections = [];
$scope.boletos = FactoryBoleto.getBoletos();
$scope.gridBoletos = {
data: 'boletos',
selectedItems: $scope.selections,
multiSelect: false
};
});
app.factory('FactoryBoleto', function ($http) {
var getBoletos = function() {
$http({
method: 'POST',
url: "./Default.aspx/get_boleto",
async: false
}).success(function(result){
console.info(result);
});
};
return { getBoletos: getBoletos };
});
and this is my webmethod
[WebMethod]
public static string get_boleto()
{
List<TFechamento_Boleto> lista = new List<TFechamento_Boleto>();
JavaScriptSerializer serializer =new JavaScriptSerializer();
TFechamento fechamento = new TFechamento(2);
lista = fechamento.getDados(1).Boleto;
var json = serializer.Serialize(lista);
return json;
}
Ah, and if i make the request with JQuery AJAX I get the json...
someone help me, im getting crazy with this... and sorry for my bad english :p
I've resolved this issue by setting headers, responseType and by adding an empty data object
factory.handshake = function () {
return $http({
method: "POST",
url: urlBase.concat("/Handshake"),
data: {},
headers: { "Content-Type": "application/json" },
responseType: 'json'
});
};
...and, when I call my webmethod the result magically appears
myFactory.handshake()
.success(function (fromApi) {
alert(fromApi.d);
})
.error(function (error) {
$scope.status = 'Unable to load sport data: ' + error.message;
});
Are you missing [ScriptMethod(UseHttpGet = true)] ?
[WebMethod]
[ScriptMethod(UseHttpGet = true)]
public List<ProjectOfEmployee> GetAllProjectName()
{
return GetProjectName();
}
http://shahjadatalukdar.wordpress.com/2013/08/09/how-to-call-asmx-webservice-using-http-get-
with-jquery-ajax/
Checking, some others threads:
https://groups.google.com/forum/#!msg/angular/AQ_caU-qVJ0/Csugs6zI2-EJ
AngularJS call webmethod
I tinkered with this out of curiosity/learning Angular:
The issue is content-type header - if you don't define this, the WebMethod isn't invoked and you will get the aspx page (in both jQuery and Angular..any actually)
ASP.NET AJAX Content-Type Header Validation
There is a built-in validation layer of protection that ASP.NET enforces for both GET and POST based ASP.NET AJAX web methods, which is that regardless of the HTTP verb being used, ASP.NET always requires that the HTTP Content-Type header is set to the value application/json. If this content type header is not sent, ASP.NET AJAX will reject the request on the server.
So try this, not really sending any data, but Angular will set the header:
$http.post("default.aspx/get_boleto", {});
or in your case:
$http({
method: 'POST',
url: "./Default.aspx/get_boleto",
data: {}, //nothing really, just doing this so the header is set
async: false
}).success(.....
If you inspect your XHR call:
Angular XHR without data, Content-Type isn't set:
POST /default.aspx/helloWorld HTTP/1.1
Host: localhost:51120
Connection: keep-alive
Content-Length: 0
Cache-Control: max-age=0
Accept: application/json, text/plain, */*
Origin: http://localhost:51120
User-Agent: ....
Referer: ....
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Angular XHR with data, Content-Type is set:
POST /default.aspx/helloWorld HTTP/1.1
Host: localhost:51120
Connection: keep-alive
Content-Length: 2
Cache-Control: max-age=0
Accept: application/json, text/plain, */*
Origin: http://localhost:51120
User-Agent:...
Content-Type: application/json;charset=UTF-8
Referer: ....
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
New at Angular so if there are better/easier ways, I'll defer...
Hth...
i have the same problem as you.until now i have create an alternative solution to get json result from my c# webmethod:
$scope.yourscopefunction=function(){
$.ajax({
type: "POST",
url: "webmethodURL",
contentType: "application/json;charset=utf-8",
success: function (data) {
$.map(data.d, function (dataobject) {
alert(dataobject.yourobjectfield);
});
},
error: function (xhr, status, errorThrown) {
alert(status + "* " + errorThrown + " * " + xhr);
}
});
};
if you have an other solution better than this using $http, please tell me
This is probably a very common problem but I couldn't get through it with the solutions from internet . First let me introduce the issue ,
I have a Rest WCF service exposed as follows :
// Service operation that retrieves the KPI result
[OperationContract]
[WebInvoke(Method = "GET", RequestFormat=WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "/KPI/{monthYear}/{currentYear}/{companyCode}/{divisionCode}/{shopCode}/{parameterName}/{kpiCode}")]
int Get_SY_KPI(string monthYear,string currentYear,string companyCode, string divisionCode, string shopCode, string parameterName, string kpiCode);
I'm trying to call this service from an html form with a simple ajax call :
$.ajax({
type: "GET",
url: "http://localhost:5547/FoxWcfRest.svc/KPI/March/2014/001/001/003/END_QUANTITY_INDICATOR_HP/002",
contentType: "application/json; charset=utf-8",
success: function(response) {
alert(response);
},
error: function()
{
alert("Oops");
}
});
I'm not sure what's going wrong but I'm getting null alert msg , I've read something about crossdomain issues .. anybody could help ?
Testing with Fiddler and a client test page, I am receiving a 400 error when making an Ajax POST to my WCF service. A GET to the same url works fine though. I set a break point in the C# code on the service, but its not even getting into the method. I need some help determining what is wrong because I have no idea at this point. A similar POST worked fine previously, but I had to rewrite my Ajax call and I'm assuming I'm missing something out of that? Very confused and frustrated.
[OperationContract]
[WebGet(UriTemplate = "/{appName}/{custCode}/{custUserName}/",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
IList<Url> GetUrls(string appName, string custCode, string custUserName);
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped,
Method = "POST",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/{appName}/{custCode}/{custUserName}/")]
ResponseAction SaveDeviceInfo(string appName, string custCode, string custUserName, DeviceInfo deviceInfo);
Here is my Ajax call on the client side:
var jsDeviceInfo = {
deviceUuid: 'Unique660',
deviceModel: 'Mark3',
deviceCordova: '2.3.3',
devicePlatform: 'Android',
deviceVersion: '3.3.0'
};
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "http://localhost:xxx/Service.svc/testApp/custCode/userId",
data: JSON.stringify({ deviceInfo: jsDeviceInfo }),
processdata: false,
success: function (msg) {
alert(msg);
alert('Posted successfully');
},
error: function (msg) {
alert('Failed ' + msg.status);
}
});
I am in the process of testing some web services on my local machine. Because the test page sits on the root at port 80, and the web-services on different ports, I get the following error from Chrome's diagnostic tool:
XMLHttpRequest cannot load http://PCNAME:8083/PackageSearch. Origin http://PCNAME is not allowed by Access-Control-Allow-Origin.
After doing some searching, I came across the CORS Features of ServiceStack, and put the following attribute on my Web Service:
[EnableCors(allowedMethods: "GET, POST")]
However, the error still persists. This is the ajax call:
function packageSearch(tourCode) {
var searchUrl = url + 'PackageSearch';
var searchData = {
TourCode: tourCode,
};
$.ajax(searchUrl,{
data : JSON.stringify(searchData),
type: 'POST',
contentType: 'application/json, charset=utf-8',
dataType: 'json',
success: function (result) {
oTable.fnClearTable();
}});
};
Where url is http://PCNAME/.
EDIT
I have even set up the following during the Configuration stage:
public override void Configure(Funq.Container container)
{
Plugins.Add(new CorsFeature());
RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
if (httpReq.HttpMethod == "OPTIONS")
httpRes.End();
});
base.SetConfig(new EndpointHostConfig
{
DefaultContentType = "application/json",
GlobalResponseHeaders = {
{ "Access-Control-Allow-Origin", "*" },
{ "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
{ "Access-Control-Allow-Headers", "Content-Type, origin, accept" },
}
});
});
} // Configure
You need a ContentType specified and may have to do a preflight message (OPTIONS) to do the handshake that will allow you to proceed with a cross domain call.
I thought this code looks suspicious:
if (httpReq.HttpMethod == "OPTIONS")
httpRes.End();
I think although you are setting all header responses to send CORS headers, you may be short-circuiting the HTTP response headers - they never get sent. You could verify if you use Fiddler to check the exact http response headers sent back.
See this SO answer: ServiceStack returns 405 on OPTIONS request
They send the headers before calling httprequest.end().
You probably have to do:
httpRes.AddHeader("Access-Control-Allow-Origin", "*");
... before calling response.end()