ASP.NET Core post data not serealize custom field - c#

I am using ASP.NET Core 3.1 and angular.
I send a post request from the object model to the controller method.
The controller method accepts an object at the input, but the bindingParameters field is empty.
The bindingParameters field is a list of KeyValueItem objects.
TmObject.cs
namespace v1.Atm
{
public class TmObject
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("binding")]
public string Binding { get; set; }
[JsonProperty("sourceBindingParameters")]
public string SourceBindingParameters { get; set; }
[NotMapped]
[JsonProperty("bindingParameters")]
public List<TmKeyValueItem> BindingParameters
{
get
{
return JsonConvert.DeserializeObject<List<TmKeyValueItem>>(string.IsNullOrEmpty(SourceBindingParameters) ? "" : SourceBindingParameters);
}
set
{
SourceBindingParameters = JsonConvert.SerializeObject(value);
}
}
[JsonProperty("caption")]
public string Caption { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonIgnore]
public string SourceParameterGroups { get; set; }
[NotMapped]
[JsonProperty("parameterGroups")]
public List<string> ParameterGroups
{
get
{
return JsonConvert.DeserializeObject<List<string>>(string.IsNullOrEmpty(SourceParameterGroups) ? "" : SourceParameterGroups);
}
set
{
SourceParameterGroups = JsonConvert.SerializeObject(value);
}
}
[NotMapped]
[JsonProperty("parameters")]
public List<TmObjectParameter> Parameters;
[NotMapped]
[JsonProperty("removeParameters")]
public List<int> RemoveParameters { get; set; }
public TmObject()
{
Parameters = new List<TmObjectParameter>();
RemoveParameters = new List<int>();
}
}
}
If the bindingParameters field is changed, it works:
[NotMapped]
[JsonProperty("bindingParameters")]
public List<BindingParameter> BindingParameters{ get; set; }
Tell me, please, what could be the problem?
P.S. Prior to this, the project was implemented on ASP.NET Webforms and there the code described above worked.
update
I got out of the problem as follows. Opened the SourceBindingParameters field for visibility on the client by adding [JsonProperty ("sourceBindingParameters")]. And before sending data to the server, I serialize the values from BindingParameters to sourceBindingParameters.
public updateTmObject(tmObject: TmObject) {
tmObject.sourceBindingParameters = JSON.stringify(tmObject.bindingParameters);
return this.httpService.post('/v1/Editor/UpdateObject', JSON.stringify(tmObject.bindingParameters), this.httpOptions).subscribe(
(response: any) => {
this.reset();
this.getTmObjects();
return true;
},
error => {
console.error("TmObjects|TmObjectsService.updateTmObject(): " + error.status);
}
);
}

The bindingParameters from request is not a list of string values but complex objects. You'd better create a class for this objects
public class BindingParameter
{
public int Id { get; set; }
public string Key { get; set; }
public string Value { get; set; }
public bool Visible { get; set; }
}
and declare the property as the following
public List<BindingParameter> BindingParameters{ get; set; }

Related

Validation of Class with FluentValidation returning object is required for non-static field

I am trying to add FluentValidator to my .net core 3.1 Worker Service. I created a class that will hold my CSV parsed files.
public partial class Subjects
{
public Guid SubjectId { get; set; }
public string Code { get; set; }
public Guid OrganizationId { get; set; }
public string PreferredName { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
public string Gender { get; set; }
public string LastNameInitial { get; set; }
public string CodeDisplay { get; set; }
public Guid? RaceId { get; set; }
public Guid? MaritalStatusId { get; set; }
public Guid? StatusId { get; set; }
public string Rank { get; set; }
public string Email { get; set; }
public string MobilePhone { get; set; }
public bool MobilePhoneDoNotLeaveMsg { get; set; }
public bool MobilePhoneDoNotText { get; set; }
public string WorkPhone { get; set; }
public bool WorkPhoneDoNotLeaveMsg { get; set; }
}
Then according to the documentation, I create the Validation class implementing the AbstractValidator interface:
class SubjectsValidation : AbstractValidator<Subjects>
{
public SubjectsValidation()
{
RuleFor(subject => Subjects.FirstName).NotEmpty();
}
}
According to the documentation, I need to add the rules in the constructor. However, when I pass in the lambda for the rule I got this error:
"An object reference is required for non-static field, method, or
property"
So I modified the constructor like this:
class SubjectsValidation : AbstractValidator<Subjects>
{
public SubjectsValidation()
{
Subjects subject = new Subjects();
RuleFor(x=>subject.FirstName).NotEmpty();
}
}
Which got of the error, but when I try to call the validation I get an error when I instantiate the object for testing:
Subjects subject = new Subjects();
subject.FirstName = "John";
SubjectsValidation validator = SubjectsValidation();
This returns a failed message because I had to create a new subject in the Subject Validation so it return a failure. So following the instructions on the website, I just can't get this working. How do I fix this?
The RuleFor method is expecting a delegate. So your first attempt will work if you use the parameter of the delegate within the body (subject instead of Subjects):
class SubjectsValidation : AbstractValidator<Subjects>
{
public SubjectsValidation()
{
RuleFor(subject => subject.FirstName).NotEmpty();
}
}

Convert Rest API JSON Response into C# object

I have a code REST API response which is json, and parsing to JObject and pulling a value from it. But i am getting the error when parsing to JObject.
Error: "Unexpected character encountered while parsing value: S. Path '', line 0, position 0."
Is there any other way to convert Json string to C# object.
I have the following code:
using Newtonsoft.Json;
using (HttpResponseMessage message = httpclient.GetAsync(folderIdURL).Result)
{
if(message.IsSuccessStatusCode)
{
var dataobjects = message.Content.ReadAsStringAsync();
//dataobjects = "{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/","title":"DQL query results","author":[{"name":"EMC Documentum"}],"updated":"2019-05-02T15:19:52.508+00:00","page":1,"items-per-page":100,"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)"}],"entries":[{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)&index=0","title":"0b0111738011c114","updated":"2019-05-02T15:19:52.508+00:00","published":"2019-05-02T15:19:52.508+00:00","links":[{"rel":"edit","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c114"}],"content":{"json-root":"query-result","definition":"https://gbc-dev5.cloud.wc.com/DctmRest/repositori es/dmgbsap_crt/types/dm_sysobject","properties":{"r_object_id":"0b0111738011c114","object_name":"04"},"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c114"}]}},{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)&index=1","title":"0b0111738011c115","updated":"2019-05-02T15:19:52.509+00:00","published":"2019-05-02T15:19:52.509+00:00","links":[{"rel":"edit","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c115"}],"content":{"json-root":"query-result","definition":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/types/dm_sysobject","properties":{"r_object_id":"0b0111738011c115","object_name":"05"},"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c115"}]}}]}"
JObject responseObj = JObject.Parse(dataobjects.ToString());
String id = (String)responseObj["entries" -->"content"-->"properties"-->"object_name"];
}
}
}
I am expecting the value from (String)responseObject["enteries"]["content"][" properties"]["object_name"]
JObjects are a pain. You could get a sample of the JSON response and paste it into a converter like json2csharp.com. It will generate a class for you which you can then use like so:
Generated Class:
public class MyClass
{
public string SomeProperty { get; set; }
public string AnotherProperty { get; set; }
}
Usage:
if (message.IsSuccessStatusCode)
{
var deserializedObject = JsonConvert.DeserializeObject<MyClass>(response.Content.ReadAsStringAsync().Result);
Console.WriteLine(deserializedObject.SomeProperty);
}
I would suggest to follow those steps:
You need to check that your json is actually a json, because an error says it is not. You can use online tools like this
If possible, avoid JObject and generate real classes. It is not that hard if you know the structure, and you can use another online tools
Modify your code to use classes
so you will have something like:
using System;
using Newtonsoft.Json;
namespace ConsoleApp11
{
class Program
{
public class Message
{
public Enteries enteries { get; set; }
}
public class Enteries
{
public Content content { get; set; }
}
public class Content
{
public Properties properties { get; set; }
}
public class Properties
{
public string object_name { get; set; }
}
static void Main(string[] args)
{
var input = "{\"enteries\":{\"content\":{ \"properties\":{ \"object_name\":\"your value string\"}}}}";
Message msg = JsonConvert.DeserializeObject<Message>(input);
Console.WriteLine(msg?.enteries?.content?.properties?.object_name ?? "no value");
Console.ReadKey();
}
}
}
I hope it helps 😊
Thank you so much for all the help and trips. Finally i am able to get the required value from JSON string.
Here is the Final code json2csharp.com
public class Author
{
public string name { get; set; }
}
public class Link
{
public string rel { get; set; }
public string href { get; set; }
}
public class Link2
{
public string rel { get; set; }
public string href { get; set; }
}
public class Properties
{
public string r_object_id { get; set; }
public string object_name { get; set; }
}
public class Link3
{
public string rel { get; set; }
public string href { get; set; }
}
public class Content
{
public string json_root { get; set; }
public string definition { get; set; }
public Properties properties { get; set; }
public List<Link3> links { get; set; }
}
public class Entry
{
public string id { get; set; }
public string title { get; set; }
public DateTime updated { get; set; }
public DateTime published { get; set; }
public List<Link2> links { get; set; }
public Content content { get; set; }
}
public class RootObject
{
public string id { get; set; }
public string title { get; set; }
public List<Author> author { get; set; }
public DateTime updated { get; set; }
public int page { get; set; }
public int items_per_page { get; set; }
public List<Link> links { get; set; }
public List<Entry> entries { get; set; }
}
Using Newtonsoft.Json
First get the list of entries from the responseObj. Then loop each entries and use LINQ to JSON to get values by property name or index.
You can use Item[Object] index on JObject/JArray and then cast the returned JValue to the type you want
JObject responseObj = JObject.Parse(dataobjects.ToString());
// get JSON result objects into a list
IList<JToken> entries = responseObj ["entries"].Children().ToList();
foreach(JToken entry in entries)
{
string object_name = (string) entry["content"]["properties"]["object_name"];
}

Unable to deserialize JSON in c#

I am getting the below JSON in response from a REST API.
{
"data":{
"id":123,
"zoneid":"mydomain.com",
"parent_id":null,
"name":"jaz",
"content":"172.1 6.15.235",
"ttl":60,
"priority":null,
"type":"A",
"regions":[
"global"
],
"system_record":false,
"created_at":"2017-09-28T12:12:17Z",
"updated_at":"2017-09-28T12:12:17Z"
}
}
and trying to resolve using below code but that doesn't result in a correctly deserialized type.
var model = JsonConvert.DeserializeObject<ResponseModel>(response);
below is a class according the field I received in JSON response.
public class ResponseModel
{
public int id { get; set; }
public string zone_id { get; set; }
public int parent_id { get; set; }
public string name { get; set; }
public string content { get; set; }
public int ttl { get; set; }
public int priority { get; set; }
public string type { get; set; }
public string[] regions { get; set; }
public bool system_record { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
}
What is missing?
You're missing a wrapper class.
public class Wrapper
{
public ResponseModel data {get;set}
}
and then do:
var model = JsonConvert.DeserializeObject<Wrapper>(response).data;
to get the instance of your ResponseModel out the data property.
You can deduct this from your json:
{ "data":
{ "id":123, /*rest omitted */ }
}
The type that will receive this JSON needs to have a property named data. The suggested Wrapper class acts as that type.
According to json2csharp website, your model seems to be incorrect. Try this one :
public class ResponseModel
{
public int id { get; set; }
public string zoneid { get; set; }
public object parent_id { get; set; }
public string name { get; set; }
public string content { get; set; }
public int ttl { get; set; }
public object priority { get; set; }
public string type { get; set; }
public List<string> regions { get; set; }
public bool system_record { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
}
public class RootObject
{
public ResponseModel data { get; set; }
}
Here a cool trick you can do in Visual Studio 2015-2017 where it generates the the correct class if you just copy the JSON (ctrl + c).
You need to create a new class in visual studio and once inside the class go to Edit menu -> Paste special -> paste JSON As Classes.
Steps to generate json class
This will generate the C# object for that json for you and save you all the hassle :)
Your model does not match your response - it matches the data property. Simply wrap another object round it
public class ResponseData
{
public ResponseModel Data {get; set; {
}
and then
var model = JsonConvert.DeserializeObject<ResponseData>(response);

How to send list of object to webapi c#?

I'm trying to send a list of objects to webapi in json-array format. But, in the parameter its getting null.
Now, let me post the code that i have tried so far
[HttpPost]
[Route("~/api/visitsave")]
public IHttpActionResult Save(List<VisitDataModel> visitobj)
{
foreach (VisitDataModel visitobjs in visitobj) {
VisitManager obj = new VisitManager(visitobjs);
bool value = obj.Save();
}
return Ok();
}
This is the json-array I'm trying to pass, but it is not working in the parameter visitobj.
Its receiving null. As I'm new to webapi and c#, I'm struggling with this.
But when i pass single json object I'm getting values and when i switched back to list, it's not working.
Let me post the json array that am trying to post:
{"visitobj":[{"Remarks":"test","UserID":193,"FindingsAtSite":"nothing","CheckInDate":"2017-02-01 12:00:00","CheckOutDate":"2017-02-01 12:00:00","VisitStatusID":1,"CreatedBy":192,"CreatedDateTime":"2017-02-01 12:00:00","Claim":{"TransportMode":1,"Date":"2017-02-01 12:00:00","FromLocation":"chennai","ToLocation":"re","Ticket":123.2,"Conveyance":123.5,"Lodge":234.0,"Meals":23}}]}
This is the jsonresponse am trying to send to my webapi can someone helpme out this may be dumb question but am struggling with this. Thanks in advance!!
May be you are passing json in wrong format. I have an API action like this
[HttpPost]
[Route("sample")]
public IHttpActionResult SampleOp(List<SampleObj> smpJson)
{
foreach (var item in smpJson){
//Do Some Thing Here
}
return ok();
}
And passing the json data as
[{
"name":"name 1",
"address":"address 1",
"age":1
},
{
"name":"name 2",
"address":"address 2",
"age":2
}]
Here is my SampleObj modal
public class SampleObj {
public string name { get; set; }
public string address { get; set; }
public int age { get; set; }
}
It is tested and working here
This is a normal behavior since your contract does not match.
Change your parameters to the following and your argument will be ok
public class Claim
{
public int TransportMode { get; set; }
public string Date { get; set; }
public string FromLocation { get; set; }
public string ToLocation { get; set; }
public double Ticket { get; set; }
public double Conveyance { get; set; }
public double Lodge { get; set; }
public int Meals { get; set; }
}
public class Visitobj
{
public string Remarks { get; set; }
public int UserID { get; set; }
public string FindingsAtSite { get; set; }
public string CheckInDate { get; set; }
public string CheckOutDate { get; set; }
public int VisitStatusID { get; set; }
public int CreatedBy { get; set; }
public string CreatedDateTime { get; set; }
public Claim Claim { get; set; }
}
public class VisiteRequest
{
public List<Visitobj> visitobj { get; set; }
}
Or the second option you have to change the Json sent object as an array
[{"Remarks":"test","UserID":193,"FindingsAtSite":"nothing","CheckInDate":"2017-02-01 12:00:00","CheckOutDate":"2017-02-01 12:00:00","VisitStatusID":1,"CreatedBy":192,"CreatedDateTime":"2017-02-01 12:00:00","Claim":{"TransportMode":1,"Date":"2017-02-01 12:00:00","FromLocation":"chennai","ToLocation":"re","Ticket":123.2,"Conveyance":123.5,"Lodge":234.0,"Meals":23}}]

JSON.NET deserialize results in list with default values

Am I missing something obvious here? JSON:
{"p":[{},{"clientId":102102059663,"checkbox1Ticked":false,"checkbox2Ticked":false},{"clientId":23841,"checkbox1Ticked":false,"checkbox2Ticked":false},{"clientId":102102111426,"checkbox1Ticked":false,"checkbox2Ticked":false}]}
C#: (checkboxData is the string above)
public JsonResult SubmitSelectedChanges(string checkboxData)
{
var deserializedClients = JsonConvert.DeserializeObject<ChangeList>(checkboxData);
return null;
}
public class ChangeList
{
public List<Change> p { get; set; }
}
public class Change
{
string clientId { get; set; }
bool checkbox1Ticked { get; set; }
bool checkbox2Ticked { get; set; }
}
After deserializing the clientId is always null and the checbox1Ticked and checkbox2Ticked is false.
It was because I had forgotten the access modifiers for the change class:
public class Change
{
public string clientId { get; set; }
public bool checkbox1Ticked { get; set; }
public bool checkbox2Ticked { get; set; }
}
I would have thought this would have thrown an exception.

Categories