1

I'm trying to convert a 2sxc App.Data to a json string.

I tried :

using System.Web.Script.Serialization;

    var org = (IEnumerable<dynamic>)AsDynamic(App.Data["MyData"])
                .Where(s => (s.Show == true ))
                .OrderBy(n => n.Name);
    string retour = new JavaScriptSerializer().Serialize(org);

but I have an error Exception has been thrown by the target of an invocation.

Any idea how to return a json string of these data?

Thank you!

2 Answers2

1

There are at least three ways of doing this. Two things you must know:

  1. raw entities can refer to other entities (as they could have relationships). If you just do a trivial serialization, you might easily run into infinite loops (which are stopped after a few recursions)
  2. internally every value can be multi-language, so the raw internal format may not be ideal for whatever you're trying to do.

Now let's look at your scenario: I assume you are in a Razor or WebApi, and want to provide the items either as hidden HTML - like a <div data='{somejson}'> or to return it from a WebApi - for further use. I'll also assume you don't care too much about languages or related items - meaning you don't want the full data, just a basic read.

Let's look at your options:

(not recommended) the easiest for you to fully control would be to create a dictionary with the values, and serialize that

(recommended) the way EAV and 2sxc do it is to prepare data for serialization, and then let the serializer take it from there. To achieve this, there is a Serializer-object in the EAV which you can use. You'll find it in most API calls in the source of the EAV / 2sxc - the syntax is usually something like

var Serializer = new ToSic.Eav.Serializers.Serializer();
return Serializer.Prepare(single-entity-or-Ienumerable-of-entities);

this actually does what I mentioned before - it creates a Dictionary<field-name, value-object> which any serializer can then use. Related items are automatically converted into a list of id+title combinations, so you can work with them in JS, but without delivering the entire tree of all sub-items.

Hope this helps ;)

iJungleBoy
  • 5,325
  • 1
  • 9
  • 21
  • Thank you Daniel, this is really clear. You perfectly understood the context. I tried that in my controller but I receive this error: error CS1502: The best overloaded method match for 'ToSic.Eav.Serializers.Serializer.Prepare(ToSic.Eav.DataSources.IDataSource, System.Collections.Generic.IEnumerable)' has some invalid arguments My code seems pretty simple: var org = IEnumerable)AsDynamic(App.Data["Organisms"]) ; var Serializer = new ToSic.Eav.Serializers.Serializer(); return Serializer.Prepare(org); Any idea why I'm having this error? Thank you! – Frédéric Laurent Nov 29 '17 at 00:59
  • your org-object seems to have the wrong type. The Prepare seems to expect an IEntity or IEnumerable. your `org` is IEnumerable. try AsEntity(org). Since AsEntity can only handle 1 item at a time, you'll proabably need something like `var org2 = org.Select(AsEntity);` – iJungleBoy Nov 29 '17 at 11:56
  • @iJungleBoy, were there any changes made regarding this one? I'm getting `error CS0234: The type or namespace name 'Serializers' does not exist in the namespace 'ToSic.Eav' (are you missing an assembly reference?)` – Constantine Ketskalo Oct 19 '21 at 19:34
  • This was deprecated a long time ago. If you're updating to v11 there is a replacement on `ToSic.Sxc.Conversion.DataToDictionary` - but this is also deprecated in v12 (but will continue to work) because it doesn't use DI properly. in v12 we strongly suggest you use the new service on https://docs.2sxc.org/api/dot-net/ToSic.Eav.DataFormats.EavLight.IConvertToEavLight.html - so code it like `var prepared = GetService().Convert(...);` – iJungleBoy Oct 25 '21 at 09:31
0

It works perfectly. Thank you very much !

For the records, here is the working code (DNN 9.1.1 / 2sxc 9.11.1) to expose the data from a simple table (no relationship) in a SxcApiController with the ability to manipulate the data before exposing them. The idea is to add manipulations that can't be done in the visual query.

[HttpGet]   
[AllowAnonymous]
public string showAllOrganisms()
{
     IEnumerable<dynamic> org = (IEnumerable<dynamic>)AsDynamic(App.Data["Organisms"])
         .Where(s => (s.Show == true ))
         .OrderBy(n => n.Name);

     var org2 = org.Select(AsEntity);

     var Serializer = new ToSic.Eav.Serializers.Serializer();
     var prepared = Serializer.Prepare(org2);

     var jss = new JavaScriptSerializer();
     var retour = jss.Serialize(prepared);

     return retour;
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • FYI: `ToSic.Eav.Serializers` was deprecated a long time ago. If you're updating to v11 there is a replacement on `ToSic.Sxc.Conversion.DataToDictionary` - but this is also deprecated in v12 (but will continue to work) because it doesn't use DI properly. in v12 we strongly suggest you use the new service on https://docs.2sxc.org/api/dot-net/ToSic.Eav.DataFormats.EavLight.IConvertToEavLight.html - so code it like `var prepared = GetService().Convert(...);` – iJungleBoy Oct 25 '21 at 09:35