Json Value doesn't assign to the List [HttpPost] - c#

Since am new to web api, i am finding some difficulty to post json List to Web API.
Json
[
{
"ItemId":20,
"RegId":"VISIT0001778",
"BLoadDetailId":"8/31/2018 12:28:10 PM",
"OrderReferenceNo":null,
"StartTime":"0001-01-01T00:00:00",
"InvalidItemMsg":"",
"InvalidItemstatus":false,
"BLoadingBay":"Chute 009",
"BLoadingBayCode":null,
"BLoadingBayID":7,
"RFID":7123,
"GangId":2,
"BOrderTransfer":false,
"BLoadedBags":0.0,
"BRemainingBags":0.0,
"BConversionValue":null,
"WHid":2
}
]
class :
public class clsStartTimeUpdate
{
public int ItemId { get; set; }
public string RegId { get; set; }
public string BLoadDetailId { get; set; }
public string OrderReferenceNo{ get; set; }
public DateTime StartTime { get; set; }
public string InvalidItemMsg { get; set; }
public bool InvalidItemstatus { get; set; }
public string BLoadingBay { get; set; }
public string BLoadingBayCode { get; set; }
public int? BLoadingBayID { get; set; }
public long? RFID { get; set; }
public int? GangId { get; set; }
public bool BOrderTransfer { get; set; }
public decimal BLoadedBags { get; set; }
public decimal BRemainingBags { get; set; }
public string BConversionValue { get; set; }
public int? WHid { get; set; }
}
Json request
http://localhost:49290/api/config/Post?StartTimeDetails=[enter image description here][1][{%22ItemId%22:20,%22RegId%22:%22VISIT0001778%22,%22BLoadDetailId%22:%228/31/2018%2012:28:10%20PM%22,%22OrderReferenceNo%22:null,%22StartTime%22:%222001-01-01T00:00:00%22,%22InvalidItemMsg%22:%22%22,%22InvalidItemstatus%22:false,%22BLoadingBay%22:%22Chute%20009%22,%22BLoadingBayCode%22:null,%22BLoadingBayID%22:7,%22RFID%22:7123,%22GangId%22:2,%22BOrderTransfer%22:false,%22BLoadedBags%22:0.0,%22BRemainingBags%22:0.0,%22BConversionValue%22:null,%22WHid%22:2}]
Method WebAPI
[HttpPost]
public HttpResponseMessage Post([FromUri]List<clsStartTimeUpdate> StartTimeDetails)
{
return base.BuildSuccessResult(HttpStatusCode.OK, StartTimeDetails);
}
result:
[{"ItemId":0,"RegId":null,"BLoadDetailId":null,"OrderReferenceNo":null,"StartTime":"0001-01-01T00:00:00","InvalidItemMsg":null,"InvalidItemstatus":false,"BLoadingBay":null,"BLoadingBayCode":null,"BLoadingBayID":null,"RFID":null,"GangId":null,"BOrderTransfer":false,"BLoadedBags":0.0,"BRemainingBags":0.0,"BConversionValue":null,"WHid":null}]
return result doesnot assign the values as in the Json.
May be this is a simple situation , but i really appreciate the help.

It seems that you want to convey your json with HttpGet request instead of HttpPost then you can follow below,
1) Send Json with HttpGet
Method: Get
Url: http://localhost:49290/api/config/MyGet?StartTimeDetails=[{%22ItemId%22:20,%22RegId%22:%22VISIT0001778%22,%22BLoadDetailId%22:%228/31/2018%2012:28:10%20PM%22,%22OrderReferenceNo%22:null,%22StartTime%22:%220001-01-01T00:00:00%22,%22InvalidItemMsg%22:%22%22,%22InvalidItemstatus%22:false,%22BLoadingBay%22:%22Chute%20009%22,%22BLoadingBayCode%22:null,%22BLoadingBayID%22:7,%22RFID%22:7123,%22GangId%22:2,%22BOrderTransfer%22:false,%22BLoadedBags%22:0.0,%22BRemainingBags%22:0.0,%22BConversionValue%22:null,%22WHid%22:2}]
Web Api Method:
[HttpGet]
public HttpResponseMessage MyGet(string StartTimeDetails)
{
List<clsStartTimeUpdate> clsStartTimeUpdates = JsonConvert.DeserializeObject<List<clsStartTimeUpdate>>(StartTimeDetails);
return base.BuildSuccessResult(HttpStatusCode.OK, StartTimeDetails);
}
Note: Its bad practice to send huge json in query string, so for use HttpPost instead
2) Send Json with HttpPost
Method: Post
Url: http://localhost:49290/api/config/MyPost
Data:
[
{
"ItemId":20,
"RegId":"VISIT0001778",
"BLoadDetailId":"8/31/2018 12:28:10 PM",
"OrderReferenceNo":null,
"StartTime":"0001-01-01T00:00:00",
"InvalidItemMsg":"",
"InvalidItemstatus":false,
"BLoadingBay":"Chute 009",
"BLoadingBayCode":null,
"BLoadingBayID":7,
"RFID":7123,
"GangId":2,
"BOrderTransfer":false,
"BLoadedBags":0.0,
"BRemainingBags":0.0,
"BConversionValue":null,
"WHid":2
}
]
Web Api Method:
[HttpPost]
public HttpResponseMessage MyPost([FromBody]List<clsStartTimeUpdate> StartTimeDetails)
{
return base.BuildSuccessResult(HttpStatusCode.OK, StartTimeDetails);
}

For complex types Always use [FromBody] in the argument.
[HttpPost]
public HttpResponseMessage Post([FromBody]List<clsStartTimeUpdate> StartTimeDetails)
{
return base.BuildSuccessResult(HttpStatusCode.OK, StartTimeDetails);
}
And then specify your query object in Body.
Note: To specify the value in the body, You will need an API client like Postman or Swagger.
https://www.getpostman.com/
In Postman,
Select Post method and specify the URL,
Then go to "Body" tab and select raw.
Specify JSON as type.
In the body, paste your data.
{ [
{
"ItemId":20,
..........
}
]}
The Other answer by #ershoaib is the real fix for the problem that OP is facing. However, I am leaving this answer as it is the standard which should be followed.

Since you are using post you should expect the data in the controller method to come from body. See related issue here

Related

.NET Core API REST C# List into List is null

I'm developing an api in net core.
I've done a post function in which I send an object containing multiple parameters and a list within another list.
When I'm debugging the code the function is called correctly but I find that the second list always arrives null.
The rest of the data arrives at you correctly. I have done different tests with other objects and everything works correctly.
It is this case in which the list within another the second one arrives null.
My code:
example request input
{
"Name": "TestName",
"Related1":
[{
"id1": "TestNameRelated1",
"Related2":
[{
"id2": "TestNameRelated2"
}]
}]
}
[HttpPost]
public resultExample Test([FromBody]TestClass test)
{
//do something
}
[DataContract]
public class TestClass
{
[DataMember]
public string Name { get; set; }
[DataMember]
public List<TestClassArray> Related1 { get; set; }
}
[DataContract]
public class TestClassArray
{
[DataMember]
public string id1 { get; set; }
[DataMember]
public List<TestClassArray2> Related2 { get; set; }
}
[DataContract]
public class TestClassArray2
{
[DataMember]
public string id2 { get; set; }
}
This api was previously made in .NET framework 4.8 and this case worked correctly.
Now I'm passing the api to .Net5.
Could it be that in .Net5 it is not allowed to pass lists within other lists?
Do you have to enable some kind of configuration to be able to do this now?
You need use class/DTO with constructor like shown below and you should be good to go. I have uploaded this sample API app's code working with .net5.0 on my GitHub here.
public class TestClass
{
public TestClass()
{
Related1 = new List<TestClassArray>();
}
public string Name { get; set; }
public List<TestClassArray> Related1 { get; set; }
}
public class TestClassArray
{
public TestClassArray()
{
Related2 = new List<TestClassArray2>();
}
public string id1 { get; set; }
public List<TestClassArray2> Related2 { get; set; }
}
public class TestClassArray2
{
public string id2 { get; set; }
}
public class ResultExample
{
public string StatusCode { get; set; }
public string Message { get; set; }
}
Controller Post Method
[HttpPost]
[ProducesResponseType(typeof(ResultExample), 200)]
public ResultExample Post([FromBody] TestClass test)
{
ResultExample testResult = new ResultExample();
TestClass test2 = new TestClass();
TestClassArray testClassArray = new TestClassArray();
TestClassArray2 testClassArray2 = new TestClassArray2();
test2.Name = test.Name;
foreach (var item in test.Related1)
{
foreach (var item2 in item.Related2)
{
testClassArray2.id2 = item2.id2;
}
testClassArray.Related2.Add(testClassArray2);
}
test2.Related1.Add(testClassArray);
Console.WriteLine(test2);
testResult.Message = "New Result added successfullly....";
testResult.StatusCode = "201";
return testResult;
}
Swagger Input Sample Payload
Post Controller Result
Response of Sample input payload,(You can change it to default 201 response code as well)
I had a similar issue.
API method shows List was null
In my case a date field was not well formatted
So I use SimpleDateFormat on Android Studio with a correct datetime format
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss",Locale.US);
item.setDate(dateFormat.format(calendar.getTime()));
and works fine

Asp.NetCore API Controller not getting Data from Json

I have 2 applications, one which posts data to another. When I run the first application the post method in the controller executes but the model or ObjavaDto (objaveList) can't be found so it's null. When I copy-paste the json from var json into Postman everything works. What am I missing?
var json = new JavaScriptSerializer().Serialize(objaveList[2]);
I used [2] just for simplicity reasons because there are a lot of them
string url = "http://localhost:61837/api/Objave";
string result;
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/json");
result = client.UploadString(url, "POST", json);
}
2nd application Controller
namespace StecajeviInfo.Controllers.Api
{
[Route("api/[controller]")]
public class ObjaveController : Controller
{
[HttpPost]
public void Post([FromBody]ObjavaDto objaveList)
{
}
}
}
public class ObjavaDto
{
public string OznakaSpisa { get; set; }
public string NazivOtpravka { get; set; }
public string NazivStecajnogDuznika { get; set; }
public string PrebivalisteStecajnogDuznika { get; set; }
public string SjedisteStecajnogDuznika { get; set; }
public string OIBStecajnogDuznika { get; set; }
public string OglasSeOdnosiNa { get; set; }
public DateTime DatumObjave { get; set; }
public string OibPrimatelja { get; set; }
public string Dokument { get; set; }
}
Sent data looks like this
{
"OznakaSpisa":"St-6721/2015",
"NazivOtpravka":"Rješenje - otvaranje stečajnog postupka St-6721/2015-7",
"NazivStecajnogDuznika":"RAIN AIR d.o.o.",
"PrebivalisteStecajnogDuznika":"Savska 144/A, 10000, Zagreb",
"SjedisteStecajnogDuznika":"",
"OIBStecajnogDuznika":‌​"37144498637",
"Oglas‌​SeOdnosiNa":"Missing Oib",
"DatumObjave":"\/Date(1501106400000)\/",
"OibPrimatelja"‌​:"37144498637",
"Doku‌​ment":"e-oglasna.pra‌​vosudje.hr/sites/def‌​ault/files/ts-zg-st/‌​…;"
}
Thank you all for your replies, you have been very helpful and gave me an idea how to test. I tested with commenting out properties and I found out it's because of the special characters in Naziv otpravka ("Rješenje" and "stečajnog") which are luckily present only in that property.
I found that this solved the problem https://stackoverflow.com/a/12081747/6231007
client.Headers["Content-Type"] = "application/json; charset=utf-8";
client.UploadDataAsync(new Uri(url), "POST",
Encoding.UTF8.GetBytes(json));
Datetime is problematic. Make it nullable (DateTime?) and test with that. You'll probably get all other properties filled and datetime will stay null. If that's the problem, make sure your client sends datetime format that your model binder understands.

webapi not recognize json list

I've got a list of objects in JSON that isn't recognized by a WebApi2 controller
The JSON list is the following:
{
"FirstObjectType": [{"Name": "the_name"}],
"SecondObjectType": [{"Label": "01_obj"}, {"Label": "02_obj"}]
}
The Model class is:
public class CompositeObject
{
[JsonProperty("FirstObjectType")]
public List<FirstObject> fo { get; set; }
[JsonProperty("SecondObjectType")]
public List<SecondObject> so { get; set; }
}
The controller is:
public IHttpActionResult PostList([FromBody] CompositeObject jsonList)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
List<FirstObject> fo_list = jsonList.fo;
foreach (var item in fo_list)
{
db.FirstObject.Add(item);
db.SaveChanges();
}
return StatusCode(HttpStatusCode.OK);
}
When I submit the Post action, the controller recognize both lists in CompositeObject jsonList as Null
There is a problem in your model, where names are not being matched. You have to update model as:
public class FirstObjectType
{
public string Name { get; set; }
}
public class SecondObjectType
{
public string Label { get; set; }
}
public class RootObject
{
public List<FirstObjectType> FirstObjectType { get; set; }
public List<SecondObjectType> SecondObjectType { get; set; }
}
I have assumed that FirstObjectType contains string with name Name and SecondObjectType contains string with name Label. Make sure to use same names for properties of FirstObjectType and SecondObjectType class as in JSON string.
The issue was in the client code because I missed to set the Content-type as application/json in the header section.
In this way the WebApi server doesn't recognize in the right way the JSON object (I think that the server look for a x-www-form-urlencoded type)
So, the code above is right, but I have found another solution
In the WebApi controller:
using Newtonsoft.Json.Linq;
public IHttpActionResult PostList([FromBody] JObject ReceivedObjectsList)
{
var receivedLists = ReceivedObjectsList.Properties();
List<FirstObject> fo = ReceivedObjectsList["FirstObjectType"].ToObject<List<FirstObject>>();
List<SecondObject> so = ReceivedObjectsList["SecondObjectType"].ToObject<List<SecondObject>>();
...
}

MVC WEB API Controller C# JSON Deserialize not working

I have been struggling with my first c# project. This is a web api controller that will receive a post from AngularJS. The post is coming across but appears to have an extra set of brackets in the JSON object (right click/copy value in vs 2015) . I have tried various methods but everytime I deserialize the JSON object I get null values.
public class LocationsTestController : ApiController
{
[System.Web.Http.HttpPost]
[Route("")]
public IHttpActionResult Post(object json)
{
string sjson = json.ToString();
Coords oCoords = JsonConvert.DeserializeObject<Coords>(sjson);
DBEntities db = new DBEntities();
db.spUpdateLocation(User.Identity.Name, oCoords.latitude.ToString(), oCoords.longitude.ToString());
db.SaveChanges();
return Ok(oCoords.latitude); //return trash data for now
}
}
Here is my JSON copied from the the object received by the post.
{{
"coords": {
"latitude": 43.445969749565833,
"longitude": -80.484091512936885,
"altitude": 100,
"accuracy": 150,
"altitudeAccuracy": 80,
"heading": 38,
"speed": 25
},
"timestamp": 1442113213418
}}
I have tried mapping to the entity framework, but problem is I need to add the authenticated username to the json object as I don't want to trust what is being passed to the API.
Any help would be much appreciated.
Try to receive a model instead of plain string in your WebApi method:
public class CoordsItemModel
{
public double latitude { get; set; }
public double longitude { get; set; }
public int altitude { get; set; }
public int accuracy { get; set; }
public int altitudeAccuracy { get; set; }
public int heading { get; set; }
public int speed { get; set; }
}
public class CoordsModel
{
public CoordsItemModel coords { get; set; }
public long timestamp { get; set; }
}
[System.Web.Http.HttpPost]
[Route("")]
public IHttpActionResult Post(CoordsModel model)
{
DBEntities db = new DBEntities();
db.spUpdateLocation(User.Identity.Name, model.coords.latitude.ToString(), model.coords.longitude.ToString());
db.SaveChanges();
return Ok(model.coords.latitude.ToString()); //return trash data for now
}
There might be some issues with the way you are posting from client side. It's hard to check without the client code and what exactly is coming over network (in fiddler for example).
Generally the web api should be able to get the object directly without you deserializing it. So, if the client is posting proper json, this should work
public IHttpActionResult Post(Coords oCoords)
{
//use oCoords directly
}
If that doesn't work, try changing your web api method to receive string rather than an object, and deserialize that string.
public IHttpActionResult Post(string jsonString)
{
Coords oCoords = JsonConvert.DeserializeObject<Coords>(jsonString);
//rest of the code
}
If you still have double braces, you can do this before you deserialize
jsonString = jsonString.Replace("{{", "{").Replace("}}", "}");
But, obviously, this is not the correct fix. The issue still remains somewhere.
Use It.
public class coordsSample
{
public string latitude { get; set; }
public string longitude { get; set; }
public int altitude { get; set; }
public int accuracy { get; set; }
public int altitudeAccuracy { get; set; }
public int heading { get; set; }
public int speed { get; set; }
}
public class coords1
{
public coordsSample coords { get; set; }
public long timestamp { get; set; }
}
static void Main(string[] args)
{
var jsonFormat = #"[{""timestamp"":""1442113213418"",""coords"":{
""latitude"":""43.445969749565833"",""longitude"":""-80.484091512936885"",""altitude"":""100"",""accuracy"":""150""
,""altitudeAccuracy"":""80"",""heading"":""38"",""speed"":""25""}}]";
var result = JsonConvert.DeserializeObject<coords1>(jsonFormat.Substring(1).Substring(0, jsonFormat.Length - 2));
Console.WriteLine(result.coords.latitude);
Console.WriteLine(result.coords.longitude);
}
Try Like that it will help for you.because those coords you take in json it trated as a properties so for that you need to create a new class and assign this properties in inside it.Thanks

c# WebApi OData complex type is always null in post ODataRoute

My problem is that "siteSetup" is always null for the following odata action:
[HttpPost]
[ODataRoute("Setup")]
public IHttpActionResult Setup(SiteSetup siteSetup)
{
return BadRequest("Not yet working");
}
This is my complex type
public class SiteSetup
{
public SiteSetup()
{
}
public string Username
{
get;
set;
}
public string Password
{
get;
set;
}
public string CompanyName
{
get;
set;
}
}
And this is the fiddler for a request.
Action with complextype as parameter is support in OData/WebApi V4, you may use ODataActionParameters in your controller method, you can see this page for instruction, http://odata.github.io/WebApi/#04-07-action-parameter-support

Categories

Resources