this is my client side ajax call:
var list = ["a", "b", "c", "d"];
var jsonText = { data: list };
$.ajax({
type: "POST",
url: "/api/scheduledItemPriceStatus/updateStatusToDelete",
data: jsonText,
dataType: "json",
traditional: true,
success: function() { alert("it worked!"); },
failure: function() { alert("not working..."); }
});
this is chrome network header:
Request URL:http://localhost:2538/api/scheduledItemPriceStatus/updateStatusToDelete
Request Method:POST
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:27
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Host:localhost:2538
Origin:http://localhost:2538
Referer:http://localhost:2538/Pricing/ScheduledItemPrices
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11
X-Requested-With:XMLHttpRequest
Form Dataview URL encoded
data:a
data:b
data:c
data:d
this is my webapi controller method:
public HttpResponseMessage UpdateStatusToDelete(string[] data)
result:
when I debug, the data parameter in UpdateStatusToDelete returns {string[0]} instead of data:a
data:b
data:c
data:d
What am I doing wrong? Any help is really appreciated.
For passing simply types, the data to post must take the form of a name value pair with the name portion being an empty string. So you need to make the Ajax call like so:
$.ajax({
type: "POST",
url: "/api/values",
data: { "": list },
dataType: "json",
success: function() { alert("it worked!"); },
failure: function() { alert("not working..."); }
});
Additionally, on your Web API action, annotate it w/ the [FromBody] attribute. Something like:
public void Post([FromBody]string[] values)
That should do the trick.
You should pass the list itself, and not any other object wrapping it.
E.g. pass the following:
var list = ["a", "b", "c", "d"];
in
$.ajax({
type: "POST",
url: "/api/scheduledItemPriceStatus/updateStatusToDelete",
// Pass the list itself
data: list,
dataType: "json",
traditional: true,
success: function() { alert("it worked!"); },
failure: function() { alert("not working..."); }
});
Your method signature on server is correct.
use var jsonText = { data: JSON.stringify(list)}
In the backend, you could use FormDataCollection.GetValues(string key) to return an array of strings for that parameter.
public HttpResponseMessage UpdateStatusToDelete(FormDataCollection formData) {
string[] data = formData.GetValues("data");
...
}
use the method above to send array as suggested by cris in your jquery ajax call.
JSON data is usually in key value pair.
var tmp = [];
tmp.push({
//this is the key name 'a' "a": "your value", //it could be anything here in
//string format.
"b": "b",
"c": "c",
"d": "d"
});
{ data: JSON.stringify(tmp);}
You can also accomplish above by using two dimensional array
Additionally do this in the webapi project.
under the models folder in your web api project create a class file. Possibly class1.cs.
Create 4 properties
public string a {get; set;}
public string b {get; set;}
public string c {get; set;}
public string d {get; set;}
Now do this in your controller
using projectname.models
[HttpPost]
public return-type actionname(List<Class1> obj)
{
//Further logic goes here
}
I am sure this will work.
Setting the dataType won't help you.
This is how I do it :
var SizeSequence = {};
SizeSequence.Id = parseInt(document.querySelector("dd#Sequence_Id").textContent);
SizeSequence.IncludedSizes = [];
var sizes = document.querySelectorAll("table#IncludedElements td#Size_Name");
// skipping the first row (template)
for (var i = 1, l = sizes.length ; i != sizes.length ; SizeSequence.IncludedSizes.push(sizes[i++].textContent));
$.ajax("/api/SizeSequence/" + SizeSequence.Id, {
method: "POST",
contentType: "application/json; charset=UTF-8",
data: JSON.stringify(SizeSequence.IncludedSizes),
...
The Server Part
// /api/SizeSequence/5
public async Task<IHttpActionResult> PostSaveSizeSequence(int? Id, List<String> IncludedSizes)
{
if (Id == null || IncludedSizes == null || IncludedSizes.Exists( s => String.IsNullOrWhiteSpace(s)))
return BadRequest();
try
{
await this.Repo.SaveSizeSequenceAsync(Id.Value, IncludedSizes );
return Ok();
}
catch ( Exception exc)
{
return Conflict();
}
}
References
jQuery.ajax()
You can also do this with JSON.stringify, which feels more semantically intuitive than putting things in an object with an empty string key. (I am using Web API 2, not sure if that matters.)
Client code
$.ajax({
type: 'POST', //also works for PUT or DELETE
url: '/api/UserRole',
contentType: "application/json",
data: JSON.stringify(["name1", "name2"])
})
Server Code
[HttpPost]
[Route("api/UserRole")]
public IHttpActionResult AddUsers(string[] usernames)
Related
I'm using ajax to send an int64 and a string from a month selector to my server-side, but my variable is always null or 0.
JS:
function deleteConta(id) {
var data = $("#monthSelector").val();
var params = {
id: id,
dataAtual: data
};
$.ajax({
type: "POST",
url: '/Contas/ContaView?handler=Delete',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(params),
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (partialReturn) {
$("#partial").html(partialReturn);
}
});
}
C#:
public PartialViewResult OnPostDelete([FromBody] long id, string dataAtual)
{
contaDTO.Remove(id, contaDTO.Database, contaDTO.ContaCollection);
dataCorrente = DateTime.ParseExact(dataAtual, "yyyy-MM", null).AddMonths(1);
contas = BuscarContasUsuarioMes(User.Identity.Name, dataCorrente);
return Partial("_PartialContas", contas);
}
I already checked with debugger and my variables are ok and filled with value expected (One test was like {id: 50, dataAtual: '2023-01'}
Checked a lot of forums, but Couldn't figure out how to make this thing work.
By declaring the number parameter with [FromBody] you tell ASP.NET Core to use the input formatter to bind the provided JSON (or XML) to a model. So your test should work, if you provide a simple model class.
Have you tried to remove it and sending value to the action?
—- UPDATE ——
Try this
function deleteConta(id) {
var data = $("#monthSelector").val();
$.ajax({
type: "POST",
url: '/Contas/ContaView?handler=Delete',
data: { id: id, dataAtual: data },
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (partialReturn) {
$("#partial").html(partialReturn);
}
});
}
I have a view with multiple inputs for my Model (Html.TextBoxFor(x => x.attribute) etc. And my ajax method is:
function callMethod() {
$.ajax({
type: "POST",
data: $('#Form').serialize() ,
url: '#Url.Action("formMethod", "Test")',
}).done(function (newTable) {
$('#RefundTableDiv').html(newTable);
});
};
and this works perfectly, the model comes perfectly to formMethod, but when i change formMethod and add another parameter for example 'int test' it doesnt work anymore.
My method looks like:
function callMethod() {
var number = 2;
$.ajax({
type: "POST",
data: {"model": $('#Form').serialize(),
"test": number},
url: '#Url.Action("formMethod", "Test")',
}).done(function (newTable) {
$('#RefundTableDiv').html(newTable);
});
};
the "test": number does come correctly to the method in the controller but the model suddenly is null now?
What am i doing wrong?
Using .serialize() serializes your model as a query string (e.g. someProperty=someValue&anotherProperty=anotherValue&...). To add additional name/value pairs, you can append then manually, for example
var data = $('#Form').serialize() + '&test=' + number;
$.ajax({
....
data: data;
or use the param() method (useful if you have multiple items and/or arrays to add)
var data = $("#Form").serialize() + '&' + $.param({ test: number }, true);
$.ajax({
....
data: data;
you can do it like this:
function callMethod() {
var number = 2;
var sd = $('#Form').serializeArray();
sd.push({ name:"test", value:number });
$.ajax({
type: "POST",
data: sd,
url: '#Url.Action("formMethod", "Test")',
}).done(function (newTable) {
$('#RefundTableDiv').html(newTable);
});
};
I don´t know why my parameter "ParametroFiltro Filtro" is getting null, the other parameters "page" and "pageSize" is getting OK.
public class ParametroFiltro
{
public string Codigo { get; set; }
public string Descricao { get; set; }
}
My ApiController Get method:
public PagedDataModel<ParametroDTO> Get(ParametroFiltro Filtro, int page, int pageSize)
My ajax call:
var fullUrl = "/api/" + self.Api;
$.ajax({
url: fullUrl,
type: 'GET',
dataType: 'json',
data: { Filtro: { Codigo: '_1', Descricao: 'TESTE' }, page: 1, pageSize: 10 },
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
You are trying to send a complex object with GET method. The reason this is failing is that GET method can't have a body and all the values are being encoded into the URL. You can make this work by using [FromUri], but first you need to change your client side code:
$.ajax({
url: fullUrl,
type: 'GET',
dataType: 'json',
data: { Codigo: '_1', Descricao: 'TESTE', page: 1, pageSize: 10 },
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
This way [FromUri] will be able to pick up your complex object properties directly from the URL if you change your action method like this:
public PagedDataModel<ParametroDTO> Get([FromUri]ParametroFiltro Filtro, int page, int pageSize)
Your previous approach would rather work with POST method which can have a body (but you would still need to use JSON.stringify() to format body as JSON).
Provide the contentType property when you make the ajax call. Use JSON.stringify method to build the JSON data to post. change the type to POST and MVC Model binding will bind the posted data to your class object.
var filter = { "Filtro": { "Codigo": "_1", "Descricao": "TESTE" },
"page": "1", "pageSize": "10" };
$.ajax({
url: fullUrl,
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(filter),
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
It's also possible to access POST variables via a Newtonsoft.Json.Linq JObject.
For example, this POST:
$.ajax({
type: 'POST',
url: 'URL',
data: { 'Note': note, 'Story': story },
dataType: 'text',
success: function (data) { }
});
Can be accessed in an APIController like so:
public void Update([FromBody]JObject data)
{
var Note = (String)data["Note"];
var Story = (String)data["Story"];
}
If you append json data to query string, and parse it later in web api side. you can parse complex object too. It's useful rather than post json object, espeicaly in some special httpget requirement case.
//javascript file
var data = { UserID: "10", UserName: "Long", AppInstanceID: "100", ProcessGUID: "BF1CC2EB-D9BD-45FD-BF87-939DD8FF9071" };
var request = JSON.stringify(data);
request = encodeURIComponent(request);
doAjaxGet("/ProductWebApi/api/Workflow/StartProcess?data=", request, function (result) {
window.console.log(result);
});
//webapi file:
[HttpGet]
public ResponseResult StartProcess()
{
dynamic queryJson = ParseHttpGetJson(Request.RequestUri.Query);
int appInstanceID = int.Parse(queryJson.AppInstanceID.Value);
Guid processGUID = Guid.Parse(queryJson.ProcessGUID.Value);
int userID = int.Parse(queryJson.UserID.Value);
string userName = queryJson.UserName.Value;
}
//utility function:
public static dynamic ParseHttpGetJson(string query)
{
if (!string.IsNullOrEmpty(query))
{
try
{
var json = query.Substring(7, query.Length - 7); //seperate ?data= characters
json = System.Web.HttpUtility.UrlDecode(json);
dynamic queryJson = JsonConvert.DeserializeObject<dynamic>(json);
return queryJson;
}
catch (System.Exception e)
{
throw new ApplicationException("can't deserialize object as wrong string content!", e);
}
}
else
{
return null;
}
}
In .NET Core, the HttpClient sets the transfer-encoding: chunked header by default. This can cause the .NET Web API controller parameters to be null.
To get around this, you'll need to set the ContentLength header explicitly:
var json = JsonConvert.SerializeObject(myObject);
var content = new StringContent(json, Encoding.UTF8, "application/json");
content.Headers.ContentLength = json.Length;
var response = await client.PostAsync("http://my-api.com", content);
SO answer if you already know the transfer-encoding header is the issue: How to disable Chunked Transfer Encoding in ASP.Net C# using HttpClient
Related bug which won't be fixed, which gives some insight into the problem: https://github.com/dotnet/runtime/issues/30283
Here is my ajax call
$.ajax({
async: false,
url: "/api/clients/UpdateResourceContactProductsByResourceContactId/" + id,
type: 'POST',
data: { strIds: strIds },
success: function (data) {
}
});
where id is the integer and strIds is a string contantenation of integers, they look like 123_254_741_6650 ...
And this the server side code ...
[HttpPost]
public IHttpActionResult UpdateResourceContactProductsByResourceContactId
(int id, string strIds)
{
//...
}
When I hit the update button, I'm getting the following error:
{"Message":"No HTTP resource was found that matches the request URI
'http://localhost/api/clients/UpdateResourceContactProductsByResourceContactId/22757'.",
"MessageDetail":"No action was found on the controller 'Clients' that matches the request."}
Am I missing something?
Try this...
$.ajax({
async: false,
url: "/api/clients/UpdateResourceContactProductsByResourceContactId",
type: 'POST',
data: { id: id, strIds: strIds },
success: function (data) {
}
});
I think you're passing the data wrong. You are passing a object. Either change you method to accept a JObject and use dynamic to pull the strIds out, pass the string by itself, or use it as a URL parameter.
//example using JObject below
[HttpPost]
public IHttpActionResult UpdateResourceContactProductsByResourceContactId(int id, JObject data)//JObject requires Json.NET
{
dynamic json = data;
string ids = json.strIds
}
If you are going to POST an object you need to call JSON.stringify on it too in the javascript.
var data = JSON.stringify({ strIds: strIds });
$.ajax({
async: false,
url: "/api/clients/UpdateResourceContactProductsByResourceContactId/" + id,
type: 'POST',
data: data,
success: function (data) {
}
});
I am trying to get a list of items in WebAPI
The ajax methods looks like this
$.ajax({
type: 'GET',
url: 'api/values',
data: JSON.stringify({ pageNo: pageNo + 1, pageSize: pageSize }),
contentType: 'application/json'
});
In the values controller I am not able to get the values.
my controller looks like this.
public IEnumerable<string> Get([FromURI] pagingInfo)
{
return new string[] { "value1", "value2" };
}
What is the correct standard. Is the above standard correct
or should put the pageno and pagesize in url and create an another route.
Generally, it is not recommended (or even banned) to send body via GET, just only query string is valid:
Removing method JSON.stringify, your ajax call should be:
$.ajax({
type: "GET",
url: "/api/values",
data: { pageNo: 1, pageSize: 2 },
success: function (data) {
}
});
It will automatically convert to query string, if using JSON.stringify, you will get JSON notation in query string and make it wrong. If you take a look on Fiddler, using JSON.stringify, the URL is like:
/api/values?{%22PageNo%22:1,%22PageSize%22:2}
And your Action is till:
public IEnumerable<string> Get([FromURI]PagingInfo pagingInfo)
{
return new string[] { "value1", "value2" };
}