Home > database >  System.Text.Xml and Generic objects produce exception "Compiling JScript/CSharp scripts is not
System.Text.Xml and Generic objects produce exception "Compiling JScript/CSharp scripts is not

Time:11-17

Let's start with the following code (Please note the commented-out block):

public sealed class AnotherTest
{
    public sealed class MyBagContainer<T>
    {
        [XmlArray("Bag", Namespace = "myNs"),
            XmlArrayItem("li", Namespace = "myNs2")]
        public List<T> Items { get; set; } = new List<T> { };
    }

    public sealed class MyListableObject1
    {
        [XmlElement(Namespace = "myNs3")]
        public int SomeInt { get; set; }
    }

    public sealed class MyListableObject2
    {
        [XmlElement(Namespace = "myNs3")]
        public bool SomeBool { get; set; }
    }

    public sealed class SomeObject
    {
        public SomeObject()
        {
            Xmlns.Add("myNs", "http://example.com/ns");
            Xmlns.Add("myNs2", "http://example.com/ns2");
            Xmlns.Add("myNs3", "http://example.com/ns3");
        }

        [XmlElement(Namespace = "myNs2")]
        public MyBagContainer<MyListableObject1> MyBag1 { get; set; }
            = new MyBagContainer<MyListableObject1>
        {
            Items =
                {
                    { new MyListableObject1 { SomeInt = 42 } },
                    { new MyListableObject1 { SomeInt = 43 } }
                }
        };

        [XmlElement(Namespace = "myNs2")]
        public MyBagContainer<MyListableObject1> MyBag2 { get; set; }
            = new MyBagContainer<MyListableObject1>
            {
                Items =
                {
                    { new MyListableObject1 { SomeInt = 44 } },
                    { new MyListableObject1 { SomeInt = 45 } }
                }
            };

        /*
        [XmlElement(Namespace = "myNs2")]
        public MyBagContainer<MyListableObject2> MyBag3 { get; set; }
            = new MyBagContainer<MyListableObject2>
            {
                Items =
                {
                    { new MyListableObject2 { SomeBool = true } },
                    { new MyListableObject2 { SomeBool = false } }
                }
            };
        */

        [XmlNamespaceDeclarations]
        public XmlSerializerNamespaces Xmlns { get; set; }
            = new XmlSerializerNamespaces();
    }

    public void Run()
    {
        var obj = new SomeObject();

        using var ms = new MemoryStream();
        using var w = XmlWriter.Create(ms, new XmlWriterSettings
        {
            OmitXmlDeclaration = true,
            Indent = true
        });
        new XmlSerializer(obj.GetType())
            .Serialize(w, obj, obj.Xmlns);

        var s = System.Text.Encoding.UTF8.GetString(ms.ToArray());
        Console.WriteLine(s);
    }
}

When you run this, it works great. Creates everything exactly how it should be:

<SomeObject
    xmlns:myNs="http://example.com/ns"
    xmlns:myNs2="http://example.com/ns2"
    xmlns:myNs3="http://example.com/ns3">
  <MyBag1 xmlns="myNs2">
    <Bag xmlns="myNs">
      <li xmlns="myNs2">
        <SomeInt xmlns="myNs3">42</SomeInt>
      </li>
      <li xmlns="myNs2">
        <SomeInt xmlns="myNs3">43</SomeInt>
      </li>
    </Bag>
  </MyBag1>
  <MyBag2 xmlns="myNs2">
    <Bag xmlns="myNs">
      <li xmlns="myNs2">
        <SomeInt xmlns="myNs3">44</SomeInt>
      </li>
      <li xmlns="myNs2">
        <SomeInt xmlns="myNs3">45</SomeInt>
      </li>
    </Bag>
  </MyBag2>
</SomeObject>

Now, uncomment the block of code and run it again. You'll get this error:

System.PlatformNotSupportedException: 'Compiling JScript/CSharp scripts is not supported'

With this stack trace:

   at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location)
   at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace, String location)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type)
   at AnotherTest.Run() in AnotherTest.cs:line 92

Obviously, there are no scripts anywhere in this code.

I am assuming that's some generic error for "You put me in a pickle here, I may be able to serialize this, but how would I deserialize it?"

Is there any way to get XML serialization to work with generics? Or would I have to build the document manually (i.e. not using classes to define structure, but rather add items to an XmlDocument manually.)

The above structure has to stay as-is. I am working with a spec.

CodePudding user response:

Indeed, this error seems to be produced in several situations where the XmlSerializer encounters some limitations, ambiguities or inconsistencies.

Here, it seems to be a restriction of the XmlSerializer on .NET6 (on .NET Framework, your code works without problems). Without generics and with different XmlArray declarations ("Bag1" and "Bag2") below it works:

public sealed class MyBagContainer1
{
    [XmlArray("Bag1", Namespace = "myNs"),
        XmlArrayItem("li", Namespace = "myNs2")]
    public List<MyListableObject1> Items { get; set; } = new List<MyListableObject1> { };
}
public sealed class MyBagContainer2
{
    [XmlArray("Bag2", Namespace = "myNs"),
        XmlArrayItem("li", Namespace = "myNs2")]
    public List<MyListableObject2> Items { get; set; } = new List<MyListableObject2> { };
}

Both with the same name "Bag" produces the same error.

  • Related