Error while calling Webapi in my asp.net project - javascript

This is my api code that return successfull json data while using get method
public Question[] Get() {
getQuestion obj = new AllDataAccess.getQuestion();
return obj.questionList().ToArray();
}
This is my post method data that accept the value and save in database
public void Post([FromBody] string question) {
SaveQuestion obj = new AllDataAccess.controller.SaveQuestion();
obj.savaData(question);
}
This is the method that call my api
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: 'http://localhost:53893/api/values',
data: "{'question':'" + $("#submit").value + "'}",
dataType: 'json',
async: false,
success: function(data, status) {
console.log(status);
},
error: function(err) {
console.log(err);
}
});
Now the problem is when i post the data with one textbox value its give me a message in console that "nocontent" and record save in data base with null value

It seems that your ajax url is wrong. You should specify the action name (post). Also, use JSON.stringify to retrieve proper json from javascript object.
var postData = { question:$("#submit").val() };
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: 'http://localhost:53893/api/values/post',
data: JSON.stringify(postData),
dataType: 'json',
success: function (data,status) {
console.log(status);
},
error: function (err) {
console.log(err);
}
});
In the server side, you should create a model class for Post method;
public class PostInput
{
public string Question { get; set; }
}
And then Post method looks like;
[HttpPost]
public void Post([FromBody]PostInput input)
{
SaveQuestion obj = new AllDataAccess.controller.SaveQuestion();
obj.savaData(question);
}

If you want to use FromBody, you can do so.
JavaScript
$.ajax({
type: "POST",
//default content-type, could be omitted
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
url: 'http://localhost:53893/api/values/post',
data: {'': $("#submit").val()}
});
API action
[HttpPost]
public void Post([FromBody]string question)
{
SaveQuestion obj = new AllDataAccess.controller.SaveQuestion();
obj.savaData(question);
}
You had these issues.
Wrong content-type for your ajax call.
Data was not posted correctly.
val() should be used instead of .value.
API action should be decorated with [HttpPost].

Related

Validate Anti forgery key not working with ajax post

I have tried to use validate antiforgery token with ajax post request but the response is that no root element found .
i remove the antiforgery token it works perfectly .
Here is my code :
javascript ;
function Save() {
let GroupName = GetElementValue("GroupName");
let GroupId = GetElementValue("GroupId");
var Group = {
__RequestVerificationToken: gettoken(),
GroupId: :1",
GroupName: "My Group Name"
};
if (IsFormValid("GroupForm")) {
AjaxPost("/Groups/AddGroup", Group).done(function () {
GetGroups();
});
}
}
function gettoken() {
var token = '#Html.AntiForgeryToken()';
token = $(token).val();
return token;
}
function AjaxPost(url, data) {
return $.ajax({
type: "post",
contentType: "application/json;charset=utf-8",
dataType: "json",
responseType: "json",
url: url,
data: JSON.stringify(data)
});
}
I have also tried this :
$.ajax({
type: "POST",
url: "/Groups/AddGroup",
data: {
__RequestVerificationToken: gettoken(),
GroupId: 1,
GroupName: "please work"
},
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
});
Here Is The backend :
[HttpPost]
[ValidateAntiForgeryToken]
public void AddGroup([FromBody] GroupView Group)
{
if (Group.GroupName.Trim().Length>0)
{
bool existed = _context.Groups.Any(x => x.GroupName.ToLower().TrimEnd().Equals(Group.GroupName.ToLower().TrimEnd()));
if (!existed)
{
Groups group = new Groups()
{
GroupName = Group.GroupName
};
_context.Groups.AddAsync(group);
_context.SaveChanges();
int? groupId = group.GroupId;
}
}
}
And Here Is My Class GroupView
public class GroupView
{
public string GroupId { get; set; }
public string GroupName { get; set; }
}
I want to use the method where i send the serial token with my data normally ,
how can i make it works ?
any help!
In ASP.NET Core you can pass antiforgery token either via form or headers. So I can suggest 2 solutions for you.
Solution 1. Headers
In order to let the framework read token from headers you need to configure AntiforgeryOptions and set HeaderName to non null value. Add this code to Startup.cs
//or if you omit this configuration
//HeaderName will be "RequestVerificationToken" by default
services.AddAntiforgery(options =>
{
options.HeaderName = "X-CSRF-TOKEN"; //may be any other valid header name
});
And pass antiforgery token in AJAX
function Save() {
//..
//no need to set token value in group object
var Group = {
GroupId: "1",
GroupName: "My Group Name"
};
//..
}
function AjaxPost(url, data) {
return $.ajax({
type: "post",
contentType: "application/json;charset=utf-8",
dataType: "json",
responseType: "json",
headers: {
"X-CSRF-TOKEN": gettoken()
},
url: url,
data: JSON.stringify(data)
});
Solution 2. Form
You have already tried to pass token via form but it didn't work. Why? The reason is that the default implementation of IAntiforgeryTokenStore (is used for reading tokens from request) cannot read antiforgery token from json but reads it as form data. If you want to make it work then don't stringify request data and remove contentType property from $.ajax call. JQuery will set appropriate content type and serialize data respectively for you.
//all other original code is unchanged, group needs to contain a token
function AjaxPost(url, data) {
return $.ajax({
type: "post",
dataType: "json",
responseType: "json",
url: url,
data: data
});
Also you need to remove [FromBody] attribute from action parameter to let model binder properly bind model in this case
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddGroup(GroupView group)
For FromBody, it will bind the model from application/json, but CSRF would not read the token from body.
For the simplest way, you could add the header with RequestVerificationToken.
Controller
[HttpPost("/Groups/AddGroup")]
[ValidateAntiForgeryToken]
public void AddGroup([FromBody] GroupView Group)
{
}
Client
<script type="text/javascript">
$(document).ready(function(){
var Group = {
__RequestVerificationToken: gettoken(),
GroupId: 1,
GroupName: "My Group Name"
};
AjaxPost("/Groups/AddGroup", Group).done(function () {
GetGroups();
});
});
function gettoken() {
var token = '#Html.AntiForgeryToken()';
token = $(token).val();
return token;
}
function AjaxPost(url, data) {
return $.ajax({
type: "post",
contentType: "application/json;charset=utf-8",
dataType: "json",
responseType: "json",
url: url,
headers: {
"RequestVerificationToken": gettoken()
},
data: JSON.stringify(data)
});
}
</script>

ajax post global function vs repeat the same function for each request

I have something that i do not understand .
I do have a global function AjaxPost()
that take url and data than send them to backend .
it calls the function but the parameters are always null .
So i take the same content of the function and used it directly in the request , it works perfectly .
this One Doesn't work //example : AjaxPost("/Road/DeleteRoad", road);
function AjaxPost(url, data) {
return $.ajax({
type: "post",
url: url,
contentType: "application/json;charset=utf-8",
dataType: "json",
data: JSON.stringify(data)
});
}
this one works perfectly
$.ajax({
type: "post",
url: "/Road/DeleteRoad",
contentType: "application/json;charset=utf-8",
dataType: "json",
data: JSON.stringify(road)
});
Here the action method
[HttpPost]
public async Task<IActionResult> DeleteRoad([FromBody]r road)
{
int.TryParse(road.RoadID, out int RoadID);
if (RoadID > 0)
{
await _road.DeleteRoad(RoadID);
}
return RedirectToAction("Index");
}
Here is the class r
public class r
{
public string RoadID { get; set; }
}
Here Is The Road object
//for example :
var road ={
RoadID :4,
}
Maybe you are not passing the road parameter correctly?
The following code works, sending two calls to the server. The server correctly retrieves the RoadID value. Here's the javascript:
"use strict";
$(document).ready(() => {
var road = { RoadID: 4 };
// First call
$.ajax({
type: "post",
url: "/home/DeleteRoad",
contentType: "application/json;charset=utf-8",
dataType: "json",
data: JSON.stringify(road)
});
// Second call
ajaxPost("/home/DeleteRoad", road);
}
function ajaxPost(url, data) {
return $.ajax({
type: "post",
url: url,
contentType: "application/json;charset=utf-8",
dataType: "json",
data: JSON.stringify(data)
});
}
The C# code is:
public class Road
{
public string RoadID { get; set; }
}
[HttpPost]
public async Task<ActionResult> DeleteRoad([System.Web.Http.FromBody]Road road)
{
Debug.WriteLine($"Road ID = { road.RoadID }");
return RedirectToAction("Index");
}
The server's output is:
Road ID = 4
Road ID = 4
Hope this helps :)

Pass json from js to controller

Data doesn't passing to controller, always null
My script in view:
function deleteRecords() {
var selected = [];
$('#myTable input:checked').each(function () {
selected.push($(this).attr('id'));
});
$.ajax({
url: '/Home/DeleteRecords',
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: { "json": JSON.stringify(selected) },
error: function () {
alert("Error!");
}
});
}
My home controller method:
[HttpPost]
public IActionResult DeleteRecords(string AllId)
{
return null;
}
send ajax request data like below,
$.ajax({
url: '/Home/DeleteRecords',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(selected),
error: function () {
alert("Error!");
}
});
and receive the data in action like
[HttpPost]
public IActionResult DeleteRecords(string[] AllId)
{
return null;
}
It need to pass the action. Hope it helps to you.
with the code in your question, try below to get the json
System.Web.Context.Current.Request.Form["json"]
if you want some more graceful stuff, you need to put FromBody attribute in your parameter signature
DeleteResults([FromBody] string json)
Name your property in the Post the same as your method so that the automatic binding picks it up. - Turns out this doesn't matter for single object.
The data Object you were creating was not parse-able by .net, use JSON.stringify directly for the data payload.
Note: The change in Home controller since you are passing an array of string.
function deleteRecords() {
var selected = [];
$('#myTable input:checked').each(function () {
selected.push($(this).attr('id'));
});
$.ajax({
url: '/Home/DeleteRecords',
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(selected),
error: function () {
alert("Error!");
}
});
}
For your home controller method:
[HttpPost]
public IActionResult DeleteRecords(string[] AllId)
{
return null;
}

Jquery Ajax and MVC5 httpPost no value received

I try to send values from my view to my controller.
The method in my controller is called but the value(s) still remain NULL.
Here is the Javascript part:
GUIRequests.prototype.SetNewItemDeliveryValues = function () {
var modelNumberID = this.GetValue('#ModelNumberID');
this.Request.GetPreOrderIDForModelNumberID(modelNumberID); //InventValueRequest
this.Request.GetShortfallAndOverdeliveryInNewItemDelivery(modelNumberID);
}
InventValueRequest.prototype.GetPreOrderIDForModelNumberID = function (_modelNumberID) {
this.CallAjax("/NewItemDelivery/GetPreOrderIDForModelNumberID", _modelNumberID, CallbackMethods.SetPreOrderID);
}
//Private
InventValueRequest.prototype.CallAjax = function (_url, _data, _successFunctionPointer) {
$.ajax({
type: 'POST',
url: _url,
contentType: 'application/json',
data: JSON.stringify(_data),
success: _successFunctionPointer,
error: InventValueRequest.HandleError
});
}
Asp.Net MVC5 (C#) part
[HttpPost]
public ActionResult GetPreOrderIDForModelNumberID(string _modelnumberID)
{
String preOrderID = "";
if (_modelnumberID == null)
{
preOrderID = "No value received";
}
else
{
//Do something
}
return Json(preOrderID);
}
What could be the problem with my code ? why don't I receive any values in my C# part ? It seems that the values get send correctly, at least the payload contains the values I would expect.
_data should have the property _modelnumberID like following.
_data = {'_modelnumberID': '1'}
try below code :
$.ajax({
type: 'POST',
dataType: 'text',
url: _url,
contentType: 'application/json',
data: "_modelnumberID=" + _data,
success: _successFunctionPointer,
error: InventValueRequest.HandleError
});
The Ideal solution would be to use a view model.
public class Create
{
public string _modelnumberID{get;set;}
}
And your HttpPost action would be accepting an object of this
[HttpPost]
public ActionResult View(Create model)
{
// do something and return something
}
and ajax will be
$('.submit').click(function () {
var myData = {
_modelnumberID: _data
}
$.ajax({
url: '/Controller/Action',
type: 'POST',
data: myData,
processData: false
}).done(function () {
}).fail(function () {
});
});
$.ajax({
type: 'POST',
url: _url+"?_modelnumberID="+ _data,
success: _successFunctionPointer,
error: InventValueRequest.HandleError
});
Try this.

Pass string array as data in jquery ajax to web api

I am trying to pass string array to a Web Api method which accepts an array of strings as argument. Bellow my Web Api method
[HttpGet]
public string HireRocco(string[] hitList)
{
string updateList = string.Empty;
return updateList;
}
My ajax
var uri = 'http://localhost:16629/api/AssassinApi/HireRocco',
hitList = ['me', 'yourself'];
$.ajax({
url: uri,
type: 'GET',
data: { hitList : hitList },
cache: false,
dataType: 'json',
async: true,
contentType: false,
processData: false,
success: function (data) {
},
error: function (data) {
}
});
The above ajax successfully hits the HireRocco method but hitList param is still null. What should I change to pass an array of strings as param.
If you need to send data via a HttpGet, you can add [FromUri] you can edit your controller action as follows and your JavaScript should work as is:
[HttpGet]
public string HireRocco([FromUri] string[] hitList)
{
string updateList = string.Empty;
return updateList;
}
Remove contentType: false then set processData to true so it can append the postData your url, as that's how a get request works or you will have to change your api to accept POST request which are set through the header.
$.ajax({
url: uri,
type: 'GET',
data: { hitList : hitList },
cache: false,
dataType: 'json',
async: true,
processData: true,
success: function (data) {
console.log(data);
},
error: function (data) {
}
});
First of all i suggest that you use POST rather than GET.
create a javascript array. push the data inside it. send it to web api action method by using JSON.Stringify.. and then process the further logic.
In web api create a model variable.. and create a list object..
Following is the code..
Javascript
var demoarray=[];
demoarray.push({"test1":"hi", "test2":"hello"}); //test1 and test2 are model variable names in web api and hi and hello are their values
you can repeat the process in for loop or something for adding multiple values.
$.ajax({
url:"http://localhost..",
type: "POST",
data: JSON.Stringify(demoarray),
contentType: "application/json",
success: function(data)
{
},
error: function(data)
{
}
});
WEB API Code
Create a model class and two properties
public string test1 {get; set;}
public string test2 {get; set;}
controller code
[Httppost]
public void actionmethod(List<modelclass> obj)
{
int i=0;
for(i=0; i<obj.count; i++)
{
//your logic
}
}

Categories

Resources