Ajax CORS call not working for application/json - ajax

My following code is working fine and I am able to call API
$.ajax({
url: "http://localhost:57786/mvc/create",
method: "POST",
data: { FirstName: "ABC", LastName: "XYZ" },
success: function (data) {
alert("Success");
},
error: function (statusText, error) {
alert("Error");
}
});
But following code is not working and I am not able to call API
$.ajax({
url: "http://localhost:57786/mvc/create",
method: "POST",
data: JSON.stringify({ FirstName: "ABC", LastName: "XYZ" }),
contentType: "application/json; charset=utf-8",
success: function (data) {
alert("Success");
},
error: function (statusText, error) {
alert("Error");
}
});
Here is API code
[EnableCors("*","*","*")]
public class MVCController : Controller
{
// POST: MVC/Create
[HttpPost]
public ActionResult Create(MyData value)
{
//My Code
}
}
I am getting response The response had HTTP status code 404.
Why Ajax call is failing when I use contentType to application/json?

Had similar issues and i fixed it by adding some configurations in the system.webserver in web.config or you can write it as a custom filter attribute and then register it in filterconfig.cs in App_start folder.
<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>
<--this is for the web,config-->
or for the filterconfig.cs you can write a custom filter and override the ActionFilterAttribute but note that the challenge with this is that any action such as /token to generate an authorization token might fail because it does not satisfy the onActionExecuting method, so maybe you might want to go with the web.config
public class CustomHeaderAttributeFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//add in your custom headers
filterContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
filterContext.HttpContext.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type");
filterContext.HttpContext.Response.AddHeader("Access-Control-Allow-Methods", "GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS");
base.OnActionExecuting(filterContext);
}
public void OnException(ExceptionContext filterContext)
{
//do some cool exception handling here
}
}
}

Related

Getting 405 Error Method Not Allowed on my AJAX POST call to my Web API

I'm trying to call my Web API Function from an AJAX POST call but keep getting a 405 Error. I've been looking but only been finding solutions saying to Enable CORS, which I've done, but to no avail. For now, I'm just trying to display the data in html. The user enters in an Order Number and that fills in the parameter for the Web API Function. Can anyone tell me what's going wrong?
My Web API Function:
<Route("{ordNbr}/contents")>
<HttpGet>
Public Function GetOrderContents(ByVal ordNbr As String) As SPFolderOver
Dim retValue As ReturnVal
retValue = GetOrderInformation(ordNbr)
Dim sp = New Sharepoint()
Dim t = sp.GetOrderContent(retValue.Year, retValue.SONumber)
Dim contentFolder = New SPFolderOver()
contentFolder = SPFolderOver.LoadFolder(t)
contentFolder.FolderName = t.FullPath
Return contentFolder
End Function
My AJAX call:
function GetOrder() {
var order = document.getElementById("orderNbr").value;
$.ajax({
cache: false,
type: "POST",
url: "http://localhost:54754/orders/{ordNbr}/contents",
data: { 'ordNbr': order },
success: function (data) {
$("#orderContents").html(data);
}
});
};
In my global.asax
Protected Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*")
If (HttpContext.Current.Request.HttpMethod = "OPTIONS") Then
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache")
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept")
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000")
HttpContext.Current.Response.End()
End If
End Sub
In my Web.config
<httpProtocol>
<customHeaders>
<remove name="Access-Control-Allow-Origin" />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Olaround-Debug-Mode, Authorization, Accept" />
<remove name="Access-Control-Allow-Headers" />
<add name="Access-Control-Expose-Headers" value="X-Olaround-Debug-Mode, X-Olaround-Request-Start-Timestamp, X-Olaround-Request-End-Timestamp, X-Olaround-Request-Time, X-Olaround-Request-Method, X-Olaround-Request-Result, X-Olaround-Request-Endpoint" />
</customHeaders>
</httpProtocol>
Glad you where able to debug using the Network tab. As a note, I recommend naming the JSON response response to make the distinction with the input data.
function GetOrder() {
var order = document.getElementById("orderNbr").value;
$.ajax({
type: "GET",
data: { 'ordNbr': order },
url: "http://localhost:54754/orders/{ordNbr}/contents)",
cache: false,
success: function (response) {
$("#orderContents").html(response);
},
error: function (err) {
alert("Error: " + err.errorText);
}
});
}

How to enable cors in .Net Core for web api ajax call

Am trying pull data from .net core web api using ajax call am getting the below error
Failed to load http://localhost:8085/api/menu: Response for preflight has invalid HTTP status code 404.
but am getting data sucessfully from postman.
am trying below code for ajax
$(document).ready(function(){
$.ajax({
url: 'http:/localhost:8085/api/menu',
type: 'GET',
dataType: 'json',
data: '{ }',
success: function (data) {
console.log(data);
},
failure: function (data) {
alert(data.responseText);
}, //End of AJAX failure function
error: function (data) {
alert(data.responseText);
}
});
});
I have added below tag in web.config file
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
Please suggest your thoughts.
Thanx in advance.
you can define your policy in Startup file as a part of ConfigureServices method
for example:
{
services.AddCors(c => {
c.AddPolicy("policyName", p => {
p.AllowAnyOrigin().AllowAnyMethod();
});
});
}
and then in Configure method
app.UseCors("policyName");

Handle Errors for Http and Ajax requests using HandleError Attribute Class

I am handling all the errors in controllers using the HandleError Attribute which i have modified for for http and ajax requests, and handling them as a 500 error type.
public class HandleExceptionsAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled)
return;
else
{
ErrorLogger.LogException(filterContext);
if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult
{
Data = new
{
success = false,
message = "error",
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
base.OnException(filterContext);
}
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
}
}
}
and using it on each controller as:
[HandleExceptions]
public class InvoiceController : Controller
{}
I have also mode on the customErrors in web.config as:
<customErrors mode="On" >
<error statusCode="400" redirect="Home/Error400" />
<error statusCode="401" redirect="Home/Error401" />
<error statusCode="403" redirect="Home/Error403" />
<error statusCode="500" redirect="/Home/Error" />
</customErrors>
and the httpErrors as:
<httpErrors errorMode="Custom" existingResponse="Replace">
<!--<remove statusCode="404" subStatusCode="-1" />-->
<error statusCode="404" path="/Home/Error404" responseMode="ExecuteURL"/>
<!--<remove statusCode="500" subStatusCode="-1" />-->
<error statusCode="500" path="/Home/Error" responseMode="ExecuteURL"/>
</httpErrors>
The problem with me is that when I just uncomment the remove tag for status code then it's work fine with httpErrors but not with ajax request because instead of returning the status code it returns the Home/Error page.
But if i comment this tag then httpErrors not return error page in most cases but work fine for ajax request which i can get in statusCode.
$.ajax({
url: "#Url.Action("SomeAction", "SomeController")",
type: "POST",
async: true,
cache: false,
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
if (response.success) {
catchSuccess("Success", response.responseText);
}
else {
catchWarning("Error", response.responseText);
}
},
Error: function (ex) {
catchError("Unkown Error", "Contact the Administrator");
},
statusCode: {
500: function () {
catchError("Error 500", "Internal Server Error. Contact the Administrator");
},
403: function () {
catchError("Error 403", "Internal Server Error. Contact the Administrator");
},
404: function (response) {
catchError("Error 404", "Internal Server Error. Contact the Administrator");
}
}
});
What should I do to catch both side errors?
Ajax request errors: I want to return the status code
Http request errors: I want to return the page from an action. (Home/Error).
As it is working I am posting solution as answer.
For above issue instead of checking statuscode check error in Jquery AJAX.
Sysntax for the same is
error:Function( jqXHR jqXHR, String textStatus, String errorThrown ).
Try to log output to console or alert to check desired result to handle.
And if you want to handle specific response then throw specific error not generic one.

ASP.NET web API HTTP Delete 405 Method Not Allowed

I already worked with web API and had a lot of problems like posting multiple parameters. I upgraded to WebApi2 to use routing attributes and now have problems like:
"message":"The requested resource does not support http method 'DELETE'."
I spent all day searching Stack Overflow and the web to solve the problem:
Removed webdav
In http protocol allow all get,put,post,delete
Added the [HTTPDelete] attribute
Added name="ExtensionlessUrlHandler-Integrated-4.0" path="*."
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0"
Searched Google for the necessary help here
Can someone please guide me on this?
I had the same problem. Adding the below code to your web.config should fix the problem under the system.webserver section:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/>
I had the same problem, because my controller was like this:
[HttpDelete]
public HttpResponseMessage Delete(string Id)
{
....
}
And on the client I used the send the ID as request body:
var url = '/api/upload';
var data = JSON.stringify({ 'Id': id }); // <-- In the body
$.ajax({
url: url,
type: 'DELETE',
data: data, // <-- in the body
contentType: 'application/json'
})
When I changed the client to use it as URL parameter instead it worked:
var url = '/api/upload/' + id; // <- In the URL
$.ajax({
url: url,
type: 'DELETE',
contentType: 'application/json'
});
The JavaScript code for the DELETE verb must be like this:
$.ajax({
**url: "/api/SomeController/" + id,**
type: "DELETE",
dataType: "json",
success: function(data, statusText) {
alert(data);
},
error: function(request, textStatus, error) {
alert(error);
debugger;
}
});
Do NOT use something like this,
...
data: {id:id}
...
as when you are using the POST method.

allow custom header in web api

I need to allow a custom header called "secretToken". And every call to my webapi, the user should pass this header.
I searched for a way to do that, but I could not found an easy way. How can I allow this custom header?
There's one more thing in .config file:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept,auth-key" />
</customHeaders>
</httpProtocol>
You mentioned 'allow' means passing from client? Which client?
If JavaScript, you can do something like this.
$.ajax({
type: 'GET',
url: '/api/values',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
headers: { 'X-My-Secret-Token': 'Token' },
success: function (data) {
}
});
If .NET client, you can do something like this.
string url = "http://www.myurl/api/values";
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-My-Secret-Token", "Token");
var message = client.GetAsync(url).Result;
In Web API, you can read the header in HttpRequestMessage object from any component in the pipeline. For example, you can read the header from a handler like this.
public class MyHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
var headers = request.Headers;
if (headers.Contains("X-My-Secret-Token"))
{
string token = headers.GetValues("X-My-Secret-Token").First();
}
}
}

Resources