Importing throws exception using generic version

69 views
Skip to first unread message

Greenosity

unread,
Oct 22, 2007, 4:06:55 PM10/22/07
to Jayrock
I am trying to deserialize a JSON string using the
JsonConvert.Import<T>(string text) version of Import but it's throwing
an exception. The exception message is:

Cannot import System.Collections.Generic.List`1[DocToSend] from a JSON
Array value.

My class 'T' is defined as:

public class DocToSend {
public int xmlid;
public List<int> seqs;

public DocToSend()
{
xmlid = -1;
seqs = new List<int>();
}

public DocToSend(int id)
{
xmlid = id;
seqs = new List<int>();
}
}

The exception occurs doing this:

List<DocToSend> itemsToSendList =
Jayrock.Json.Conversion.JsonConvert.Import<List<DocToSend>>(docdata);

docdata might contain the following string as an example:
[{"xmlid":23,"seqs":[1]},{"xmlid":19,"seqs":[1]},{"xmlid":26,"seqs":
[3,4,5]}]

I am expecting a System.Collections.Generic.List<DocToSend> after
deserialization. What do I need to do to get this working?

BTW, I have tried Newtonsoft's version of this same functionality,

List<DocToSend> itemsToSendList =
Newtonsoft.Json.JavaScriptConvert.DeserializeObject<List<DocToSend>>(docdata);

and it works perfect. However, I would rather stick to a single
library (Jayrock) if it has the ability to deserialize JSON strings to
C# objects.

Tom

unread,
Oct 23, 2007, 10:40:51 AM10/23/07
to Jayrock
On Oct 22, 10:06 pm, Greenosity <greenos...@gmail.com> wrote:
> I am trying to deserialize a JSON string using the
> JsonConvert.Import<T>(string text) version of Import but it's throwing
> an exception. The exception message is:
>
> Cannot import System.Collections.Generic.List`1[DocToSend] from a JSON
> Array value.

Hello
I have a similar problem, and here's a quick fix, which may help you
until some better solution comes out:
(I must admit that I'm too lazy to read all the Jayrock code, so this
is the first thing that I tried, it worked, and I'll leave it like
this :)

public class GenericListImporter<T>: ImporterBase
{
public GenericListImporter(): base(typeof(IList<T>)) { ; }

protected override object ImportFromArray(ImportContext context,
JsonReader reader)
{
reader.Read();
List<T> list = new List<T>() ;
Type elementType = typeof(T) ;
while (reader.TokenClass != JsonTokenClass.EndArray)
list.Add( (T)context.Import(elementType, reader) );

reader.Read();
return list.ToArray() ;
}
}

and register this in your config file like this:

<importer
type="MyNamespace.GenericListImporter`1[[MyNamespace.DocToSend,
MyAssembly]], MyAssembly" />

HTH, Tom

Greenosity

unread,
Oct 23, 2007, 10:59:35 AM10/23/07
to Jayrock
Tom,

Thanks for the suggestion. However, I've decided to use Newtonsoft's
JSON functionality instead. Without having to modify any code or add
anything to my web app's config file, I can make a single call to its
'DeserializeObject' method and it works. Newtonsoft's JSON library
also provides the only other JSON feature I need at the moment
(JsonWriter).

A problem with both both Newtonsoft and Jayrock is the severe lack of
documentation. If I'm going to use a third party library in the code
I'm adding to my company's project(s), we need good documentation. If
somebody else on the team needs to modify the code later, they have to
learn by trial and error just like I'm doing. Not good.

Tomislav Tustonic

unread,
Oct 23, 2007, 11:59:46 AM10/23/07
to jay...@googlegroups.com
Greenosity wrote:
> Tom,
>
> Thanks for the suggestion. However, I've decided to use Newtonsoft's
> JSON functionality instead. Without having to modify any code or add
> anything to my web app's config file, I can make a single call to its
> 'DeserializeObject' method and it works. Newtonsoft's JSON library
> also provides the only other JSON feature I need at the moment
> (JsonWriter).
>
> A problem with both both Newtonsoft and Jayrock is the severe lack of
> documentation. If I'm going to use a third party library in the code
> I'm adding to my company's project(s), we need good documentation. If
> somebody else on the team needs to modify the code later, they have to
> learn by trial and error just like I'm doing. Not good.

Yes, that's the common problem with many open source libraries,
especially small ones, with a single developer, like Jayrock.
However, I played a bit with the exporters and using custom type
descriptors to export objects for various purposes, and I really
like this stuff, it's very powerful.
In my application I created a simple custom type descriptor builder,
which can build CTD from the object and subobject properties, and,
using this, I created 2-3 custom type descriptors per type,
one is for 'grid view', other for 'details view', so I can send
just the data that I want to show on my UI, instead of deep
object graphs. I'm using NHibernate with my domain model, so object
graphs become very deep very quickly. It's also quite easy to
end up with the circular reference, which can't be exported. At
first I was constantly changing my NH mappings and business objects,
but it wasn't going anywhere, so I looked deeper and now I'm glad
I did :)
The next step would be to make some mapping file or something, so
that I can change CTD from the config file, or perhaps I could make
my API customizable by client. For example, the customer could say
'send me the list of these objects, but give me only these
properties'. Also, it's easy to change CTD depending on the
user roles and similar.
So... I believe that this effort has already paid, and it will
give me an opportunity to build something that otherwise would be
quite hard.
Ah, and, once in a blue moon I write some small pieces of documentation
on our wiki, so people who come after will have something to read :)

Cheers, Tom

Tom

unread,
Oct 23, 2007, 4:47:13 PM10/23/07
to Jayrock
Fix... in the last line, instead of:

return list.ToArray() ;

should be just:

return list ;


Atif Aziz

unread,
Oct 26, 2007, 12:36:53 PM10/26/07
to jay...@googlegroups.com
> I must admit that I'm too lazy to read all the Jayrock code,
> so this is the first thing that I tried, it worked, and
> I'll leave it like this :)

Tom, you're definitely in the right direction. :)

Atif Aziz

unread,
Oct 26, 2007, 12:53:10 PM10/26/07
to jay...@googlegroups.com
> A problem with both both Newtonsoft and Jayrock is
> the severe lack of documentation.

There is some documentation here:
http://msdn2.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_topic5

It's far from ideal, though and, I agree with your comment in general. The lack of documentation is also why I do spend time in this group to help whenever possible. Unfortunately, you just caught me during an overloaded week (upgrading my laptop to Vista didn't help) and I am grateful that Tom stepped in to help as well.

> If I'm going to use a third party library in the code I'm adding
> to my company's project(s), we need good documentation.

Don't forget, it's free beer. ;) Seriously, if anyone wants to help write some articles or tutorials as wikis then I can try to setup the infrastructure. Is this too much to expect?

-----Original Message-----
From: jay...@googlegroups.com [mailto:jay...@googlegroups.com] On Behalf Of Greenosity
Sent: Tuesday, October 23, 2007 5:00 PM
To: Jayrock
Subject: [Jayrock] Re: Importing throws exception using generic version

Atif Aziz

unread,
Oct 26, 2007, 1:07:04 PM10/26/07
to jay...@googlegroups.com
> What do I need to do to get this working?

Just want to point out a design issue here that may tell you why this is not supported out-of-the-box. Your "seq" field is typed as List<int> whereas List<T> is not designed or meant to be publicly exposed. It's a private implementation class provided for convenience. You should really be typing "seq" as IList<int>. This first bit has nothing to do with Jayrock. It's simply about the public API design of a class. This is the same reason that Jayrock was not unnecessarily bloated to import Hashtable or ArrayList auto-magically. They're just concrete implementations of IDictionary and IList. One should be working with the latter across sub-systems. This has been mentioned before over at:

http://groups.google.com/group/jayrock/browse_thread/thread/e7dc5452e4664be5

So you should type "seq" as IList<int> even though that doesn't help you immediately with Jayrock. :) Json.NET gets away with this because it has support for C# 2.0 generics whereas Jayrock is still maintaining compatibility with C# 1.x (though it's open enough architecturally to work in generics by adding generic importers and exporters). Also, Json.NET is hard-wired for quite a few special cases whereas Jayrock entertains the 80% well-defined cases and provides hooks for the rest.

-----Original Message-----
From: jay...@googlegroups.com [mailto:jay...@googlegroups.com] On Behalf Of Greenosity
Sent: Monday, October 22, 2007 10:07 PM
To: Jayrock

Atif Aziz

unread,
Oct 26, 2007, 1:07:56 PM10/26/07
to jay...@googlegroups.com
I've just finished and committed a sample that demonstrates converting to and from JSON via importers and exporters as well as logical typing via ICustomTypeDescriptor:
See: http://svn.berlios.de/wsvn/jayrock/trunk/samples/JsonConversionsDemo/?rev=588

In there, you'll find a pretty thorough exploration of importing lists and collections using generics and duck-typed approaches. The latter is really for folks stuck with C# 1.x. At one point, it may make sense to move the importer and exporter classes into the core library.

Hopefully this should help until the documentation comes along.

-----Original Message-----
From: jay...@googlegroups.com [mailto:jay...@googlegroups.com] On Behalf Of Tom
Sent: Tuesday, October 23, 2007 4:41 PM
To: Jayrock

Atif Aziz

unread,
Oct 26, 2007, 1:14:08 PM10/26/07
to jay...@googlegroups.com
>>
I played a bit with the exporters and using custom type
descriptors to export objects for various purposes, and I really
like this stuff, it's very powerful.
<<

Tom, good to see you "getting it." It looks though that not a lot of folks seem to catch on the ICustomTypeDescriptor hint. I was hoping that by leveraging standard interfaces from the base framework like ICustomTypeDescriptor, the model and problem domain would be well understood and therefore wouldn't need further documentation. :)

>>
I write some small pieces of documentation
on our wiki, so people who come after will have something to read :)
<<

Would any of this documentation also make public soup?

-----Original Message-----
From: jay...@googlegroups.com [mailto:jay...@googlegroups.com] On Behalf Of Tomislav Tustonic
Sent: Tuesday, October 23, 2007 6:00 PM
To: jay...@googlegroups.com
Subject: [Jayrock] Re: Importing throws exception using generic version

Atif Aziz

unread,
Oct 26, 2007, 1:19:47 PM10/26/07
to jay...@googlegroups.com
The JSON conversions sample should also be downloadable from ftp://ftp.berlios.de/pub/jayrock as part of the latest build in 6 to 7 hours from now. Otherwise, it can always be exported or downloaded from the repository.

Tomislav Tustonic

unread,
Oct 27, 2007, 1:07:33 AM10/27/07
to jay...@googlegroups.com
Atif Aziz wrote:
> I played a bit with the exporters and using custom type
> descriptors to export objects for various purposes, and I really
> like this stuff, it's very powerful.
> <<
>
> Tom, good to see you "getting it." It looks though that not a lot of folks seem to catch on the ICustomTypeDescriptor hint. I was hoping that by leveraging standard interfaces from the base framework like ICustomTypeDescriptor, the model and problem domain would be well understood and therefore wouldn't need further documentation. :)
>
> I write some small pieces of documentation
> on our wiki, so people who come after will have something to read :)
> <<
>
> Would any of this documentation also make public soup?
>

mmm, no, unfortunately. It's all in Croatian, and it's
quite specific to the application I write, and describes
how I Jayrock and Ext to solve some specific problems...
I have (quite old) tutorial about Ext and Jayrock here:
http://extjs.com/learn/Tutorial:Jayrock_with_Ext
I'm not using this approach any more, but anyway...

Cheers, Tom

Tomislav Tustonic

unread,
Oct 27, 2007, 1:21:56 AM10/27/07
to jay...@googlegroups.com
Atif Aziz wrote:
> I played a bit with the exporters and using custom type
> descriptors to export objects for various purposes, and I really
> like this stuff, it's very powerful.
> <<
>
> Tom, good to see you "getting it." It looks though that not a lot of folks seem to catch on the ICustomTypeDescriptor hint. I was hoping that by leveraging standard interfaces from the base framework like ICustomTypeDescriptor, the model and problem domain would be well understood and therefore wouldn't need further documentation. :)
>

eh... the problem could be that perhaps not many people use CTDs.
I didn't even look there before I found Jayrock, and I probably
wouldn't if I didn't already have almost finished application
for which I didn't feel like changing and modifying model, so I
had to find a different way to export my data. And I'm really
glad I did :)

Anyway... I think that some small piece is missing, and that is
the way to dynamically use and switch exporters, based on some
changeable criteria. At the moment I just stuff my CTDs in
HttpContext, and read them in Exporters, but it feels 'hackish'
and there should be something better. I was hoping to use
ExportContext.Register, or something, but didn't find the way.
Or, perhaps I'm missing something?

Cheers, Tom

Atif Aziz

unread,
Oct 27, 2007, 7:03:30 AM10/27/07
to jay...@googlegroups.com
> way to dynamically use and switch exporters, based on some
> changeable criteria

Could you elaborate? What kind changeable criteria? What's your scenario with need to switch exporters dynamically?

> I was hoping to use
> ExportContext.Register, or something, but didn't find the way.
> Or, perhaps I'm missing something?

Why not register the exporters in the configuration file?

-----Original Message-----
From: jay...@googlegroups.com [mailto:jay...@googlegroups.com] On Behalf Of Tomislav Tustonic
Sent: Saturday, October 27, 2007 7:22 AM
To: jay...@googlegroups.com
Subject: [Jayrock] Re: Importing throws exception using generic version

Tom

unread,
Oct 29, 2007, 8:39:37 AM10/29/07
to Jayrock
> Could you elaborate? What kind changeable criteria? What's your scenario with need to switch exporters dynamically?

For example, I'd like to export different data for grid
and details view. At the moment, for each of my types I build
custom type descriptor with the necessary field/property
names, which also flatten my objects where needed. Soon I'll
need to restrict some fields based on user roles and privileges
etc. This CTD is then used by my exporter to export data.
I can use single exporter per type, which is nice, but in a
few cases it seemed easier, and is probably faster, to create
dedicated exporter instead.

> > I was hoping to use
> > ExportContext.Register, or something, but didn't find the way.
> > Or, perhaps I'm missing something?
>
> Why not register the exporters in the configuration file?
>

They are registered. In fact, I only have a single generic exporter
which is registered for all the types I have, and it only reads
custom type descriptor(s) from HttpContext and exports accordingly.

Here's a short description how I use it at the moment, perhaps I'm
doing something completely stupid...

Basically I have a handler per type, and each handler has a few
methods, like GetById, List, etc. In each method I decide what
CTDs I need, build them and put it in the HttpContext. Later, in
my exporter, I read it from the context and export. This all works
quite well, but it doesn't feel right... it's like a "spooky action
at a distance" as Einstein called it :) IMHO it would be nicer if
these steps were 'local', and not spread across two or more different
places in the application, which do not seem connected.
For each new type I'd have to explain how it works and why it works,
and what steps should be done to export it. Also, exporter needs a
HttpContext, which makes it hard to test properly etc.
I hope this all makes sense. Perhaps I'm doing something really wrong,
or you have a better way to do it.

Earlier I made a small modification to Jayrock to register exporters
per request, but I don't have it anymore, since I didn't want to
depend on my hacked version :)

Cheers, Tom

Atif Aziz

unread,
Oct 29, 2007, 1:14:52 PM10/29/07
to jay...@googlegroups.com
Hi Tom,

I think I managed to wrap my head around what you're doing but I still can't see exactly why you really need to do it that way and how it would translate into a more general case. It seems to me that you need to return looser types from your service methods (considering that you need to change the shape of types on a per-request basis) but I could be wrong or not in a position to answer being on the outside. If you believe this is a very general problem that will certainly bite others as well then perhaps we can setup a general example and work from there? Passing around context is always an issue as you mix and match frameworks. Even if Jayrock provided one on a per-request basis where you could dynamically replace exporters, you would have to take care of it as a concrete dependency instead of HttpContext.

- Atif

-----Original Message-----
From: jay...@googlegroups.com [mailto:jay...@googlegroups.com] On Behalf Of Tom
Sent: Monday, October 29, 2007 1:40 PM
To: Jayrock
Subject: [Jayrock] Re: Importing throws exception using generic version

Reply all
Reply to author
Forward
0 new messages