How to serialize JSON from Form (multipart/form-data) to list? - c#

When I try to post multipart/form-data with my file and JSON, then lists are empty in model, but Alias, WorkerName and File are correctly serialized.
[HttpPost]
[Route("add")]
[Consumes("multipart/form-data")]
public async Task<JobAddDto> Add([FromForm] JobInputInternalDto model)
{
var form = Request.Form;
//do stuff with model
}
In Request.Form those values are correctly sent:
How can I serialize data from form to lists in my model?
I have my JobInputInternalDto written as:
public class JobInputDto
{
public string Alias { get; set; } = string.Empty;
public string WorkerName { get; set; } = string.Empty;
public IEnumerable<ParameterDto> Parameters { get; set; } = new List<ParameterDto>();
public IEnumerable<WorkflowOptionsDto> Workflow { get; set; } = new List<WorkflowOptionsDto>();
}
public class JobInputInternalDto : JobInputDto
{
public IFormFile? Payload { get; set; } = null;
}
With ParameterDto as:
public class ParameterDto
{
public int Order { get; set; }
public string Name { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
}
And WorkflowOptionsDto as:
public class WorkflowOptionsDto
{
public int Order { get; set; }
public string WorkerName { get; set; } = string.Empty;
public string? WorkerVersion { get; set; } = null;
public IEnumerable<ParameterDto> Parameters { get; set; } = Enumerable.Empty<ParameterDto>();
}

What i can guess by your Request.Form image is that you've sent the Parameters data with Json format like:
{ Order: 0, Name: "Test Name 0", Value: "Test Value 0" }
But since you're using
[Consumes("multipart/form-data")]
As such, C# expects the model to be form formatted, and therefore a list of objects should have the following format:
As you can see in the following image, using form format, C# is able to bind the data properly:

Related

Binding JSON values in my server side is getting failed

I want to use the json values in my c# code. So I have written the code like below
public static void WriteToIEMService(string jsonValue)
{
string TimeFormatText = DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss");
string strFileCreationDate = DateTime.Now.ToString("dd/MM/yyyy");
string strFileName = ConfigurationManager.AppSettings["IEM_SERVICEFILE"].ToString();
try
{
using (StreamWriter sw = File.CreateText(ConfigurationManager.AppSettings["LogFileDirectory"].ToString() + strFileName + "_" + strFileCreationDate + ".txt"))
{
List<MasterServiceResponse> records = JsonConvert.DeserializeObject<List<MasterServiceResponse>>(jsonValue);
sw.WriteLine("IEM Service started and send data to IEM below");
foreach (MasterServiceResponse record in records)
{
sw.WriteLine(record.SapId);
}
}
}
catch (Exception)
{
throw;
}
}
But I am getting error as
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[IPColoBilling_BKP.App_Code.MasterServiceResponse]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
Please help
EDIT
My json values is as below
{"SiteData":[{"SAPId":"I-UW-SRPR-ENB-I001","SiteRFEIDate":"03-11-2014","SiteRFSDate":"03-11-2014","ID_OD":"ID","ID_ODchangeDate":"04-11-2018","NoofRRHBase":"0","RRHBaseChangeEffectiveDate":"","No_Of_Tenancy":"3","TenancyChangeEffectiveDate":"03-11-2014","SiteStatus":"Active","SiteDropDate":""}]}
UPDATE
public class MasterServiceResponse
{
public string SapId { get; set; }
public string AcknowledgementID { get; set; }
public string FlagResponse { get; set; }
public string ResponseMessage { get; set; }
public string GisStatus { get; set; }
public string GisSendDate { get; set; }
public string SiteRFEIDate { get; set; }
public string SiteRFSDate { get; set; }
public string SiteRRHDate { get; set; }
public string NoofRRHBase { get; set; }
}
Update: A stated by Panagiotis Kanavos, You are not creating Root object, so you have to restructure your models.
Don't know what your Model looks like, But this error message says your giving json object where it is expecting JSON array,
Below is the model you should be using
public class SiteData
{
public string SAPId { get; set; }
public string SiteRFEIDate { get; set; }
public string SiteRFSDate { get; set; }
public string ID_OD { get; set; }
public string ID_ODchangeDate { get; set; }
public string NoofRRHBase { get; set; }
public string RRHBaseChangeEffectiveDate { get; set; }
public string No_Of_Tenancy { get; set; }
public string TenancyChangeEffectiveDate { get; set; }
public string SiteStatus { get; set; }
public string SiteDropDate { get; set; }
}
public class RootObject
{
public List<SiteData> SiteData { get; set; }
}
You also have to change the deserializing code
E.g.
RootObject records = JsonConvert.DeserializeObject<RootObject>(jsonValue);
foreach (SiteData record in records.SiteData)
{
sw.WriteLine(record.SapId);
}
As the error mentions, you cannot deserialize JSON object to list. So instead of:
List<MasterServiceResponse> records = JsonConvert.DeserializeObject<List<MasterServiceResponse>>(jsonValue);
You should update have something like:
MyObject obj = JsonConvert.DeserializeObject<MyObject>(jsonValue);
The exception message tells you that the JSON string contains single object, but you're tried to deserialize it into List<MasterServiceResponse> collection.
You should create a class to hold List<MasterServiceResponse>:
public class SiteData
{
public List<MasterServiceResponse> MasterServiceResponse { get; set; }
}
Then you should replace this line:
List<MasterServiceResponse> records = JsonConvert.DeserializeObject<List<MasterServiceResponse>>(jsonValue);
to return single object like this:
SiteData records = JsonConvert.DeserializeObject<SiteData>(jsonValue);
Reference:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1
Because your JSON start with a key "SiteData" which has an array value, you need to create a helper class to match that structure (e.g. class SiteResponse) with a property named SiteData of type List<MasterServiceResponse>.
Code:
public class SiteResponse
{
public List<MasterServiceResponse> SiteData { get; set; }
}
private static void TestJson()
{
var jsonValue = "{\"SiteData\":[{\"SAPId\":\"I-UW-SRPR-ENB-I001\",\"SiteRFEIDate\":\"03-11-2014\",\"SiteRFSDate\":\"03-11-2014\",\"ID_OD\":\"ID\",\"ID_ODchangeDate\":\"04-11-2018\",\"NoofRRHBase\":\"0\",\"RRHBaseChangeEffectiveDate\":\"\",\"No_Of_Tenancy\":\"3\",\"TenancyChangeEffectiveDate\":\"03-11-2014\",\"SiteStatus\":\"Active\",\"SiteDropDate\":\"\"}]}";
var siteResponse = JsonConvert.DeserializeObject<SiteResponse>(jsonValue);
List<MasterServiceResponse> records = siteResponse.SiteData;
}
Working demo here:
https://dotnetfiddle.net/wzg8AK

Can't deserialize an indexed name value pair child node C#

I'm running into an issue when I am trying to deserialize a webAPI GET call that returns a JSON object. The issue being one particular property is always null after being deserialized.
The JSON object looks like this:
{
"status":"OK",
"masterlist":{
"session":{
"session_id":intValue,
"session_name":"stringValue"
},
"0":{
"bill_id":intValue,
"number":"stringValue",
"change_hash":"stringValue",
"url":"stringValue",
"status_date":"dateValue",
"status":"stringValue",
"last_action_date":"dateValue",
"last_action":"stringValue",
"title":"stringValue",
"description":"stringValue"
},
"1":{
"bill_id":intValue,
"number":"stringValue",
"change_hash":"stringValue",
"url":"stringValue",
"status_date":"dateValue",
"status":"stringValue",
"last_action_date":"dateValue",
"last_action":"stringValue",
"title":"stringValue",
"description":"stringValue"
},
"2":{
"bill_id":intValue,
"number":"stringValue",
"change_hash":"stringValue",
"url":"stringValue",
"status_date":"dateValue",
"status":"stringValue",
"last_action_date":"dateValue",
"last_action":"stringValue",
"title":"stringValue",
"description":"stringValue"
}
}
}
As you can see the second property of masterlist isn't an array, that would make life too easy... But it looks more like a collection of name/value pairs. I have reviewed This post and the associated one listed within but they both pertain to if the name/value pair where at the root level where mine is not.
My method that I am using to deserialize is:
BillMaster billMasterList = new BillMaster();
using (HttpClient client = new HttpClient())
{
string json = Get("&op=getMasterList&state=TN");
billMasterList = JsonConvert.DeserializeObject<BillMaster>(json);
}
And the model classes the deserializer is binding to:
public class BillMaster
{
public string Status { get; set; }
public BillMasterList masterlist { get; set; }
}
public class BillMasterList
{
public BillMasterList_Session session { get; set; }
public Dictionary<int, BillMasterList_Array> BillMasterList_Array { get; set; }
}
public class BillMasterList_Array
{
public int bill_id { get; set; }
public string number { get; set; }
public string change_hash { get; set; }
public string url { get; set; }
public string status_date { get; set; }
public string status { get; set; }
public string last_action_date { get; set; }
public string last_action { get; set; }
public string title { get; set; }
public string description { get; set; }
}
When I run the code I don't throw any errors and I have values in my object except for BillMasterList_Array, that is always null. I'm obviously not doing something right but what it is alludes me.

How to attach jstree nodes in form using jquery and receive in MVC Model?

I have a form with multiple Jstree elements. I gathered all jstree nodes using this code:
var treeData = $('.jstree').jstree(true).get_json('#', { flat: false });
var jsonData = JSON.stringify(treeData);
result is an array of objects. each node has an array of children too.
in server-side I have a model like this:
public class SampleModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<JsTreeNode> Products { get; set; }
}
and JsTreeNode is like this:
public class JsTreeNode
{
public string id { set; get; }
public string text { set; get; }
public string icon { set; get; }
public JsTreeNodeState state { set; get; }
public List<JsTreeNode> children { set; get; }
public JsTreeNodeLiAttributes li_attr { set; get; }
public JsTreeNodeAAttributes a_attr { set; get; }
public string data { get; set; }
public JsTreeNode()
{
state = new JsTreeNodeState();
children = new List<JsTreeNode>();
li_attr = new JsTreeNodeLiAttributes();
a_attr = new JsTreeNodeAAttributes();
}
}
I tried to append jstree data(appending treeData , or jsonData ).
var formData = new FormData($("form").get(0));
formData.append('Products', treeData);
But nothing were received in server-side.
How can I get this tree structure in Server.

How to bind multilevel json data to a repeater in asp.net or converting json data to data table

I want to bind the Json data to the repeater I know only one process that is converting the Json data to data table and then binding data but here I am receiving multilevel json data i do't know how to convert them to data table
input json data:
{"apiAvailableBuses":
[{"droppingPoints":null,"availableSeats":40,"partialCancellationAllowed":false,"arrivalTime":"01:00 AM","cancellationPolicy":"[{\"cutoffTime\":\"1\",\"refundInPercentage\":\"10\"},{\"cutoffTime\":\"2\",\"refundInPercentage\":\"50\"},{\"cutoffTime\":\"4\",\"refundInPercentage\":\"90\"}]","boardingPoints":[{"time":"07:40PM","location":"K.P.H.B,Beside R.S Brothers","id":"2238"}],"operatorName":"Apple I Bus","departureTime":"8:00 PM","mTicketAllowed":false,"idProofRequired":false,"serviceId":"6686","fare":"1000","busType":"Hi-Tech A/c","routeScheduleId":"6686","commPCT":9.0,"operatorId":203,"inventoryType":0},
{
"droppingPoints":null,"availableSeats":41,"partialCancellationAllowed":false,"arrivalTime":"06:00 AM","cancellationPolicy":"[{\"cutoffTime\":\"1\",\"refundInPercentage\":\"10\"},{\"cutoffTime\":\"2\",\"refundInPercentage\":\"50\"},{\"cutoffTime\":\"4\",\"refundInPercentage\":\"90\"}]","boardingPoints":[{"time":"08:00PM","location":"Punjagutta,","id":"2241"}],"operatorName":"Royalcoach Travels","departureTime":"8:00 PM","mTicketAllowed":false,"idProofRequired":false,"serviceId":"6736","fare":"800","busType":"VOLVO","routeScheduleId":"6736","commPCT":9.0,"operatorId":243,"inventoryType":0}
I am trying to convert it to data table by
public void getavailablebuses()
{
string url = string.Format(HttpContext.Current.Server.MapPath("files/getavailablebuses.json"));
using (WebClient client = new WebClient())
{
string json = client.DownloadString(url);
var result = JsonConvert.DeserializeObject<RootObject>(json);
string mm = JObject.Parse(json).SelectToken("apiAvailableBuses").ToString();
// var boardingpoint = JObject.Parse(mm).SelectToken("boardingPoints").ToString();
var Availablebuses = JObject.Parse(json).SelectToken("apiAvailableBuses").ToString();
DataTable dt = (DataTable)JsonConvert.DeserializeObject(Availablebuses, (typeof(DataTable)));
}
public class apiresult
{
public string message { get; set; }
public string success { get; set; }
}
public class RootObject
{
public apiresult apiStatus;
public List<apiAvailableBuses> apiAvailableBuses{ get; set; }
// public string apiAvailableBuses { get; set; }
}
public class apiAvailableBuses
{
public string serviceId { get; set; }
public string fare { get; set; }
public string busType { get; set; }
public string departureTime { get; set; }
public string operatorName { get; set; }
public string cancellationPolicy { get; set; }
public List<boardingpoints> boardingpoints { get; set; }
public string droppingPoints { get; set; }
public string inventoryType { get; set; }
public string routeScheduleId { get; set; }
public int availableSeats { get; set; }
public string arrivalTime { get; set; }
public Boolean idProofRequired { get; set; }
public Boolean partialCancellationAllowed { get; set; }
public int operatorId { get; set; }
public double commPCT { get; set; }
public string mTicketAllowed { get; set; }
}
public class boardingpoints
{
public string location { get; set; }
public string id { get; set; }
public string time { get; set; }
}
public class cancellationPolicy
{
public string cutoffTime { get; set; }
public string refundInPercentage { get; set; }
}
Here in the data table I am unable to get the boarding points, dropping points and cancellation policy
if I load cancellation policy as list or JObject I am getting error
so here I am loading cancellation policy as string.
but I am unable to load boarding points and dropping points.
Please help with this I am scratching my head from two days. Thanks in advance
"I know only one method to bind data to a repeater i.e data table." So this is a perfect opportunity to learn other ways, wouldn't you say?
Why don't you work with the result of JsonConvert.DeserializeObject<RootObject>(json);? This is a RootObject that has a property called apiAvailableBuses which seems to be exactly what you need to bind to your repeater, no?
By the way, a bit of code review:
apiresult and apiAvailableBuses violate Microsoft's rules WRT class names: those should be in PascalCase. Same for the properties of apiresult, e.g. message and success. Same for the properties of apiAvailableBuses.
RootObject has a public field: apiStatus. That probably needs to be a a property with a getter/setter.
Moreover, apiAvailableBuses is plural, which is incorrect, since the data therein is of only one bus. Same for boardingpoints: the class contains data for a single point, not multiple.
Be consistent: if you use string, then also use bool and not Boolean.

Structure of Json in C#

My Goal:
Read JSON from site, get values of certain items and display them, after I successfully
pull that off I will want to implement taking in a value like true and set it to false.
For starters I need help figuring out how to read and write the variables. I have read
lots of tutorials and blogs about how to read in the data and parse it but what isn't
explained is where is the value stored?
Like I have this http://elsite.com/.json and it has this:
{
dola: "p9", data:{
house: [{
dola: "p9", data:{
owner: "blah", // string
price: blah, // int
url: "http://www.link.com", // url/string
message: "blahblah",
checked: false
}
},
{
dola: "p9", data:{
owner: "blah", // same as above
I have built this to get the data:
[DataContract]
class container
{
[DataMember(Name = "data")]
public Data1 dataStart { get; set; }
[DataContract]
public class Data1
{
[DataMember(Name = "house")]
public HouseA[] home { get; set; }
[DataContract]
public class HouseA
{
[DataMember(Name = "data")]
public Data2 dataSec { get; set; }
[DataContract]
public class Data2
{
[DataMember(Name = "owner")]
public string own { get; set }
[DataMember(Name = "message")]
public strinng mess { get; set; }
}
}
}
}
I want to use
var blah = from post in container.dataStart.house.data // obviously not the right way to do it
select new MessageItem
{
User = post.own,
Meza = post.mess
}
with
public class MessageItem
{
public string User;
public string Meza;
}
So basically it boils down to I am not COMPLETELY understanding the structure of the arrays and objects.
Anyone able to guide me in the right way to do the from.in.select?
Have you looked at Json.NET http://json.codeplex.com/ which includes LINQ to JSON support
I prefer JavaScriptSerializer (System.Web.Extensions.dll) for this; the following works:
JsonResult obj = new JavaScriptSerializer().Deserialize<JsonResult>(json);
var qry = from house in obj.data.house
let post = house.data
select new MessageItem
{
User = post.owner,
Meza = post.message
};
with:
class JsonResult
{
public string dola { get; set; }
public Data data { get; set; }
public class Data
{
public List<House> house { get; set; }
}
public class House
{
public string dola { get; set; }
public HouseData data { get; set; }
}
public class HouseData
{
public string owner { get; set; }
public int price {get;set;}
public Uri url {get;set;}
public string message {get;set;}
public bool #checked {get;set;}
}
}

Categories

Resources