Cors issues using sharepoint - asp.net

i'm trying to query using REST API (sharepoint) and get some results.
this is where i've started
https://www.slideshare.net/CoreyRoth/fives-ways-to-query-share-point-2013-search-sharepoint-summit-toronto-2013, slide 31
this is what i have
document.getElementById("restApi")
.addEventListener("click", restApi, false);
function restApi() {
var queryUrl = "https://myAppDomain.org/_api/search/query?querytext='" + $("#restSearch").val() + "'";
$.ajax({
type: "GET",
url: queryUrl,
xhrFields: {
withCredentials: true
},
headers: {
"Accept": "application/json; odata=verbose"
},
success: function (data) {
var results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
},
error: function (error) {
}
});
}
this is the problem.
XMLHttpRequest cannot load "https://myAppDomain.org/_api/search/query?querytext=x" No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:63734' is therefore not allowed
access.
and another way i've tried providing password and username
headers: {
"Accept": "application/json; odata=verbose",
"password": "my password",
"username": "my account name"
},
for which i get
XMLHttpRequest cannot load
https://myAppDomain.org/_api/search/query?querytext=x. Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:63734' is therefore not allowed
access. The response had HTTP status code 401.
I'm using .net webApi, for which i've installed the cors packages, configuration
// Enabled cors
config.EnableCors(new EnableCorsAttribute("*", "*", "*") { SupportsCredentials = true });
The app are internal and i'm using windows credentials pass and account name.
So why am i getting this error, what do i do wrong?, i've searched and tried other solutions but always get the same problem related to
No 'Access-Control-Allow-Origin' header is present on the requested

Open IIS
Go to Sites and find your Sharepoint site
Right-click -> Explore
Open web.config
Add the following code inside system.webServer node
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
Save and exit

I've managed to solve my issue (partially, because i would have wanted to use CSOM rather then REST API on client side) by allowing cross domain calls from my application, directly to the application(sharepoint app) for which i made the request.
So in the requested app i've added the following file :
web.config
in section :
system.webserver/httpprotocol/customheaders
content :
<add name="Access-Control-Allow-Origin" value="https://myApplicationDomain.zzz" />
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Credentials" value="true" />

If the server is being developed by you
Have you put the "Access-Control-Allow-Origin: localhost" in your .htaccess or in your webserver configuration?
You can, also, add that header in your response from the server.

Related

How to call wcf service using ajax

I'm trying to call a WCF service from ajax call. This is my ajax call:
$j.ajax(
{
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
context: this,
async: false,
url: appServicePath + "Student/GetRolesByUserId",
data: JSON.stringify({ "userId": userId }),
success: this.getRolesByIdResponse,
error: this.getRolesByIdFailure
}
);
when I test my service using Fiddler I'm able to get the roles of the user that I'm passing its value from ajax but when I call the service from my application I get an error: 405 Method Not Allowed.
What am I doing wrong?
According to your description, I think this problem is due to cross-domain, the problem generates an OPTIONS request, So the method is not allowed. If you put the script in the same domain as the webservice, you won't have this problem.
Here is Http 405 method document.
https://www.rfc-editor.org/rfc/rfc7231#section-6.5.5
You now need to turn on cross-domain support for a WCF application hosted on the web server side.
Web.config
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="content-type" />
<add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
</customHeaders>
</httpProtocol>
</system.webServer>
Global.asax
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (Request.Headers.AllKeys.Contains("Origin")&&Request.HttpMethod=="OPTIONS")
{
Response.End();
}
}
Feel free to contact me if you have any questions.

Why does call to web service (.asmx) fail when deployed to Azure [duplicate]

When consuming a WebService, I got the following error:
Request format is unrecognized for URL unexpectedly ending in /myMethodName
How can this be solved?
Found a solution on this website
All you need is to add the following to your web.config
<configuration>
<system.web>
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
</system.web>
</configuration>
More info from Microsoft
Despite 90% of all the information I found (while trying to find a solution to this error) telling me to add the HttpGet and HttpPost to the configuration, that did not work for me... and didn't make sense to me anyway.
My application is running on lots of servers (30+) and I've never had to add this configuration for any of them. Either the version of the application running under .NET 2.0 or .NET 4.0.
The solution for me was to re-register ASP.NET against IIS.
I used the following command line to achieve this...
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i
Make sure you're using right method: Post/Get, right content type and right parameters (data).
$.ajax({
type: "POST",
url: "/ajax.asmx/GetNews",
data: "{Lang:'tr'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) { generateNews(msg); }
})
Superb.
Case 2 - where the same issue can arrise) in my case the problem was due to the following line:
<webServices>
<protocols>
<remove name="Documentation"/>
</protocols>
</webServices>
It works well in server as calls are made directly to the webservice function - however will fail if you run the service directly from .Net in the debug environment and want to test running the function manually.
For the record I was getting this error when I moved an old app from one server to another. I added the <add name="HttpGet"/> <add name="HttpPost"/> elements to the web.config, which changed the error to:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at BitMeter2.DataBuffer.incrementCurrent(Int64 val)
at BitMeter2.DataBuffer.WindOn(Int64 count, Int64 amount)
at BitMeter2.DataHistory.windOnBuffer(DataBuffer buffer, Int64 totalAmount, Int32 increments)
at BitMeter2.DataHistory.NewData(Int64 downloadValue, Int64 uploadValue)
at BitMeter2.frmMain.tickProcessing(Boolean fromTimerEvent)
In order to fix this error I had to add the ScriptHandlerFactory lines to web.config:
<system.webServer>
<handlers>
<remove name="ScriptHandlerFactory" />
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</handlers>
</system.webServer>
Why it worked without these lines on one web server and not the other I don't know.
In my case the error happened when i move from my local PC Windows 10 to a dedicated server with Windows 2012.
The solution for was to add to the web.config the following lines
<webServices>
<protocols>
<add name="Documentation"/>
</protocols>
</webServices>
I use following line of code to fix this problem. Write the following code in web.config file
<configuration>
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="50000000"/>
</webServices>
</scripting>
</system.web.extensions>
</configuration>
I did not have the issue when developing in localhost. However, once I published to a web server, the webservice was returning an empty (blank) result and I was seeing the error in my logs.
I fixed it by setting my ajax contentType to :
"application/json; charset=utf-8"
and using :
JSON.stringify()
on the object I was posting.
var postData = {data: myData};
$.ajax({
type: "POST",
url: "../MyService.asmx/MyMethod",
data: JSON.stringify(postData),
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log(data);
},
dataType: "json"
});
I also got this error with apache mod-mono. It looks like the documentation page for webservice is not implemented yet in linux. But the webservice is working despite this error. You should see it by adding ?WSDL at the end of url, i.e http://localhost/WebService1.asmx?WSDL
In html you have to enclose the call in a a form with a GET with something like
label
You can also use a POST with the action being the location of the web service and input the parameter via an input tag.
There are also SOAP and proxy classes.
In my case i had an overload of function that was causing this Exception, once i changed the name of my second function it ran ok, guess web server doesnot support function overloading
a WebMethod which requires a ContextKey,
[WebMethod]
public string[] GetValues(string prefixText, int count, string contextKey)
when this key is not set, got the exception.
Fixing it by assigning AutoCompleteExtender's key.
ac.ContextKey = "myKey";
In our case the problem was caused by the web service being called using the OPTIONS request method (instead of GET or POST).
We still don't know why the problem suddenly appeared. The web service had been running for 5 years perfectly well over both HTTP and HTTPS. We are the only ones that consume the web service and it is always using POST.
Recently we decided to make the site that host the web service SSL only. We added rewrite rules to the Web.config to convert anything HTTP into HTTPS, deployed, and immediately started getting, on top of the regular GET and POST requests, OPTIONS requests. The OPTIONS requests caused the error discussed on this post.
The rest of the application worked perfectly well. But we kept getting hundreds of error reports due to this problem.
There are several posts (e.g. this one) discussing how to handle the OPTIONS method. We went for handling the OPTIONS request directly in the Global.asax. This made the problem dissapear.
protected void Application_BeginRequest(object sender, EventArgs e)
{
var req = HttpContext.Current.Request;
var resp = HttpContext.Current.Response;
if (req.HttpMethod == "OPTIONS")
{
//These headers are handling the "pre-flight" OPTIONS call sent by the browser
resp.AddHeader("Access-Control-Allow-Methods", "GET, POST");
resp.AddHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, SOAPAction");
resp.AddHeader("Access-Control-Max-Age", "1728000");
resp.End();
}
}
I was getting this error until I added (as shown in the code below) $.holdReady(true) at the beginning of my web service call and $.holdReady(false) after it ends. This is jQuery thing to suspend the ready state of the page so any script within document.ready function would be waiting for this (among other possible but unknown to me things).
<span class="AjaxPlaceHolder"></span>
<script type="text/javascript">
$.holdReady(true);
function GetHTML(source, section){
var divToBeWorkedOn = ".AjaxPlaceHolder";
var webMethod = "../MyService.asmx/MyMethod";
var parameters = "{'source':'" + source + "','section':'" + section + "'}";
$.ajax({
type: "POST",
url: webMethod,
data: parameters,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
xhrFields: {
withCredentials: false
},
crossDomain: true,
success: function(data) {
$.holdReady(false);
var myData = data.d;
if (myData != null) {
$(divToBeWorkedOn).prepend(myData.html);
}
},
error: function(e){
$.holdReady(false);
$(divToBeWorkedOn).html("Unavailable");
}
});
}
GetHTML("external", "Staff Directory");
</script>
Make sure you disable custom errors. This can mask the original problem in your code:
change
<customErrors defaultRedirect="~/Error" mode="On">
to
<customErrors defaultRedirect="~/Error" mode="Off">

Acces-Control-Allow-Origin works with Web.config (IIS7) but not with (WebApiConfig.cs) ASP.NET Cross Origin support

For a project i want to load and view a pdf file with angular-pdfjs. The team uses ASP.net Cross Origin, to Allow-Acces-Control, Headers, Credentials etc.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Replace the default implementation of the ITraceWriter with our custom logger.
config.Services.Replace(typeof (ITraceWriter), new GlobalTraceLogger());
// Replace the default exception logger to be able to log exceptions with NLog
config.Services.Replace(typeof (IExceptionLogger), new GlobalExceptionLogger());
// Replace the default exceptionhandler to be able to handle exceptions globally
config.Services.Replace(typeof (IExceptionHandler), new GlobalExceptionHandler());
// We must enable cors, because otherwise we are not able to commuincate with a java script client
// TODO: We need to restirct the requested resource. Do not allow every origin!
// Do not run this in prodocutive environment
var cors = new EnableCorsAttribute("*", "*", "*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
config.MapHttpAttributeRoutes();
// Make the default return type JSON
var appXmlType =
config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
This works good so far, but if i want to load my pdf file with angular-pdfjs, i get a Cross Origin Error, because Allow-Acces-Control-Origin "*" didn't works for my pdf-url.
(https://img3.picload.org/image/roirrgcw/corsworksnot.png)
But if i using instead of ASP.net Cross Origin Support the Allow-Access-Control of IIS7 in Web.config:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested- With, Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</httpProtocol>
it works and the pdf will be loaded correctly.
(https://picload.org/image/roirrgci/corsworks.jpg)
But the problem is, at the moment the page is loaded via "file://" and so i get
an error because there is no Access-Control-Allow-Origin for 'null'. That means, my pdf is loading correctly this way, but the login, pictures... won't be loaded anymore. So my question is, if someone knows how i can change the WebApiConfig-Implementation that my pdf-file get an Access-Controll-Allow as well. Or maybe can someone tell where the error could be.
For information:
Thats the way i'm loading the pdf with angular-pdfjs:
<!---------------------------THE PDF VIEWER DIRECTIVE------------------------->
<div pdf-viewer="options" pdf-url="pdfUrl" id="my-viewer" class="col col-lg-10"></div>
<!---------------------------THE PDF VIEWER DIRECTIVE------------------------->
and thats the url, i'm using:
function PdfviewController(ebmGuideLineService, mediaService, $scope, $window) {
var vm = this;
$scope.pdfUrl = 'http://localhost:3787/NCCN_Evidence_Blocks_Melanoma.pdf';
$scope.options = { mouseZoom: false, mousePan: false };
Please tell me, if you need more informations and thank you for your help.

Server application has enabled CORS yet client gets "Access-Control-Allow-Origin" error

I have an RESTful API and I've added this to allow Cross-origin request
public static void Register(HttpConfiguration config)
{
...
// Allow Cross-origin request
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors();
...
}
My client is an AngularJS application calling the server like this
var json = JSON.stringify({
Request: 'INIT'
}),
req = {
method: 'GET',
url: 'http://localhost:51615/api/Call/2/' + json
}
$http(req)
.then(function(response){
console.info('response', response)
})
.catch(function(error){
console.error(error);
})
Even thou Cross-origin should be allowed I still get this error
XMLHttpRequest cannot load
http://localhost:51615/api/Call/2/%7B%22Request%22:%22INIT%22%7D. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:86' is therefore not allowed
access. The response had HTTP status code 400.
How can this be?
Big thanks to #shaunhusain for pointing out that I should take a look at the network response in chrome. Here I saw that the problem was with unsafe data in my url string (the json part). Changing the request from get to post along with json as data and not part of the url fixed my problem
try with putting this two appsettings in web.config of your web api project
<configuration>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<appSettings>
</configuration>

Request format is unrecognized for URL unexpectedly ending in

When consuming a WebService, I got the following error:
Request format is unrecognized for URL unexpectedly ending in /myMethodName
How can this be solved?
Found a solution on this website
All you need is to add the following to your web.config
<configuration>
<system.web>
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
</system.web>
</configuration>
More info from Microsoft
Despite 90% of all the information I found (while trying to find a solution to this error) telling me to add the HttpGet and HttpPost to the configuration, that did not work for me... and didn't make sense to me anyway.
My application is running on lots of servers (30+) and I've never had to add this configuration for any of them. Either the version of the application running under .NET 2.0 or .NET 4.0.
The solution for me was to re-register ASP.NET against IIS.
I used the following command line to achieve this...
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i
Make sure you're using right method: Post/Get, right content type and right parameters (data).
$.ajax({
type: "POST",
url: "/ajax.asmx/GetNews",
data: "{Lang:'tr'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) { generateNews(msg); }
})
Superb.
Case 2 - where the same issue can arrise) in my case the problem was due to the following line:
<webServices>
<protocols>
<remove name="Documentation"/>
</protocols>
</webServices>
It works well in server as calls are made directly to the webservice function - however will fail if you run the service directly from .Net in the debug environment and want to test running the function manually.
For the record I was getting this error when I moved an old app from one server to another. I added the <add name="HttpGet"/> <add name="HttpPost"/> elements to the web.config, which changed the error to:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at BitMeter2.DataBuffer.incrementCurrent(Int64 val)
at BitMeter2.DataBuffer.WindOn(Int64 count, Int64 amount)
at BitMeter2.DataHistory.windOnBuffer(DataBuffer buffer, Int64 totalAmount, Int32 increments)
at BitMeter2.DataHistory.NewData(Int64 downloadValue, Int64 uploadValue)
at BitMeter2.frmMain.tickProcessing(Boolean fromTimerEvent)
In order to fix this error I had to add the ScriptHandlerFactory lines to web.config:
<system.webServer>
<handlers>
<remove name="ScriptHandlerFactory" />
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</handlers>
</system.webServer>
Why it worked without these lines on one web server and not the other I don't know.
In my case the error happened when i move from my local PC Windows 10 to a dedicated server with Windows 2012.
The solution for was to add to the web.config the following lines
<webServices>
<protocols>
<add name="Documentation"/>
</protocols>
</webServices>
I use following line of code to fix this problem. Write the following code in web.config file
<configuration>
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="50000000"/>
</webServices>
</scripting>
</system.web.extensions>
</configuration>
I did not have the issue when developing in localhost. However, once I published to a web server, the webservice was returning an empty (blank) result and I was seeing the error in my logs.
I fixed it by setting my ajax contentType to :
"application/json; charset=utf-8"
and using :
JSON.stringify()
on the object I was posting.
var postData = {data: myData};
$.ajax({
type: "POST",
url: "../MyService.asmx/MyMethod",
data: JSON.stringify(postData),
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log(data);
},
dataType: "json"
});
I also got this error with apache mod-mono. It looks like the documentation page for webservice is not implemented yet in linux. But the webservice is working despite this error. You should see it by adding ?WSDL at the end of url, i.e http://localhost/WebService1.asmx?WSDL
In html you have to enclose the call in a a form with a GET with something like
label
You can also use a POST with the action being the location of the web service and input the parameter via an input tag.
There are also SOAP and proxy classes.
In my case i had an overload of function that was causing this Exception, once i changed the name of my second function it ran ok, guess web server doesnot support function overloading
a WebMethod which requires a ContextKey,
[WebMethod]
public string[] GetValues(string prefixText, int count, string contextKey)
when this key is not set, got the exception.
Fixing it by assigning AutoCompleteExtender's key.
ac.ContextKey = "myKey";
In our case the problem was caused by the web service being called using the OPTIONS request method (instead of GET or POST).
We still don't know why the problem suddenly appeared. The web service had been running for 5 years perfectly well over both HTTP and HTTPS. We are the only ones that consume the web service and it is always using POST.
Recently we decided to make the site that host the web service SSL only. We added rewrite rules to the Web.config to convert anything HTTP into HTTPS, deployed, and immediately started getting, on top of the regular GET and POST requests, OPTIONS requests. The OPTIONS requests caused the error discussed on this post.
The rest of the application worked perfectly well. But we kept getting hundreds of error reports due to this problem.
There are several posts (e.g. this one) discussing how to handle the OPTIONS method. We went for handling the OPTIONS request directly in the Global.asax. This made the problem dissapear.
protected void Application_BeginRequest(object sender, EventArgs e)
{
var req = HttpContext.Current.Request;
var resp = HttpContext.Current.Response;
if (req.HttpMethod == "OPTIONS")
{
//These headers are handling the "pre-flight" OPTIONS call sent by the browser
resp.AddHeader("Access-Control-Allow-Methods", "GET, POST");
resp.AddHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, SOAPAction");
resp.AddHeader("Access-Control-Max-Age", "1728000");
resp.End();
}
}
I was getting this error until I added (as shown in the code below) $.holdReady(true) at the beginning of my web service call and $.holdReady(false) after it ends. This is jQuery thing to suspend the ready state of the page so any script within document.ready function would be waiting for this (among other possible but unknown to me things).
<span class="AjaxPlaceHolder"></span>
<script type="text/javascript">
$.holdReady(true);
function GetHTML(source, section){
var divToBeWorkedOn = ".AjaxPlaceHolder";
var webMethod = "../MyService.asmx/MyMethod";
var parameters = "{'source':'" + source + "','section':'" + section + "'}";
$.ajax({
type: "POST",
url: webMethod,
data: parameters,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
xhrFields: {
withCredentials: false
},
crossDomain: true,
success: function(data) {
$.holdReady(false);
var myData = data.d;
if (myData != null) {
$(divToBeWorkedOn).prepend(myData.html);
}
},
error: function(e){
$.holdReady(false);
$(divToBeWorkedOn).html("Unavailable");
}
});
}
GetHTML("external", "Staff Directory");
</script>
Make sure you disable custom errors. This can mask the original problem in your code:
change
<customErrors defaultRedirect="~/Error" mode="On">
to
<customErrors defaultRedirect="~/Error" mode="Off">

Resources