Pass Javascript array to the back end with post - javascript

I am trying to pass a javascript array to the back end. But apparently, I am not expecting the right type in the back end. What type should I expect? I added the delete method as well. Do I need to iterate in this array to be able to delete records?
[{"questionId":135,"answer":"A6.1"},{"questionId":135,"answer":"A6.2"}]
function deleteAnswers(arrayToDelete) {
$http.post(baseUrl + "Admin/deleteAnswers", {data: arrayToDelete})
.success(function (data, status, headers, config) {})
}
[HttpPost]
public ActionResult deleteAnswers(string data) {
Console.Write(data);
Response.StatusCode = 200;
return Content("Sucess");
}
public void deleteAnswers(dynamic answersToDelete) {
try {
using (TestEntities testEntity = new TestEntities()) {
foreach (var item in answersToDelete) {
Console.Write(item.);
//remove from
}
testEntity.SaveChanges();
}
} catch (Exception ex) {
Console.Write(ex);
}
}

You are sending an object with a property data with an array value, so your signature should look something like this:
[HttpPost]
public ActionResult deleteAnswers(MyObject data)
{
Console.Write(data);
Response.StatusCode = 200;
return Content("Sucess");
}
public class MyObject {
public List<Answer> Data { get; set; }
}
public class Answer {
public int QuestionId { get; set; }
public string Answer { get; set; }
}

Related

How can I convert string to JSON in Model class

I would like convert string to JSON while receiving the value from API. I am sending value from postman but I am unable to convert it to the JSON object in the model class ,I have decorated model class with the custom decorator. Thanks in Advance.
This is the Model Class and I wrote custom JSON convertor.
namespace WebApplication2.Models
{
[Serializable]
public class Test
{
[JsonConverter(typeof(UserConverter))]
public AS_AscContext AscParcelContext { get; set; }
}
public class AS_AscContext
{
public string ShellType { get; set; }
public string LayoutName { get; set; }
}
public class UserConverter : JsonConverter
{
private readonly Type[] _types;
public UserConverter(params Type[] types)
{
_types = types;
}
public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
{
JToken t = JToken.FromObject(value);
if (t.Type != JTokenType.Object)
{
t.WriteTo(writer);
}
else
{
JObject o = (JObject)t;
IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList();
o.AddFirst(new JProperty("Keys", new JArray(propertyNames)));
o.WriteTo(writer);
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanRead
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return _types.Any(t => t == objectType);
}
}
This is the controller receiving value
[HttpPost]
public IActionResult Privacy([FromBody]Test aS_AggregatorRequest)
{
return View();
}
This is the postman collection
Try to change your postman JSON like this,
{
"ascParcelContext": {
"shellType": "ceme-sales-wallaby",
"layoutName": "value"
}
}
Don't escape any of the JSON data.
your json has another json inside. So it is better to fix the api but if you don't have an access try this
[HttpPost]
public IActionResult Privacy([FromBody]JObject jsonObject)
{
jsonObject["ascParcelContext"]= JObject.Parse( (string) jsonObject["ascParcelContext"]);
Test test = jsonObject.ToObject<Test>();
.....
}
public class Test
{
[JsonProperty("ascParcelContext")]
public AS_AscContext AscParcelContext { get; set; }
}
public class AS_AscContext
{
[JsonProperty("shellType")]
public string ShellType { get; set; }
[JsonProperty("layoutName")]
public string LayoutName { get; set; }
}

ASP.Net Core 3 Posting JSON array to controller

I´m having issues passing an array of JSON objects to an MVC controller in ASP.Net core 3. The JSON object is built from a CSV file and passed through an AJAX call. The correct action is called but the object received is always null.
JS:
async function updateData(){
var obj = await getData();
$.ajax({
type: "POST",
contentType: "application/json",
url: "/admin/metric/Update",
data: obj,
dataType: 'json',
success: function (data) {
console.log("SUCCESS : ", data);
},
error: function (e) {
console.log("ERROR : ", e);
}
});
}
async function getData(){
var metric = {};
var metrics = [];
var response = await fetch('https://bloburi.net/source/file.csv');
var data = await response.text();
var table = data.split('\n').slice(1);
table.forEach(row => {
var columns = row.split(',');
metric["FirstName"] = columns[0];
metric["LastName"] = columns[1];
metric["Email"] = columns[2];
metric["AverageHandleTime"] = columns[3];
metric["AverageFollowUp"] = columns[4];
metric["AverageHold"] = columns[5];
metric["Date"] = columns[6];
metrics.push(JSON.stringify(metric));
});
console.log(metrics);
return metrics;
}
Models:
public class MetricBase
{
[Required]
public string Date { get; set; }
public double AverageHandleTime { get; set; }
public double AverageHold { get; set; }
public double AverageFollowUp { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class MetricModel
{
public IEnumerable<MetricBase> MetricBase { get; set; }
}
Controller:
[HttpPost]
public IActionResult Update([FromBody]MetricModel obj)
{
return Json(new { obj });
}
I think the issue may be on how I'm deffining the class that is receiving the JSON, but I've tried multiple things like deffining MetricBase as a List<> or straight up as an array in MetricModel, but it doesn't seem to work.
Any help is appreciated!
You adding the stringify item inside array via code
metrics.push(JSON.stringify(metric));
instead of stringify the whole array. Change the line to
metrics.push(metric);
and data: obj, to
data: JSON.stringify(obj),.
With the mentioned change, the $.ajax sends the whole array. Also change the action to
public IActionResult Update([FromBody]IEnumerable<MetricBase> obj)

Pass Array of Objects in http Post

I have a web api developed. I need to pass an array of objects
[{"Id":"10010","lati":"12.991845763535506","longi":"77.54596710205078","PSID":"1001"},
{"Id":"10011","lati":"12.97846402705198","longi":"77.55729675292969","PSID":"1001"},
{"Id":"10012","lati":"12.967758119178907","longi":"77.54425048828125","PSID":"1001"}]
The model class of web api is given below
Locate.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace webapi.Models
{
public class Locate
{
[Key][Required]
public string Id { get; set; }
public string lati { get; set; }
public string longi { get; set; }
public string PSID { get; set; }
}
}
and the code corresponding to post method in controller file is given below
LocatesController.cs
// POST: api/Locates
[ResponseType(typeof(Locate))]
public async Task<IHttpActionResult> PostLocate(Locate locate)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Locates.Add(locate);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (LocateExists(locate.Id))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtRoute("DefaultApi", new { id = locate.Id }, locate);
}
private bool LocateExists(string id)
{
return db.Locates.Count(e => e.Id == id) > 0;
}
I send the http post request in my js script given below
app.js
$scope.adding = function()
{
var idd = $rootScope.vaar;
var datas = [];
var len = latitudes.length;
for (var i = 0; i < len; i++) {
datas.push({
"Id": idd + i.toString(),
"lati": latitudes[i].toString(),
"longi": longitudes[i].toString(),
"PSID": idd
});
}
var jsonData = angular.Json(datas);
var objectToSerialize = {'object':jsonData};
var data = $.param(objectToSerialize);
var config = {
headers: {
'Content-Type': 'application/-www-form-urlencoded;charset=utf-8'
}
}
$http.post('http://localhost:8080/pool/api/locates/', data,config).success(function (data, status, headers, config) {
alert("Success");
}).error(function (data, status, header, config) {
alert("An error has occured while adding!"+status);
});
}
It does not add the above array. Please help me
the problem is here:
[ResponseType(typeof(Locate))]
public async Task<IHttpActionResult> PostLocate(Locate locate)
and you are posting an array so it should be:
[ResponseType(typeof(Locate))]
public async Task<IHttpActionResult> PostLocate(List<Locate> locates)
The problem is solved. I changed the parameter to (List<Locate> locates) and made a logic inside post method. Thank you Glenn Packer

AngularJS ngResource POST object is Null in C# Web API

My problem is that when I send a complete Javascript object to my Web API Controller I always get null values. Even though I have a complete object I need to specify each attribute and value as you can see below. How can I make Web API accept a ready made Javascript object and bind it correctly?
C# Web Api Controller:
[Route("addcredentials/{salesId}")]
[HttpPost]
public IHttpActionResult AddCredentials([FromUri] int salesId, [FromBody] ScriveCredentials credentials)
{
return Ok(credentials);
}
C# Credentials object:
public class Credentials
{
public string ClientIdentifier { get; set; }
public string ClientSecret { get; set; }
public string TokenIdentifier { get; set; }
public string TokenSecret { get; set; }
}
Javascript object passed to resource, saved as "result" further down:
{ClientIdentifier: "a", ClientSecret: "b", TokenIdentifier: "c", TokenSecret: "d"}
Resource method:
addCredentials: {
method: 'POST',
url: 'api/addcredentials/:userSalesId'
}
Usage that results in null values:
userResource.addCredentials({ userSalesId: user.SalesId }, { credentials: result}).$promise.then(function (data) {
console.log(data);
});
Payload for this request:
{"credentials":{"ClientIdentifier":"a","ClientSecret":"b","TokenIdentifier":"c","TokenSecret":"d"}}
Usage that works but seems overly complicated:
userResource.addCredentials({ userSalesId: user.SalesId }, { ClientIdentifier: result.ClientIdentifier, ClientSecret: result.ClientSecret, TokenIdentifier: result.TokenIdentifier, TokenSecret: result.TokenSecret }).$promise.then(function (data) {
console.log(data);
});
Request payload:
{"ClientIdentifier":"a","ClientSecret":"b","TokenIdentifier":"c","TokenSecret":"d"}
Update
Tried the following and it did not work either, null on all values:
addScriveCredentials: {
method: 'POST',
url: 'api/addcredentials/'
result.SalesId = user.SalesId;
userResource.addCredentials({}, { credentials: result }).$promise.then(function (data) {
console.log(data);
});
C#:
[Route("addcredentials")]
[HttpPost]
public IHttpActionResult Addcredentials(Credentials credentials)
{
return Ok(credentials);
}
I had done a sample earlier, hope the follwing code will help you to understand.
The Model.
using System.ComponentModel.DataAnnotations;
public class ProductModel
{
public ProductModel(int id, string name, string category, decimal price)
{
Id = id;
Name = name;
Category = category;
Price = price;
}
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Category { get; set; }
[Required]
public decimal Price { get; set; }
}
The ApiController.
using Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Hosting;
using System.Web.Http;
public class ProductsController : ApiController
{
// other code omitted for brevity.
[HttpPost]
public IHttpActionResult PostProduct(ProductModel product)
{
try
{
if (product == null)
{
throw new ArgumentNullException("Product parameter cannot be null");
}
if (ModelState.IsValid)
{
// code omitted for brevity.
return this.Ok();
}
else
{
throw new Exception("Product is invalid");
}
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
[HttpPut]
public IHttpActionResult PutProduct(ProductModel product)
{
try
{
if (product == null)
{
throw new ArgumentNullException("Product parameter cannot be null");
}
if (ModelState.IsValid && product.Id > 0)
{
// code omitted for brevity.
return this.Ok();
}
else
{
throw new Exception("Product is invalid");
}
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
// other code omitted for brevity.
}
The Angular service.
// products.js
(function () {
"use strict";
angular
.module("exampleApp")
.constant("baseUrl", "http://localhost:53631/api/products/")
.factory("productsResource", productsResource);
productsResource.$inject = ["$resource", "baseUrl"];
function productsResource($resource, baseUrl) {
return $resource(baseUrl + ":id",
{
id: "#id"
},
{
create: {
method: "POST"
},
save: {
method: "PUT"
}
});
}
})();
The Angular controller. Focus on createProduct and updateProduct functions below
// edit.controller.js
(function () {
"use strict";
angular
.module("exampleApp")
.controller("EditController", EditController);
EditController.$inject = ["$routeParams", "$location", "productsResource"];
function EditController($routeParams, $location, productsResource) {
var vm = this;
vm.currentProduct = null;
vm.createProduct = createProduct;
vm.updateProduct = updateProduct;
vm.saveEdit = saveEdit;
vm.cancelEdit = cancelEdit;
if ($location.path().indexOf("/edit/") === 0) {
var id = $routeParams.id;
productsResource.get({ id: id }, function (data) {
vm.currentProduct = data;
});
}
function cancelEdit() {
$location.path("/list");
}
function updateProduct(product) {
product.$save().then(function () {
$location.path("/list");
});
}
function saveEdit(product) {
if (angular.isDefined(product.id)) {
vm.updateProduct(product);
} else {
vm.createProduct(product);
}
vm.currentProduct = {};
}
function createProduct(product) {
new productsResource(product).$create().then(function (newProduct) {
$location.path("/list");
});
}
}
})();
You could pass one object as the body of the post message instead.
Add a class like this
public class addCredentialObj
{
public int salesId { get; set; }
public Credentials credentials { get; set; }
}
Modify your controller like this (The use of FromBody can be read here)
[Route("addcredentials")]
[HttpPost]
public IHttpActionResult AddCredentials([FromBody]addCredentialObj obj)
{
return Ok(credentials);
}
In the client you need to create a matching json object to the addCredentialObj class
var yourCredentials = {"ClientIdentifier":"a","ClientSecret":"b","TokenIdentifier":"c","TokenSecret":"d"};
var jsonData = {
salesId: yourId,
credentials: yourCredentials
};
And then in the $http request to the controller, stringify the json object
$http({
method: 'POST',
url: 'api/addcredentials',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
},
data: JSON.stringify(jsonData),
});

Send array to ASP.NET from jquery and work with It

I have en array that looks like this:
[Object { OldData="(3) Lindrigt skadad", NewData="(9) Uppgift saknas", AccidentNumber=1173590}]
I make a Jquery-post as below to ASP.NET:
$.ajax({
type: "POST",
url: DataReview.BASE + "/UOS/SaveUOSChangeLog",
data: postData,
success: function (data) {
//alert(data.Result);
},
dataType: "json",
traditional: true
});
Here Is my controller:
public ActionResult SaveUOSChangeLog(List<String> values)
{
try
{
var fish = Json(new { Data = values });
return Json(new { Result = "True", ResultData = values }, JsonRequestBehavior.AllowGet);
}
catch(Exception e)
{
return Json(new { Result = "Fail", Message = "Faaaaaail" }, JsonRequestBehavior.AllowGet);
}
}
When I debug this, the value of values is [0] = "[object Object]"
How can I access the actually values from the array?
EDIT:
I have created the following model:
public class UOSChangeLogFrontEnd
{
public int AccidentNumber { get; set; }
public string OldData { get; set; }
public string NewData { get; set; }
public int Action { get; set; }
}
An my controller looks like this:
public ActionResult SaveUOSChangeLog(List<UOSChangeLogFrontEnd> values)
{
try
{
var fish = Json(new { Data = values });
return Json(new { Result = "True", ResultData = values }, JsonRequestBehavior.AllowGet);
}
catch(Exception e)
{
return Json(new { Result = "Fail", Message = "Faaaaaail" }, JsonRequestBehavior.AllowGet);
}
}
But the value count Is 0 when I debug.
Create a model like this, instead of using String as a model.
public class AccidentModel
{
public int AccidentNumber { get; set; }
public string OldData { get; set; }
public string NewData { get; set; }
}
Then used it in your action like this:
public ActionResult SaveUOSChangeLog(AccidentModel accident)
{
//..use your model
}
Try this:
Model:
public class Object
{
public string OldData { get; set; }
public string NewData { get; set; }
public string AccidentNumber { get; set; }
}
public class RootObject
{
public Object Object { get; set; }
}
Controller:
public ActionResult SaveUOSChangeLog(List<RootObject> values)
JavaScript:
[{
"Object": {
"OldData": "(3) Lindrigt skadad",
"NewData": "(9) Uppgift saknas",
"AccidentNumber": "1173590"
}
}]

Categories