Pagination Newtonsoft.Json - c#

A problem I've been running into recently is dealing with pagination of Json I receive from the server. I can work around some instances but would like a better approach. So the structure I receive here illustrates a problem I can run into:
Modules
{
ID
Title
Description
Lessons
{
edges
{
node
{
ID
}
}
}
}
So for the lessons array, the server inserts the edges and node elements because of the use of pagination. So what I would expect instead is:
Modules
{
ID
Title
Description
Lessons
{
ID
}
}
The main problem however with this is that it stops me being able to deserialize the object easily, i.e. I can't do this:
Modules[] modules = JsonConvert.DeserializeObject<Modules[]>(json, settings);
My Lesson and Module class for reference is just:
public class Lesson
{
public int ID;
}
[System.Serializable]
public class Module
{
public string ID;
public string Title;
public string Description;
public Lesson[] Lessons;
}
So just wondered if anyone else had come across a similar issue and what solutions they've done to work around it?

Your serialization should work just fine if you create concrete objects for 'edges' and 'node'.
I assume 'lessons' it an array of 'edge' object. 'edge' object contains the 'node' object, which has the property 'id'

So I worked out a bit of a workaround (sort of following Zero Cool's answer) which is to make generic Edges and Node classes. i.e.
[System.Serializable]
public class Edges<T>
{
public Node<T>[] edges;
}
public class Node<T>
{
public T node;
}
And then declare them where I am using Pagination. It's not lovely but works alright as I usually know what is/isn't paginated.
Would still be interested if there's a cleaner way.

Related

What is best approach for data inheritation in elasticsearch?

I have an parent class and two child like these:
public class Parent {
public Guid Id { get; set; }
public string Name { get; set; }
}
public class FirstChild {
public string IdentityCode { get; set; }
}
public class OtherChild {
public string RegistrationCode { get; set; }
}
There is a question: Is it a good approach to store these two inherited classes in the same Index inside ElasticSearch?
I see there is a _type property that is added to my docs after they are stored in DB but it has always "doc" value.
I test this code to fill it but it seems it is not working this way.
await ElasticClient.IndexAsync<FirstChild>(child, m => m.Index(IndexName));
And Also, I found this question on SO for retrieving my entries from DB but it is outdated and the API is changed and no more accessible.
I want to know if it is a good approach to store sibling data in the same index how can I do this properly.
As of ES 6.0, it is not possible anymore to store multiple types inside the same index, i.e. the _type field you're referring to will always be either doc or _doc. In ES 8.0, the _type field will be removed altogether.
However, if it makes sense for your use case, you can still decide to store several types inside a single index using a custom type field that is present in your document.
You should strive to only store in the same index data that share the same (or very similar) mapping, which doesn't seem to be the case for Parent, FirstChild and SecondChild, but if you add a public string type property to your classes you can still do it.

Serializing an IEnumerable in protobuf-net

I have a library of fairly heavy-weight DTOs that is currently being used by some WCF services. We are attempting to bring it into protobuf-net world, with as little modification as possible. One particular set of items is giving me trouble in serialization. I'm going to simply them here because it gets a little complicated, but the gist of the problem is:
public class Key
{
public string Id {get; set;}
}
public class KeyCollection : IEnumerable<Key>
{
private readonly List<Key> list;
#region IEnumerable
// etc...
#endregion
}
public class Item
{
public long Id { get; set; }
}
public abstract class ContainerBase
{ }
public abstract class ContainerBase<T> : ContainerBase
where T : Item
{ }
public abstract class ContainerType1Base : ContainerBase<Item>
{
public KeyCollection Keys { get; set; }
}
public class ContainerType1 : ContainerType1Base
{ }
I've left out the decorators because I don't they're the problem, mostly because if I add void Add(Key item) { } to KeyCollection the whole thing seems to work. Otherwise, I run into problems attempting to serialize an instance of ContainerType1.
Actually, changing the signature of KeyCollection is kind of prohibitive, so I'm attempting to follow this answer to try to do it programatically. Specifically, setting itemType and defaultType to null on the "Keys" ValueMember of ContainerType1, ContainerType1Base and ContainerBase<Item>. I also set IgnoreListHandling to true on KeyCollection... which totally doesn't work. I get a generic "failed to deserialize" exception on the client, which I can post here if it would help. On the server side, I serialize it out using Serializer.Serialize(), and I spit out Serializer.GetProto<>() as well as JSON of the object, and they all seem to be work okay.
How can I turn off the list handling? Related to that, is there a way to turn on extra debugging while serializing to try to get some more information of the problem?
Fundamentally, the code shown looks fine. Unfortunately, there's currently a "feature" in gRPC that means that it discards the original exception when a marshaller (serializer) fails for some reason, so gRPC does not currently expose the actual problem. I have submitted a fix for this - it may or may not be accepted.
In the interim, I suggest that you simply remove gRPC from the equation, and simulate just the marshaller workload; to do this, on the server: generate the data you are trying to send, and do:
var ms = new MemoryStream();
Serializer.Serialize(ms, yourDataHere);
var payload = Convert.ToBase64String(ms.ToArray());
and obtain the value of payload (which is just a string). Now at the client, reverse this:
var ms = new MemoryStream(Convert.FromBase64String(thatStringValue));
Serialize.Deserialize<YourTypeHere>(ms);
My expectation here is that this should throw an exception that will tell you what the actual problem is.
If the gRPC change gets merged, then the fault should be available via:
catch (RpcException fault)
{
var originalFault = fault.Status.DebugException;
// ^^^
}

How to set up a C# model to convert properties to Knockout computed observables

We're using durandal to convert C# models to Knockout viewmodels for rendering. I'm wondering if there's a way I can set up a C# model with properties that have a set method or something so that the bindings and dependencies are already present when I get the Knockout viewmodel.
I'd like a scenario like this to happen.
public class MyObject{
public string FirstName{get; set;}
public string LastName {get; set}
private string fullName{get; set;}
public FullName{
get{return fullName;}
set{fullName = FirstName +" "+LastName}
}
I've used the prime example Knockout uses when explaining computed observables. I understand how to achieve this in purely JS viewmodel. However, I'd like to set up my C# model similar to what I have above (I don't think this actually works) in order to get back a computed that already has it's dependencies.
I'm not entirely sure it's possible, but it sure would be nice.
Max Brodin mentions KnockoutMVC which is a huge antipattern and you lose almost all benefits with Knockout since it creates server callbacks for almost everything you do.
A better option is to use for example DuoCode or Open source alternative WootzJs
These tools will compile C# code to Javascript, I have only tested DuoCode but it was farily easy to create a Knockout binding for it. After that its easy to create ViewModels like
using Knockout;
namespace ViewModels
{
public class FooViewModel
{
private readonly Observable<string> bar;
private readonly Observable<string> computed;
public FooViewModel()
{
bar = Global.Observable("HelloWorld"); //Translates to ko.observable("HelloWorld") on client
computed = Global.Computed(() => bar.Get() + "COMPUTED");
}
public Observable<string> Bar { get { return bar; } }
public Observable<string> Computed { get { return computed; } }
}
}
I have also created bindings for ko.mapping like
Mapping.Map(new { bar = "DataFromserver" }, null, this); which translates to
ko.mapping.fromJS({ bar = "DataFromserver" }, null, this); on client
The idea is good, but it's not going to work in the real world projects. Your C# code need to be translated to javascript and it could work for simple cases like yours. But if you change your computed property to more something complicated you will have problems.
There is a knockoutmvc project that provides such functionality. They have hello world sample which looks like something you can use as a start. You just need to mark your property with attributes
public class HelloWorldModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
[Computed]
[ScriptIgnore]
[JsonIgnore]
public string FullName
{
get { return FirstName + " " + LastName; }
}
}
And in razor view you should call:
#{
var ko = Html.CreateKnockoutContext();
}
#ko.Apply(Model)
You seem to want auto-translation of computed properties. That's a big ask for a small convenience. I think I could do it for trivial expressions, but how would you map .NET library methods like string.Format to javascript? You would need a client side library replicating the semantics. Big job, not worth the effort.

Objects containing list of same object type

Is there anything wrong with defining something like this:
class ObjectA
{
property a;
property b;
List <ObjectA> c;
...
}
No, and because the answer needs at least 30 characters, I'll add that this is a common pattern.
Since you included the oop tag, though, I'll add that this pattern gives a lot of control to the outside world. If c is a list of children, for example, you're giving everyone who has access to an instance of ObjectA the ability to add, delete, or replace its children.
A tighter approach would be to use some sort of read-only type (perhaps implementing IList<ObjectA>) to expose the children.
EDIT
Note that the following still allows others to modify your list:
class ObjectA
{
property a;
property b;
List <ObjectA> c;
...
public List<ObjectA> Children { get { return c; } }
}
The absence of a setter only prevents outsiders from replacing the list object.
Nope. That's perfectly acceptable. Tree structures do this.
It is perfectly valid. For example, you would have to do something like this to build a tree data structure (parent node contains a list of child nodes).
i have to ask if your question is about putting a List< > in there, or if it is about putting a List< ObjectA > inside of ObjectA. and the answer to both questions is "Yes"!
the thing to keep in mind is that by default, the access is private. if you want other classes to use this list, then you need to add a few things to your class...
class ObjectA
{
property a;
property b;
List <ObjectA> c;
// allow access, but not assignment
// you can still modify the list from outside, you just cant
// assign a new list from outside the class
public List<ObjectA> somePropertyName{ get { return this.c;}}
// same as above, only allow derived child classes to set the list
public List<ObjectA> somePropertyName{ get { return this.c;}
protected set { this.c = value;} }
// allow all access
public List<ObjectA> somePropertyName{ get { return this.c;}
set { this.c = value;} }
}
No. This is valid. Many structures uses this graph like pattern.
If you eg have a base collection class
namespace MiniGraphLibrary
{
public class GraphCollection
{
public Node Root { set; get; }
public Node FindChild(Node root)
{
throw new NotImplementedException();
}
public Node InsertNode(Node root, Node nodeToBeInserted)
{
throw new NotImplementedException();
}
}
}
Then you can have the node act like this:
namespace MiniGraphLibrary
{
public class Node
{
private string _info;
private List<Node> _children = new List<Node>();
public Node(Node parent, string info)
{
this._info = info;
this.Parent = parent;
}
public Node Parent { get; set; }
public void AddChild(Node node)
{
if (!this.DoesNodeContainChild(node))
{
node.Parent = this;
_children.Add(node);
}
}
public bool DoesNodeContainChild(Node child)
{
return _children.Contains(child);
}
}
}
Note that this is something I wrote in 2 minutes, and it is problery not good in production, but the 2 main things is that you have a parent node and many children. When you add a child node to a given node, then you make sure that it has its parent node set. Here I first check if the child is allready in the children list before connection the two.
You could make some changes to the code, and make sure that if a child is removed an parent lists that it is allready connected to. I have not done this there.
I have made this to illustrate how it could be used. And it is used many places. Fx clustered indexes in MSSQL uses some sort of this tree like representation. But I am NOT an expert on this subject, so correct me if I am wrong.
I have not implemented the two classes in the GraphCollection class. The downside of my little example is that you if you are going to implement the Find method, then you have to go through the whole graph. You could make a binary tree that only has two children:
namespace MiniTreeLibrary
{
public class SimpleNode
{
private string _info;
private SimpleNode _left;
private SimpleNode _right;
private SimpleNode _parent;
public SimpleNode(Node parent, string info)
{
this._info = info;
this.Parent = parent;
}
public Node Parent { get; private set; }
}
}
I have omitted the insertion of the right and left. Now with this binary tree you could do some pretty darn fast searching, if you wanted!! But that is another discossion.
There is many rules when it comes trees and graphs, and my graph is even a real graph. But I have put these examples here so you can see that it is used alot!! If you want to go more into linear and other data structures, then see this serie of articles. Part 3, 4 and 5 they talks alot more about trees and graphs.

C# .net 4. Help on extracting data from a daughter group in dictionary object

I am sort of new to C# programming and am having trouble with the dictionary using .net 4.0.
I have sent a JSON object through JavaScriptSerializer into a Dictionary<string, object> object which worked great at extracting all the data.
JSON chain
{
"name" : "MrMonkey",
"type" : "monkey",
"location" : {
"id" : "125235",
"name" : "zoo"
},
"owner" : {
"id" : "4211",
"name" : "Biggles"
}
}
In this dictionary object created I have daughter levels that store information I need to extract from the dictionary and store elsewhere. Say I want is to extract the location name. As you can see it also shares a keyname with the parent level and another daughter level.
For the parent level I can extract information as simply as contact.name = dict["name"].ToString(); but how would I go about extracting the required information from the daughter levels?
I was able to create a work around in JSON.net to get this to work with a little bit of fiddling by checking the datatype and then converting it if it fell within a certain type, but this was aggravating and I been told by the boss not to use JSON.net.
Without having tried, I'd try something like: (dict["location"] as Dictionary<string,object>)["name"], as I'd presume from the JSON you've provided, that the daughters themselves are again deserialized into Dictionarys.
Anyway, the debugger will help you a lot here. If you set a breakpoint on the line after the call to the deserialization, you can inspect your dictionary (point the mouse to it and wait a second) and have a look at how your structure is now stored in C# objects.
I would try to create a class that would fill it with the json result. Then work normally and if need be, serialized into json again.
public class MyObject
{
public string name { get;set; }
public string type { get;set; }
public Location location { get;set; }
public Owner owner { get;set; }
}
public class Location
{
public int id { get;set; }
public string name { get;set; }
}
public class Owner
{
public int id { get;set; }
public string name { get;set; }
}
Have you tried using dict["location"]["name"]?
I assume that the daughter level is just treated as another dictionary stored in the parent one...

Categories