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);
}
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 am trying to send some form data to a spring application using Fetch API in javascript.
I have this code to send the form data:
document.querySelector('#formPet').addEventListener('submit', event => {
event.preventDefault();
let email= document.querySelector("#email");
fetch('http://localhost:8080/petForm/'+email.value+'/pets', {
method: 'POST',
body: JSON.stringify({
help: "helpme:("
})
})
});
but i get a 415 status error "Unsupported Media Type". Even when i set specifically the header 'Content-Type' to 'application/json' it sends like 'text/plain'
fetch('http://localhost:8080/petForm/'+email.value+'/pets', {
method: 'POST',
header: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
help: "helpme:("
})
})
});
this is the response that i get from the server:
Here is the method that accept the request in Spring:
#PostMapping("petForm/{id}/pets")
public ResponseEntity<Pet> createPet(#PathVariable("id") String ownerId, #RequestBody Map<String, Object> data){
System.out.println(data);
return ResponseEntity.ok().build();
}
i don´t know why the request is send in 'text/plain' format, i try the Spring method in postman and work´s fine when i send the data in json format.
In your JavaScript code you need to use „headers“ instead of „header“. See the fetch API documentation: https://developer.mozilla.org/en-US/docs/Web/API/fetch
step 1 : add #CrossOrigin after #PostMapping(value = "petForm/{id}/pets")
like :
#PostMapping(value = "petForm/{id}/pets")
#CrossOrigin
public ResponseEntity<String> createPet(#PathVariable("id") String ownerId, #RequestBody Map<String, Object> data){
System.out.println(data);
return ResponseEntity.ok().build();
}
step 2 : add double quotes to help word
it is not json fromat :====> help: "helpme"
Correct :
it is not json fromat :====> "help": "helpme"
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();
});
}
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 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: