How can I serialize this .NET Collection item? - c#

I'm trying to xml serialize a POCO view data class into xml. It serializes, but incorrectly generates some xml.
eg. (current result .. not the one I'm after)
<ReviewListViewData>
<reviews>
<review>....</review>
...
</reviews>
</ReviewListViewData>
I'm trying to get (notice how I've removed the bad root node?) ...
<reviews>
<review>....</review>
...
</reviews>
Class is defined as...
public class ReviewListViewData
{
[XmlArray("reviews")]
[XmlArrayItem("review")]
public ReviewViewData[] Reviews { get; set; }
}
and here's a sample way it's called in an ASP.NET MVC ActionMethod :-
var reviewListViewData = GetReviewListViewData(...);
return XmlResult(reviewListViewData); // (XmlResult referenced from MVCContrib).
anyone have any ideas, please?

Try this:
[XmlRoot("reviews")]
public class ReviewListViewData
{
[XmlElement("review")]
public ReviewViewData[] Reviews { get; set; }
}

Did you try decorating the class ReviewListViewData with [XmlRoot("reviews")] instead of the XmlArray?

Related

Need help deserializing C# / .NET 6 into seperate objects

I am attempting to use JsonSerializer.Deserialize() from System.Text.JSON in .NET 6.
I have no control over the format of the JSON.
I have used it successfully in the past but now the data I need to consume is more complicated (but not VERY complicated). I am assuming that I am simply describing my data incorrectly.
I have tried several things.... but the description below is the only way so far that I could consume the data at all.
I think my biggest problem is that I am trying to use the wiz-bang "Paste Special -> Paste JSON as Classes" without really understanding how to form my classes for serialization/deserialization.
Here is a simple example of the JSON I am trying to consume:
[
{
"version": "1.0b",
"sub_version": "x.y.barf"
},
{
"somestring": "I am a string",
"isCool": false,
"a_cool_array": [
"bob",
"jill",
"pete"
]
}
]
If I use the whiz-bang "Paste Special" tool, I get the following generated for me.
public class Rootobject
{
public Class1[] Property1 { get; set; }
}
public class Class1
{
public string version { get; set; }//<-- I need these to remain in their own object
public string sub_version { get; set; }//<-- I need these to remain in their own object
public string somestring { get; set; }
public bool isCool { get; set; }
public string[] a_cool_array { get; set; }
}
Here is the problem that I have.
The whiz-bang tool put my first object (with one version strings) and second (more complicated) object into the same object.
If I use a call like this:
var deserializedJSON = JsonSerializer.Deserialize<List<Class1>>(myJSONTextHere);
I end up with two objects in the list.
The first one has the versions filled out, the second one only has the other fields filled out.
This all makes sense to me but I don't know how to get around the problem.
I need these objects to model the JSON and I need them to save back in the same format when I re-serailize the modified classes elsewhere. This isn't my exact problem as I have simplified it for the question.
I have found one way around this problem.
It is ugly but seems to work. I hate that my code has to know about the data it is manipulating.
I used the actual JSON DOM to split the two disparate classes into individual JSON objects, then used the class de-serializer to load the individual objects into their given types.
In the following example, I am not checking anything.. I happen to know the order of the objects. I could check the raw JSON to make sure it was what I was looking for. In this case, I don't need to.
So, instead of taking the class structure as pasted by the super spiffy "Paste Classes from JSON" thingamajigger.. I split the classes myself.
Like this:
public class VersionClass
{
public string version { get; set; }
public string sub_version { get; set; }
}
public class DataClass
{
public string somestring { get; set; }
public bool isCool { get; set; }
public string[] a_cool_array { get; set; }
}
Then, I can load the JSON into the objects I need like this:
using var jsonDoc = JsonDocument.Parse(jsonText);
var versionClass = jsonDoc.RootElement[0].Deserialize<VersionClass>();
var dataClass = jsonDoc.RootElement[1].Deserialize<DataClass>();
I hope this helps someone having the same problem.
Your json needs to look like this:
{
"class1": [
//more json
],
"class2": [
//more json
]
}
Then you will have:
public class RootObject
{
// class1 and 2 in here
}
public class Class1
{
}
public class Class2
{
}

Convert json to C# classes with generic property

I have json data as below:
{
status: "success",
data: {
custid1: 723,
custid2: 670,
custid3: 430
}
}
As per https://json2csharp.com/, C# classes should be like below:
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class Data {
public int custid1 { get; set; }
public int custid2 { get; set; }
public int custid3 { get; set; }
}
public class Root {
public string status { get; set; }
public Data data { get; set; }
}
But I dont like Data class above, it has custid1, custid2 as hard coded. I know here json data is like that so classes are generated accordingly but can we make some generic design which can parse below line?
var result = JsonConvert.DeserializeObject<Root>(json);
I feel that tools like Json2CSharp.com are only intended for scaffolding and prototyping rather than for directly-usable C# code. So go ahead and use it to quickly create initial code for your project, but you likely will need to tweak it for production use - in this case one of those tweaks you need to make is to change data: entry in the Root DTO class from having its own class Data to being a Dictionary<String,Int32> instead so that it can accommodate the dynamic nature of the data: property in production JSON data.
Side-note: You should use PascalCase for all class properties in your C# code - but you can configure your JSON serializer to automatically map the camelCase properties in the JSON.
If you're using Newtonsoft.Json then use CamelCaseNamingStrategy or set an explicit [JsonProperty( "camelCaseName" )]. You don't even have to do this manually because JSON2CSharp.com can do it automatically for you:
It's in the Options menu next to the Convert button:

Convert a POCO to json using only certain fields

I have an object, Project, that contains many fields, some complex some not. It is an EF class, so I can't edit it to add attributes.
I just want to generate a JSON object containing 2 of the fields (one int (id) and one string (name))
I'd hate to create another ViewModel just for this...
In my viewmodel I have a List<Project>. Is there a way to use HTML helpers to get a JSON representation of only the properties I choose without using attributes?
Here is an example of the Project class:
public class Project
{
public int Id {get; set; } <-- Serialize this
public string Name { get; set; } <-- Serialize this
public Object AnotherObject [ Get; Set; } <-- Ignore this
....
}
I'd like it to become:
[{"id":"27","name":"test1"},{"id":"34","name":"test2"},{"id":"35","name":"test3"}]
The ultimate goal here to is output the json directly to the view as a var so that it can be used in building a JsGrid.
If there is a way to do it with Html helpers, that would be great.
Thanks!
Json.NET has a great built in ignore feature. If you tag the Property you want to exclude with the [JsonIgnore] attribute, the serializer will not serialize that property.
[JsonIgnore]
public bool IsValid { get; set; }

PartialView used by 2 views accessing ViewModel data from each

I have 2 viewmodels each of them have a property called RSSFeed of type RSS. I have 2 views (one for each viewmodel) and I want them to share the same partialview which renders the data in RSSFeed.
In my main views, I have:
#{ Html.RenderPartial("Social", new ViewDataDictionary(Model)); }
In my Social partiavlview I wanted to use something like:
#ViewBag.RSSFeeds.Feed[0].Title
Running that give me 'Cannot perform runtime binding on a null reference'
Each ViewModel has:
public RSS RSSFeed = new RSS();
The supporting classes are:
public class RSSItem
{
public string Title { get; set; }
public string Link { get; set; }
public string Description { get; set; }
public DateTime PubDate { get; set; }
}
public class RSS
{
public string FeedURL { get; set; }
public List<RSSItem> Feed = new List<RSSItem>();
}
Any help is greatly appreciated. I wonder if I am actually able to do what I am looking to do or have completely done this the wrong way.
In your example above, .Feed is an empty List of RSSItems. Your code:
#ViewBag.RSSFeeds.Feed[0].Title
If attempting to get the title from the first Feed in your (empty) list which is why you are getting the null reference error.
You'd need to do a check in your partial to make sure that a Feed exists before using it.
#if (ViewBag.RSSFeeds != null && ViewBag.RSSFeeds.Feed.Count() > 0)
If you use the ViewBag, you'll need to populate that on every page load that uses it - if it's only 2 pages that might not be a problem. Maybe it would be better to use the Session to store your RSSFeeds instead?
Set
Session["RSSFeeds"] = RSSFeeds;
Get
if (Session["RSSFeeds"] != null)
return (RSSFeeds)Session["RSSFeeds"];
else
return null;
I can't comment yet, but are the inputs you are using for RenderPartial correct? on MSDN there is no method that takes a ViewDataDictionary and one other object.

iterating through objects of response JSON

I'm doing a query and get as result something like this, which i put into a Hashtable
{"success":"true", "result":[{"type":"email", "address":"aaasd#asd.com"},{"type":"email", "address":"aaasddee#dse.com"}]}
then i do
return hashtable["result"];
so I only have this left
[{"type":"email", "address":"aaasd#asd.com"},{"type":"email", "address":"aaasddee#dse.com"}]
but my problem is that I don't know how to iterate through every object from "result" to fill my own objects. I was searching for a solution but the only answer I found was to use
foreach(DictionaryEntry entry in searchResult) {
//do something<br>
}
When I iterate through the Hashtable like this I can only use the properties entry.Key and entry.Value but I can't say which value for a specific key I need. Any suggestions are welcome.
You can get it using deserialising using JSON.NET as shown below :-
var result = JsonConvert.DeserializeObject<dynamic>(searchResult);
You can create your class like below :-
public class RootObject
{
public string type { get; set; }
public string address { get; set; }
}
For more information :-
http://james.newtonking.com/json/help/index.html?topic=html/SerializingJSON.htm
Create a class that matches the signature of the result collection like:
public class Result
{
public string Type { get; set; }
public string Address { get; set; }
}
Then use Json.NET to parse the result node into a List<Result>. There is plenty of documentation online on how to use the Json.NET library.
Hope that helps,
Rob

Categories

Resources