I recently implemented cors into my Web API controller. I am calling the web api located on domain1 from a client on domain2.
For the origin, I specified a bogus url. To my understanding, only calls from this url will be accepted. Is this correct?
So only calls from
http://notgoingtowork.com
will be able to call the controller and return data
Here is my controller (domain1)
public class TestController : ApiController
{
[EnableCors(origins: "http://notgoingtowork.com", headers: "*", methods: "*")]
public int Get()
{
return 1
}
}
And then on my other domain, the ajax call (domain2)
$.ajax({
url: "http://domain1/api/Test/Get",
method: "GET",
headers: { "accept": "application/json;odata=verbose" },
success: function (data){alert("it worked");},
error: function (error) { alert("Did not work"); }
})
However, the request still is successful and is returning data. As the client is not on 'http://notgoingtowork.com', how is it able to successfully do this? What am I missing?
I am doing this on IE11. This works fine on chrome.
EDIT:
Here is the WebApiConfig.cs file
It is pretty generic. I just added the Cors part
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableCors();
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
there is a setting "Access data sources across domains" in IE 11, make sure if it is disabled:
Related
I have a working ASP.NET core web application that utilizes javascript to call a controller method. However, the controller method is currently not protected from cross-site request forgery.
My current controller method is as follows:
[HttpPost]
[IgnoreAntiforgeryToken]
public async Task CallMe(string destination, string callIndex, string fromNumber)
{
var userLogin = HttpContext.Session.Get<UserLogin>("userLogin");
if (userLogin != null)
{
var tokenModel = await GetSessionToken();
...
}
}
The corresponding javascript in my CSHTML page is as follows:
...
$.post("#Url.Action("CallMe")", { destination: destination, callIndex: callIndex, fromNumber: fromNumber });
After adding the antiforgery token to the page as recommended by the Microsoft article here.
My controller is the same except for the [IgnoreAntiforgeryToken] attribute:
[HttpPost]
public async Task CallMe(string destination, string callIndex, string fromNumber)
{
var userLogin = HttpContext.Session.Get<UserLogin>("userLogin");
if (userLogin != null)
{
var tokenModel = await GetSessionToken();
...
}
}
My updated javascript call is as follows:
var data = { destination: destination, callIndex: callIndex, fromNumber: fromNumber };
fetch("#Url.Action("CallMe")", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type' : 'application/json',
'RequestVerificationToken':
document.getElementById("RequestVerificationToken").value
},
body: JSON.stringify(data),
});
The javascript calls the method as expected; however, all parameters are null. In Fiddler, I've able to verify the header values are correct and the body is as follows:
{ "destination": "xxx", "callIndex": "xxx_idx", "fromNumber": "xxxx" }
What else needs to be added to pass the values correctly?
I'm sure this question has been posted many times before, and I have looked through all related threads. But it's still not working.
We have the JavaScript part:
$.ajax({
type: "GET",
url: "https://localhost:44346/api/persons/",
//dataType: "JSON",
success: function (response) {
callback("a");
},
error: function (response) {
callback("b");
}
}
);
And the C# part:
[Route("persons")]
[HttpGet]
public ActionResult GetPersons()
{
return new JsonResult(new { Success = true, Result = "abc" },
System.Web.Mvc.JsonRequestBehavior.AllowGet);
}
Problem is the Jquery always has error with result = "b". Breakpoints in the Api are hit. I tried with and without dataType: "JSON". Sending parameters to the Api also works, but getting the result back doesnt work. All projects are .Net 5.0.
Replace
url: "https://localhost:44346/api/persons/",
with
url: "https://localhost:44346/api/persons",
and remove [HttpGet] from your action.
[Route("~/api/persons")]
public ActionResult GetPersons()
{
return new JsonResult(new { Success = true, Result = "abc" });
}
But you will stll get error response if APIs CORS is not properly configured.
APIs (not client) startup should be like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("AllowAnyOrigins", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
services.AddControllers()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseCors("AllowAnyOrigins");
//app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
I make a call to an ASP.Net Web API which returns 404 Not found. The controller is recognized but the action is not found.
I have tried using attribute routing and [HttpGet] for the action. I've also tried using standard API routing in the WebAPI config file. I've even tried combining the two.
//[HttpGet]
//[Route("api/User")]
protected IHttpActionResult GetEmployeeHierarchyList()
{
// ...
return Json(results);
}
config.Routes.MapHttpRoute(
name: "GetEmployeeHierarchyListTwo",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = "GetEmployeeHierarchyList", }
);
return fetch("/api/User/" + api, {
method: "GET",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'credentials': 'include'
}
}).then(response => {
return response.json();
})
I expect the action to return a string to be handled by the fetch call.
Make your GetEmployeeHierarchyList() method int the controller public.
This should workfine:
[HttpGet]
[Route("api/User")]
public IHttpActionResult GetEmployeeHierarchyList()
{
// ...
return Json(results);
}
So I have a funny little problem.
When calling my API from an AngularJS client with the following code, everything works fine, except that my API only recieves an empty object as data:
var req = {
method: 'Post',
url: config.API + request.toLowerCase() + '/',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: data
}
$http(req)
.then(function(response){
// handling response
})
Now, if I remove the headers: { 'Content-Type': 'application/x-www-form-urlencoded' } or changes it to headers: { 'Content-Type': 'application/json' } I get the this error:
The requested resource does not support http method 'OPTIONS'
My API controller looks like this:
[EnableCors("*", "*", "*")]
[HttpPost]
public string Post([FromBody]dynamic value)
{
// Do some stuff
Response response = new Response();
return JsonConvert.SerializeObject(response);
}
What I'm looking for is a way to prevent the tiresome "OPTIONS not supported" error, and still be able to send dynamic data to my controller
EDIT
Regarding the duplicate, I've already tried their approach, hence why I already are using [EnableCors] in my controller. But if I add this:
public static void Register(HttpConfiguration config)
{
config.EnableCors();
}
I get this error instead
Response to preflight request doesn't pass access control check: The
'Access-Control-Allow-Origin' header contains multiple values '*, *',
but only one is allowed. Origin 'http://localhost:82' is therefore not
allowed access
I know the question has been asked many time but i still didn't find the solution.
Am having a cross domain error when i tried to communicate with my API from the client. I don't know if
there's something am missing here.
XMLHttpRequest cannot load http://localhost:28184/Customer/AddCustomer.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin http://localhost:28189 is therefore not allowed
access. The response had HTTP status code 404.
Ajax call:
function AddCompany()
{
var companyModel = {
----------
}
$.support.cors = true;
$.ajax({
url: BaseUrl + "Customer/AddCustomer",
type: "POST",
withCredentials: false,
dataType: "Jason",
cach: false,
async: true,
crossDomain: true,
data: companyModel,
success: function(data){
alert("Company has been successfully registered");
}
});
}
API controller:
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Cors;
using Fleet_API.Models;
namespace Fleet_API.Controllers
{
[EnableCors(origins: "*", headers: "*", methods: "*")]
[RoutePrefix("Api/Customer")]
public class CustomerController : ApiController
{
[Route("AddCustomer")]
[HttpPost]
public async Task<bool>AddCompany(CustomerModel model)
{
------------------------
}
}
}
Hosts file from windows
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost