I'm trying to post some data using the fetch() api and I keep receiving a "400 - Bad Request" error.
I don't have any problem using the jQuery's $.ajax() method and I'm wondering what am I doing wrong:
data
let obj = {
id_user: 57,
id_category: 60,
note: 'test'
}
Using jQuery (working)
$.ajax({
url: 'http://localhost:3001/api/devices',
type: 'post',
data: obj
}).fail(function( xhr, status, errorThrown ) {
alert( "Sorry, there was a problem!" );
console.log( "Error: " + errorThrown );
console.log( "Status: " + status );
console.dir( xhr );
})
Using fetch() (not working)
fetch('http://localhost:3001/api/devices', {
method: 'post',
body: JSON.stringify(obj)
}).then(function(response){
console.log(response)
}).catch(function(error) {
console.log(error)
})
Response
Response {type: "basic", url: "http://localhost:3001/api/devices", redirected: false, status: 400, ok: falseā¦}
Am I missing something?
Here is how to use the fetch API:
namespace WebApi.Controllers
{
public class obj
{
public int id_user { get; set; }
public int id_category { get; set; }
public string note { get; set; }
}
public class devicesController : ApiController
{
public string Post([FromBody]obj value)
{
//use newtonsoft json
string json = JsonConvert.SerializeObject(value);
return json;
}
}
}
View:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index2</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("#callAjax").click(function () {
let obj = {
id_user: 57,
id_category: 60,
note: 'test'
}
//this worked for me, FYI, I USE different port than you
//$.ajax({
// url: 'http://localhost:53110/api/devices',
// type: 'post',
// data: obj
//}).done(function (data, textStatus, jqXHR) {
// alert(data);
//}).fail(function (xhr, status, errorThrown) {
// alert("Sorry, there was a problem!");
// console.log("Error: " + errorThrown);
// console.log("Status: " + status);
// console.dir(xhr);
//})
//https://davidwalsh.name/fetch - does not work in ie11
//https://stackoverflow.com/questions/11492325/post-json-fails-with-415-unsupported-media-type-spring-3-mvc
fetch('http://localhost:53110/api/devices', {
//I HAD TO add this headers because 415 unsupported media type
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: 'post',
body: JSON.stringify(obj)
}).then(function (response) {
//alert(response)
//ADDED THIS https://developers.google.com/web/updates/2015/03/introduction-to-fetch
response.json().then(function (data) {
alert(data);
});
}).catch(function (error) {
alert(error)
})
})
})
</script>
</head>
<body>
<div>
<input type="button" value="callAjax" id="callAjax" />
</div>
</body>
</html>
Related
Trying to be more consistent with HTTP verbs, I'm trying to call a delete Handler on a Razor Page via AJAX;
Here's my AJAX code, followed by the C# code on my page :
return new Promise(function (resolve: any, reject: any) {
let ajaxConfig: JQuery.UrlAjaxSettings =
{
type: "DELETE",
url: url,
data: JSON.stringify(myData),
dataType: "json",
contentType: "application/json",
success: function (data) { resolve(data); },
error: function (data) { reject(data); }
};
$.ajax(ajaxConfig);
});
my handler on my cshtml page :
public IActionResult OnDeleteSupprimerEntite(int idEntite, string infoCmpl)
{
// my code
}
which never reaches ... getting a bad request instead !
When I switch to a 'GET' - both the type of the ajax request and the name of my handler function ( OnGetSupprimerEntite ) - it does work like a charm.
Any ideas ? Thanks !
Short answer: The 400 bad request indicates the request doesn't fulfill the server side's needs.
Firstly, your server is expecting a form by;
public IActionResult OnDeleteSupprimerEntite(int idEntite, string infoCmpl)
{
// my code
}
However, you're sending the payload in application/json format.
Secondly, when you sending a form data, don't forget to add a csrf token:
#inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
<script>
function deleteSupprimerEntite(myData){
var url = "Index?handler=SupprimerEntite";
return new Promise(function (resolve, reject) {
let ajaxConfig = {
type: "DELETE",
url: url,
data: myData ,
success: function (data) { resolve(data); },
error: function (data) { reject(data); }
};
$.ajax(ajaxConfig);
})
}
document.querySelector("#testbtn").addEventListener("click",function(e){
var myData ={
idEntite:1,
infoCmpl:"abc",
__RequestVerificationToken: "#(Xsrf.GetAndStoreTokens(HttpContext).RequestToken)",
};
deleteSupprimerEntite(myData);
});
</script>
A Working Demo:
Finally, in case you want to send in json format, you could change the server side Handler to:
public class MyModel {
public int idEntite {get;set;}
public string infoCmpl{get;set;}
}
public IActionResult OnDeleteSupprimerEntite([FromBody]MyModel xmodel)
{
return new JsonResult(xmodel);
}
And the js code should be :
function deleteSupprimerEntiteInJson(myData){
var url = "Index?handler=SupprimerEntite";
return new Promise(function (resolve, reject) {
let ajaxConfig = {
type: "DELETE",
url: url,
data: JSON.stringify(myData) ,
contentType:"application/json",
headers:{
"RequestVerificationToken": "#(Xsrf.GetAndStoreTokens(HttpContext).RequestToken)",
},
success: function (data) { resolve(data); },
error: function (data) { reject(data); }
};
$.ajax(ajaxConfig);
})
}
document.querySelector("#testbtn").addEventListener("click",function(e){
var myData ={
idEntite:1,
infoCmpl:"abc",
};
deleteSupprimerEntiteInJson(myData);
});
We are trying to make a Ajax request to our Core Web API and get the data Json result back to the Controller for further processing, Which include Deserialization of the Json object result, Ajax request is working fine and we are able to get the required Json data in data.
Can anyone here please advise the changes or the alternatives to achieve this?
View (Ajax Request)
#section scripts
{
<script type="text/javascript">
$(document).ready(function () {
GetEventDetails('#Url.Content("~/")');
});
function GetEventDetails(contextRoot) {
$.ajax({
type: "GET",
url: contextRoot + "api/EventsAPI",
dataType: "json",
success: function (data) {
debugger;
var datavalue = data;
contentType: "application/json";
//Send data to controller ???
console.log(data);
},
error: function (xhr) {
alert(xhr.responseText);
}
});
}
</script>
}
Controller.cs
public ActionResult Index()
{
/*Do all stuff before returning view
1. Get Json Data from Ajax request
2. Deserialize the obtained Json Data
3. return to view
*/
return View("Index");
}
Update:
I have tried the solution given by #J. Doe, but still unable to get the result set. Please check the screenshot and below code..
Ajax Request:
function GetEventDetails(contextRoot) {
$.ajax({
type: "GET",
url: contextRoot + "api/EventsAPI",
dataType: "json",
success: function (data) {
debugger;
var datavalue = data;
contentType: "application/json; charset=utf-8";
console.log(data);
var EventJson = data;
console.log(EventJson);
$.ajax({
type: "POST",
url: "#Url.Action("Index")",
dataType: "json",
data: EventJson,
contentType: "application/json; charset=utf-8",
//data: EventJson,
success: function (data) {
alert(data.responseText);
console.log('Data received: ');
console.log(data.responseText);
},
failure: function (errMsg) {
console.log(errMsg);
}
});
},
error: function (xhr) {
alert(xhr.responseText);
}
});
}
Class Properties:
public class RootObject
{
public Embedded _embedded { get; set; }
public Links _links { get; set; }
public Page page { get; set; }
}
Here is Action Result Controller:
public ActionResult Index(RootObject model)
{
if (model != null)
{
return Json("Success");
}
else
{
return Json("An Error Has occoured");
}
//return View("Index");
}
Error Snapshot:
enter image description here
1) Add [FromBody] the controller you are returning to. This will make the controller expect a JSON object.
[HttpPost]
public ActionResult Index([FromBody]RootObject model)
{
if (model != null)
{
return Json("Success");
}
else
{
return Json("An Error Has occoured");
}
//return View("Index");
}
2) If this doesn't work you are not posting a correct json object/you are not posting a json object use console.dir(EventJson); to inspect the object you are passing in the console of the browser.
3) How to create a JSON object in JS: https://www.w3schools.com/js/js_json_stringify.asp
We are trying
Hello soviet sojuz!
But back to question - A 2 months ago i created sample on GitHub with ajax with .Net Core - https://github.com/CShepartd/ASP.Net_Core_-_Ajax_Example
In short:
Make action with objects in controller:
public IActionResult Ajax(string name1, string name2)
{
return View();
}
Next in view send name1 and name2 to action
$('form').submit(function(event) {
event.preventDefault();
var data = {
name1: $("input[name='name1']", this).val(),
name2: $("input[name='name2']",this).val()
};
$.ajax({
type: 'POST',
url: '/Home/Ajax',
dataType: 'json',
data: data,
success: function(response) {
alert(response);
console.log('Data received: ');
console.log(response);
},
failure: function(response) {
//...
},
error: function(response) {
//...
}
});
});
I have been trying for few hours to debug a Post Ajax call to my server.
I have 2 POST methods: HelloWorld and HelloYou.
Same code, the only difference is that HelloYou takes a string as parameter:
namespace WebService
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service
{
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
public string HelloWorld()
{
return "Hello World";
}
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
public string HelloYou(string name)
{
return string.Format("Hello {0}",name);
}
}
}
The HTML client looks like that:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My Application</title>
<script type="text/javascript" src="/Scripts/jquery-2.1.1.min.js"</script>
<script type="text/javascript" src="/Scripts/ajax.js"> </script>
<script type="text/javascript" src="/Scripts/events.js"> </script>
</head>
<body>
<button id="world">HelloWorld</button>
<button id="you">HelloYou</button>
</body>
</html>
and the Ajax calls:
$(document).ready(function () {
$('#world').click(function () {
HelloWorld();
});
$('#you').click(function () {
HelloYou();
});
});
baseAddress = "http://localhost:53016/Service.svc/ajax/";
function GetURL(method) {
return baseAddress + method;
}
function HelloWorld() {
$.ajax({
async: false,
url: GetURL("HelloWorld"),
dataType: 'json',
type: 'POST',
data: null ,
processdata: true,
contentType: "application/json;charset-uf8"
})
.done(function(data) {
alert(data.d);
})
.fail(function (xhr, status, errorThrown) {
alert(status + errorThrown);
});
}
function HelloYou() {
$.ajax({
async: false,
url: GetURL("HelloYou"),
dataType: 'json',
type: 'POST',
data: JSON.stringify('{"name": "Chris"}'),
processdata: true,
contentType: "application/json;charset-uf8"
})
.done(function (data) {
alert(data.d);
})
.fail(function (xhr, status, errorThrown) {
alert(status + errorThrown);
});
}
I have tried few different ways to pass the parameter to the Ajax call:
data: JSON.stringify('{"name": "Chris"}'),
data: '{"name": "Chris"}',
data: '{name: "Chris"}',
var name ="Chris"
data: '{name: ' + JSON.stringify(name) + '}',
Every time, I get an error Bad Request 400. The same function HelloWorld with no parameter works fine.
I am lost.
I checked with Fidler the HTML Request/Response:
POST /Service.svc/ajax/HelloYou HTTP/1.1
HTTP/1.1 400 Bad Request
Thanks all
Isidore
I found a way to make it work. I changed the method from POST to GET.
For the data, I looked on JQuery API Documentation:
data: { name: "John"},
and it works. I am surprised, I thought GET wouldn't let me push data to the server.
Cheers
Isidore
I went through the yammer api's and created an simple html to post the feed into the wall.
But I have not found a clear idea to post to specific group.
I am using the following code to post on the wall.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator" content="HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org"/>
<title>A Yammer App</title>
<script src="https://assets.yammer.com/platform/yam.js" type="text/javascript">
</script>
<script type="text/javascript">
//<![CDATA[
yam.config({appId: "hyB2pTvrL36Y50py8EWj6A"});
//]]>
</script>
<title>A Yammer App</title>
</head>
<body>
<button onclick='post()'>Post on Yammer!</button>
<script type="text/javascript">
//<![CDATA[
function post() { yam.getLoginStatus( function(response) { if (response.authResponse) { alert(1); yam.request( { url: "https://www.yammer.com/api/v1/messages.json" , method: "POST" , data: { "body" : "HelloTest"} , success: function (msg) { alert("Post was Successful!: " + msg); } , error: function (msg) { alert("Post was Unsuccessful..." + msg); } } ); } else { alert(2); yam.login( function (response) { if (!response.authResponse) { yam.request( { url: "https://www.yammer.com/api/v1/messages.json" , method: "POST" , data: { "body" : "HelloTest"} , success: function (msg) { alert("Post was Successful!: " + msg); } , error: function (msg) { alert("Post was Unsuccessful..." + msg); } } ); } }); } }); }
//]]>
</script>
<script src="https://assets.yammer.com/platform/yam.js" type="text/javascript">
</script>
<script type="text/javascript">
//<![CDATA[
yam.config({appId: "hyB2pTvrL36Y50py8EWj6A"});
//]]>
</script>
<button onclick='post()'>Post on Yammer!</button>
<script type='' "text/javascript">
function post() { yam.getLoginStatus( function(response) { if (response.authResponse) { alert(1); yam.request( { url: "https://www.yammer.com/api/v1/messages.json" , method: "POST" , data: { "body" : "HelloTest"} , success: function (msg) { alert("Post was Successful!: " + msg); } , error: function (msg) { alert("Post was Unsuccessful..." + msg); } } ); } else { alert(2); yam.login( function (response) { if (!response.authResponse) { yam.request( { url: "https://www.yammer.com/api/v1/messages.json" , method: "POST" , data: { "body" : "HelloTest"} , success: function (msg) { alert("Post was Successful!: " + msg); } , error: function (msg) { alert("Post was Unsuccessful..." + msg); } } ); } }); } }); }
</script>
</body>
</html>
Can anyone guide me on this ?
I have changed the application id with the group application id as well.however it's just getting posted in the same wall with from as embed-widget.
you will have to include the group id in the API request to post the message .. here is an example in c#
StringBuilder data = new StringBuilder();
data.Append("body=" + System.Web.HttpUtility.UrlEncode(reply));
// the below line has the group Id encoded into the URL
data.Append("&group_id=" + System.Web.HttpUtility.UrlEncode(groupId));
//Create byte array of the data that is to be sent
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
//Set the content length in the request header
request.ContentLength = byteData.Length;
//write data
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
JObject jsonObj = null;
//Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
//get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
jsonObj = JObject.Parse(reader.ReadToEnd());
//Console.WriteLine("Message posted successfully!!");
return jsonObj["messages"][0]["id"].ToString();
}
}
This will post message to the particular group.
You should pass the group ID.
<script>
yam.config({appId: "Your App ID"}); //Your APP ID
</script>
<button style="width:150px" onclick='post()'>Post</button>
<script>
function post() {
yam.getLoginStatus( function(response) {
if (response.authResponse) {
yam.request(
{ url: "https://www.yammer.com/api/v1/messages.json"
, method: "POST"
, data: { "body" : "Posted to the group", "group_id":"UR GROUP ID"} // Pass ur Group ID here
}
);
} else {
yam.login( function (response) {
if (!response.authResponse) {
yam.request(
{ url: "https://www.yammer.com/api/v1/messages.json"
, method: "POST"
, data: { "body" : "Posted to the group", "group_id":"UR GROPU ID"}
}
);
}
});
}
});
}
</script>
I wrote a small API wrapper : Yammer.SimpleAPI.
You can use directly from Nuget
I am in the process of learning how to convert MVC Ajax to jquery ajax so I can do more.
This is the old ajax, I took out the loading stuff
#Ajax.ActionLink("Update Tweets", "Index", "Home",
new AjaxOptions
{
UpdateTargetId = "TweetBox",
InsertionMode = InsertionMode.InsertBefore,
HttpMethod = "Get",
})
I need to convert this to jquery ajax. It seems to be working lets see the code
<script>
$(document).ready(function () {
$("#StartLabel").click(function (e) {
$.ajax({
type: "Get",
url: '/Home/Index',
// data: "X-Requested-With=XMLHttpRequest",
// contentType: "application/text; charset=utf-8",
dataType: "text",
async: true,
// cache: false,
success: function (data) {
$('#TweetBox').prepend(data);
alert('Load was performed.');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
},
complete: function (resp) {
alert(resp.getAllResponseHeaders());
}
});
});
});
</script>
In the microsoft ajax it sets XML Request in the headers. Do I need to add that too? I am just paging my controller that performs a query to twitter and appends the data to the top.
I am using fiddler to see how the requests are different but the results are the same.
I also noticed if i put the text in the data: object its puts it in the header. i dont think that is right by any means.
You could define a normal anchor:
#Html.ActionLink("Update Tweets", "Index", "Home", null, new { id = "mylink" })
And then unobtrusively AJAXify it:
$(document).ready(function () {
$("#mylink").click(function (e) {
$.ajax({
type: "GET",
url: this.href,
success: function (data) {
$('#TweetBox').prepend(data);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
},
complete: function (resp) {
alert(resp.getAllResponseHeaders());
}
});
return false;
});
});
Notice that I return false from the click handler in order to cancel the default action. Also notice that I am using the anchor's href property instead of hardcoding it.
The 2 AJAX requests should be identical.
Here is simple example using Ajax with Jason data
// Post JSON data
[HttpPost]
public JsonResult JsonFullName(string fname, string lastname)
{
var data = "{ \"fname\" : \"" + fname + " \" , \"lastname\" : \"" + lastname + "\" }";
return Json(data, JsonRequestBehavior.AllowGet);
}
in the view add a reference to the query as following
#section Scripts{
<script src="~/Scripts/modernizr-2.6.2.js"></script>
<script src="~/Scripts/jquery-1.8.2.intellisense.js"></script>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
}
in the view add the js
note: (jsonGetfullname).on is a button
<script type="text/javascript">
$("#jsonGetfullname").on("click", function () {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "#(Url.Action("JsonFullName", "Home"))",
data: "{ \"fname\" : \"modey\" , \"lastname\" : \"sayed\" }",
dataType: "json",
success: function (data) {
var res = $.parseJSON(data);
$("#myform").html("<h3>Json data: <h3>" + res.fname + ", " + res.lastname)
},
error: function (xhr, err) {
alert("readyState: " + xhr.readyState + "\nstatus: " + xhr.status);
alert("responseText: " + xhr.responseText);
}
})
});
</script>
you can also use (POST\GET) as following:
[HttpPost]
public string Contact(string message)
{
return "<h1>Hi,</h1>we got your message, <br />" + message + " <br />Thanks a lot";
}
in the view add the js
note: (send).on is a button
$("#send").on("click", function () {
$.post('', { message: $('#msg').val() })
.done(function (response) {
setTimeout(function () { $("#myform").html(response) }, 2000);
})
.error(function () { alert('Error') })
.success(function () { alert('OK') })
return false;
});