JSON serializer with nested object lists - c#

I'm trying to setup a web service in a asp.net project to return requests in a JSON format.
the web service method code is as follows:
public string NavigationItems()
{
using (TTConnection connection = new TTConnection("ClientDb"))
{
if (MySession.Current.MyClub == null)
return USER_ERROR;
MiddleTier.WebNavigation.WebNavigationGenerator gen = MySession.Current.NavGenerator;
List<NavigationElement> list = gen.GetNavigation();
string json = JsonConvert.SerializeObject(list);
return json;
}
}
The NavigationElement object has the following constructor & properties
public NavigationElement(string pUrl, int pSequence, string pLinkText, string pDescription,int pUid)
{
url = pUrl;
sequence = pSequence;
linkText = pLinkText;
description = pDescription;
uid = pUid;
}
and the request returns the following JSON
Content-Type:application/json; charset=utf-8;
{"d":"[{\"elements\":[],\"url\":\"~/Welcome.aspx\",\"sequence\":1,\"linkText\":\"Home\",\"description\":\"Home Page\",\"uid\":1,\"parent\":null},{\"elements\":[],\"url\":\"~/About.aspx\",\"sequence\":2,\"linkText\":\"About\",\"description\":\"About Us\",\"uid\":2,\"parent\":null},{\"elements\":[{\"elements\":[{\"elements\":[],\"url\":\"~/Member/ClubHomeSub/ClubTheme.aspx\",\"sequence\":1,\"linkText\":\"Club Theme\",\"description\":\"Club Theme\",\"uid\":5,\"parent\":null},{\"elements\":[],\"url\":\"~/Member/ClubHomeSub/ClubPages.aspx\",\"sequence\":2,\"linkText\":\"Club Pages\",\"description\":\"Club Pages\",\"uid\":8,\"parent\":null}],\"url\":\"~/Member/ClubHomeSub/ClubAdmin.aspx\",\"sequence\":1,\"linkText\":\"Club Admin\",\"description\":\"Club Admin\",\"uid\":4,\"parent\":null}],\"url\":\"~/Member/ClubHome.aspx\",\"sequence\":3,\"linkText\":\"Club Home\",\"description\":\"Club Home\",\"uid\":3,\"parent\":null},{\"elements\":[],\"url\":\"~/Member/GameAnalysis.aspx\",\"sequence\":4,\"linkText\":\"Game Analysis\",\"description\":\"Game Analysis\",\"uid\":6,\"parent\":null},{\"elements\":[],\"url\":\"~/Member/SkillAquisition.aspx\",\"sequence\":5,\"linkText\":\"Skill Aquisition\",\"description\":\"Learn new game skills\",\"uid\":7,\"parent\":null}]"}
Which is valid but gets interpreted as an object with a very long string
d: "[{"elements":[],"url":"~/Welcome.aspx","sequence":1,"linkText":"Home","description":"Home Page","uid":1,"parent":null},{"elements":[],"url":"~/About.aspx","sequence":2,"linkText":"About","description":"About Us","uid":2,"parent":null},{"elements":[{"elements":[{"elements":[],"url":"~/Member/ClubHomeSub/ClubTheme.aspx","sequence":1,"linkText":"Club Theme","description":"Club Theme","uid":5,"parent":null},{"elements":[],"url":"~/Member/ClubHomeSub/ClubPages.aspx","sequence":2,"linkText":"Club Pages","description":"Club Pages","uid":8,"parent":null}],"url":"~/Member/ClubHomeSub/ClubAdmin.aspx","sequence":1,"linkText":"Club Admin","description":"Club Admin","uid":4,"parent":null}],"url":"~/Member/ClubHome.aspx","sequence":3,"linkText":"Club Home","description":"Club Home","uid":3,"parent":null},{"elements":[],"url":"~/Member/GameAnalysis.aspx","sequence":4,"linkText":"Game Analysis","description":"Game Analysis","uid":6,"parent":null},{"elements":[],"url":"~/Member/SkillAquisition.aspx","sequence":5,"linkText":"Skill Aquisition","description":"Learn new game skills","uid":7,"parent":null}]"

Turns out you don't need to use a serializer at all.
You just return type object.
public object NavigationItems()
{
using (TTConnection connection = new TTConnection("ClientDb"))
{
if (MySession.Current.MyClub == null)
return USER_ERROR;
MiddleTier.WebNavigation.WebNavigationGenerator gen = MySession.Current.NavGenerator;
List<NavigationElement> list = gen.GetNavigation();
return list;
}
}

Related

How to create exact JSON format to POST method in c# code?

Web Service required this format:
{
"Data":"{\"Name\":\"HelloWorld\",\"BirthDate\":\"2020-03-03\",\"BirthPlace\":\"Nowhere\"}"
}
I required above format to post to web service but my code below doesn't fulfil the format. Please help. I've been using below code to post
var Data = JsonConvert.SerializeObject(new
{
Data = new
{
Name= "HelloWorld",
BirthDate = "2020-03-03",
BirthPlace= "Nowhere"
}
});
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsJsonAsync(apiUrl, Data);
}
If data should contains a string serialization of the real object. You can simply serialize the inner object using the string result as value on your second serialization.
using Newtonsoft.Json;
public static string WrapAndSerialize(object value){
return JsonConvert.SerializeObject(new { Data = JsonConvert.SerializeObject(value) });
}
Using it like:
var myObject=
new
{
Name = "HelloWorld",
BirthDate = "2020-03-03",
BirthPlace = "Nowhere",
};
var Data= WrapAndSerialize(myObject);
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsJsonAsync(apiUrl, Data);
}
LiveDemo
To get the required format do:
string name = "HelloWorld";
string birthdate = "2020-03-03";
string birthplace= "Nowhere";
var jsonData = JsonConvert.SerializeObject(new
{
Data = $"\"Name\"=\"{name}\",\"BirthDate\"=\"{birthdate}\",\"BirthPlace\"=\"{birthplace}\""
});
See it in action: https://dotnetfiddle.net/UBXDtd
The format states that Data shall contain a string. Your code serializes an object with properties, which results in:
{"Data":{"Name":"HelloWorld","BirthDate":"2020-03-03","BirthPlace":"Nowhere"}}
EDIT: While this works, I would recommend #xdtTransform's answer over this. Leaving this here, in case his solution is for some reason not applicable.

Get data from B method to A method without using Session in C#?

How can i get my master_handler method handler_response data to get_data method without using session in C#.
Currently i getting data by using session, i want to get handler_response data in string response under GET_DATA() method without using session.
How can do this please help
My code is
[WebMethod]
public static string GET_DATA()
{
string Search = "1";
master_handler(Search);
string response = string.Empty;
response = (string)HttpContext.Current.Session["HANDLER_RESPONSE"]; // getting handler_response here
HttpContext.Current.Session["obj_GET_FLIGHT_DATA"] = response;
return response;
}
public static string master_handler(string dt)
{
string handler_response= string.Empty;
LibraryCaller.Master_Handler MH = new LibraryCaller.Master_Handler();
string get_api_data = MH.Search(dt);
JObject jObj = JObject.Parse(get_api_data);
handler_response= jObj.ToString();
HttpContext.Current.Session["HANDLER_RESPONSE"] = handler_response; // here currently using sesson
return handler_response;
}
Cache the value instead:
Cache.Insert("HANDLER_RESPONSE", handler_response);
To retrieve it use:
string handler_response;
handler_response = (string)Cache["HANDLER_RESPONSE"];
That's the simplest way to do it via caching, read up on it as theres a lot more to it.
I have done this by using class.
public class handler
{
public string data_handler(string dt)
{
string handler_response= string.Empty;
LibraryCaller.Master_Handler MH = new LibraryCaller.Master_Handler();
string get_api_data = MH.Search(dt);
JObject jObj = JObject.Parse(get_api_data);
handler_response= jObj.ToString();
HttpContext.Current.Session["HANDLER_RESPONSE"] = handler_response; // here currently using sesson
return handler_response;
}
}
and access data
handler h = new handler();
response = h.data_handler(search);

Web Api Post method is receiving NULL parameter always

I am trying to pass List as a parameter to web Api , Using below code;
Client Side
public async Task<ActionResult>BatchUpdatePartial(MVCxGridViewBatchUpdateValues<NewWorkItem, int> batchValues)
{
var updatedItems = new List<NewWorkItem>();
string url = "http://localhost:9198/api/values";
foreach (var item in batchValues.Update)
{
if (batchValues.IsValid((item)))
{
var updatedVals = new NewWorkItem();
updatedVals.CPK_ID = item.CPK_ID;
updatedVals.BYR_ID = item.BYR_ID;
updatedVals.P_ID = item.P_ID;
updatedVals.CPK_PRI_FLG = item.CPK_PRI_FLG;
updatedItems.Add(updatedVals);
}
else
batchValues.SetErrorText(item, "Correct Vallidation Errors");
}
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/json";
client.Encoding = System.Text.Encoding.UTF8;
string serialisedData = JsonConvert.SerializeObject(updatedItems);
string response = client.UploadString(url, serialisedData);
Object result = JsonConvert.DeserializeObject(response);
}
return PartialView("_GridViewPartial", NewWorkItem.GridData);
}
Server Side
public string Post([FromBody]string[] values)
{
string seperator = ",";
string data = string.Join(seperator, values.ToList<string>());
string result = string.Format("Succesfully uploaded: {0}", data);
return result;
}
But I am always getting NULL inside the values at server side ?
Can you please suggest me solution ?
Thanks
Unfortunately, you are not actually sending a string[] the way your POST method expects. You are sending serializedData, which is, by your own definition, a serialization of updatedItems. updatedItems is a list of a reference type - you do not provide the definition of it here, but I guarantee you it is not going to serialize the same way a string does.
You will need to change updatedItems to be List<string> or something similar.

C#: Json validation from user input

I need to validate a json file from server side, Im using asp.net mvc with c#, so I have this method in my controller
public ActionResult Validate(HttpPostedFileBase jsonFile)
{
bool validJson = false;
var serializer = new JavaScriptSerializer();
try
{
var result = serializer.Deserialize<Dictionary<string, object>>(How should I pass the json file here ??);
validJson = true;
}
catch(Exception ex)
{
validJson = false;
}
}
This is the best way for validate it ? ... sorry but I don't know how to pass the json string parameter, I have tried with jsonFile.InputStream.ToString(), jsonFile.tostring() ... what it needs ?, json user's route ? ... thanks in advance
Well how about something like this:
using (var reader = new StreamReader(jsonFile.InputStream))
{
string jsonData = reader.ReadToEnd();
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<Dictionary<string, object>>(jsonData);
// dragons be here ...
}

C# webservice losing data on return

I am programming a client program that calls a webmethod but when I get the return data there are missing values on some of the fields and objects.
The webmethod in turn is calling a WCF method and in the WCF method the return data is fine. But when it is passing to the webservice the return data is missing.
Is there any way to fix this problem?
This is my client code calling the webservice:
ReLocationDoc query = new ReLocationDoc();
query.PerformerSiteId = 1;
query.PerformerUserId = 1;
query.FromStatus = 10;
query.ToStatus = 200;
ReLocationDoc doc = new ReLocationDoc();
ServiceReference1.QPSoapClient service = new QPSoapClient();
try {
service.GetRelocationAssignment(query, out doc);
string test = doc.Assignment.Id.ToString();
} catch(Exception ex) {
MessageBox.Show(ex.Message);
}
The webmethod code is here:
[WebMethod]
return m_reLocationClient.GetRelocationAssignment(query, out reLocationDoc);
}
And at last the WCF code:
public ReLocationResult GetRelocationAssignment(ReLocationDoc query, out ReLocationDoc reLocationDoc) {
try {
LOGGER.Trace("Enter GetRelocationAssignment().");
ReLocationResult result = reLocationCompactServiceClient.GetRelocationAssignment(out reLocationDoc, query);
if(reLocationDoc.Assignment == null || reLocationDoc.Assignment.CurrentStatus == STATUS_FINISHED) {
ReLocationDoc newQuery = new ReLocationDoc();
newQuery.Assignment = new AssignmentDoc();
newQuery.Assignment.EAN = DateTime.Today.ToString();
newQuery.PerformerSiteId = QPSITE;
newQuery.PerformerUserId = QPUSER;
reLocationDoc.AssignmentStatus = m_settings.ReadyStatus; ;
result = reLocationCompactServiceClient.CreateReLocationAssignment(out reLocationDoc, newQuery);
}
return result;
} finally {
LOGGER.Trace("Exit GetRelocationAssignment().");
}
}
The GetRelocationAssignment:
public ReLocationResult GetRelocationAssignment(ReLocationDoc query, out ReLocationDoc reLocationDoc) {
try {
LOGGER.Trace("Enter GetRelocationAssignment().");
ReLocationDoc doc = new ReLocationDoc();
ReLocationResult result = new ReLocationResult();
new Database(Connection).Execute(delegate(DBDataContext db) {
User user = GetVerifiedUser(db, query, MODULE_ID);
SiteModule siteModule = SiteModule.Get(db, query.PerformerSiteId, MODULE_ID);
Status status = Status.Get(db, query.FromStatus, query.ToStatus, 0);
Status startStatus = Status.Get(db, query.FromStatus, 0);
Status endStatus = Status.Get(db, query.ToStatus, 0);
IQueryable<Assignment> assignments = Assignment.GetAssignmentsWithEndStatus(db, siteModule, endStatus);
assignments = Assignment.FilterAssignmentStartStatus(assignments, startStatus);
foreach(Assignment assignment in assignments) {
LOGGER.Debug("Handling assignment: " + assignment.Id);
result.Status = true;
AssignmentDoc assignmentDoc = FillAssignmentDoc(assignment);
//ReLocationDoc doc = new ReLocationDoc();
AssignmentStatus sts = assignment.AssignmentStatus.OrderByDescending(ass => ass.Id).First();
assignmentDoc.CurrentStatus = sts.Status.Zone;
Status currentStatus = sts.Status;
IList<Item> items = assignment.Items.ToList();
IList<ItemDoc> itemDocs = new List<ItemDoc>();
foreach(Item item in items) {
ItemDoc itemDoc = FillItemDoc(item);
ItemDetail itemDetail;
if(ItemDetail.TryGet(db, item.Id, out itemDetail)) {
ItemDetailDoc itemDetailDoc = FillItemDetailDoc(itemDetail);
itemDoc.Details = new ItemDetailDoc[1];
Event eEvent = null;
if(Event.GetEvent(db, itemDetail, currentStatus, out eEvent)) {
EventDoc eventDoc = FillEventDoc(eEvent);
itemDetailDoc.Events = new EventDoc[1];
if(eEvent.LocationId.HasValue) {
Location location = null;
if(Location.TryGet(db, eEvent.LocationId.Value, out location)) {
eventDoc.Location = new LocationDoc();
eventDoc.Location = FillLocationDoc(location, db);
}
}
itemDetailDoc.Events[0] = eventDoc;
}
itemDoc.Details[0] = itemDetailDoc;
}
itemDocs.Add(itemDoc);
}
assignmentDoc.Items = itemDocs.ToArray();
doc.Assignment = assignmentDoc;
}
}, delegate(Exception e) {
result.Message = e.Message;
});
reLocationDoc = doc;
return result;
} finally {
LOGGER.Trace("Exit GetRelocationAssignment().");
}
}
In all this code the return data is fine. It is loosing data only when passing to the webmetod.
Enter code here.
Also, the ordering of the XML tags in the message makes difference - I had a similar problem about maybe two years ago, and in that case parameter values were dissappearing during transmission because the sending part ordered the tags differently than what was defined in the schema.
Make surethe XML tags are being accessed with the same casing at either end. if the casing is not the same then the value won't be read.
You should check it all message are sending back from your webservice. Call your webservice manually and check its response.
If all data is there, probably your webservice reference is outdated; update it by right-clicking your webservice reference and choose "Update"
If your data don't came back, your problem is probably related to webservice code. You should check your serialization code (if any) again, and make sure all returned types are [Serializable]. You should check if all return types are public as it's mandatory for serialization.
As noted per John Saunders, [Serializable] isn't used by XmlSerializer.

Categories