interactive icon indicating copy to clipboard operation
interactive copied to clipboard

System.ArgumentException on creation of XMLSerializer

Open the-programmer opened this issue 3 years ago • 8 comments

Describe the bug

At the moment I am trying to parse an XML into an C# object. (link to the XML)

So I made 3 objects:

[XmlRoot("astronomical-tide")]
public class Tide
{
    [XmlElement("location")]
    public string Location;
    
    [XmlElement("reference")]
    public string Reference;
    
    [XmlElement("timezone")]
    public string Timezone;

    [XmlElement("source")]
    public string Source;

    [XmlArray("values")]
    [XmlArrayItem("value")]
    public TideValue[] TideValues;
}


public class TideValue
{
    [XmlElement("datetime")]
    public DateTimeValue DateTimeValue;
	
    [XmlElement("tide")]
    public string Tide;

    [XmlElement("val")]
    public int Value;

    [XmlIgnore]
    public DateTimeOffset Date 
    {
        get
        {
            var dateTime = DateTime.ParseExact(DateTimeValue.CurrentDateTime.Trim(), "yyyyMMddHHmm", CultureInfo.InvariantCulture);
            
            TimeSpan timeZone;
            if(DateTimeValue.SummerTime == "yes")
                timeZone = new TimeSpan(2, 0, 0);
            else
                timeZone = new TimeSpan(1, 0, 0);

            return new DateTimeOffset(dateTime, timeZone);
        }
    }
}

public class DateTimeValue
{
    [XmlAttribute("summertime")]
    public string SummerTime;
    
    [XmlText]
    public string CurrentDateTime;
}

Edit: Fixed the serializer

However if I now try to construct a XML Serializer

using(var fs = new FileStream("./Westkapelle2022.xml", FileMode.Open))
{
    var serializer = new XmlSerializer(typeof(Tide));
}

I get an Error: System.ArgumentException: Identifier 'Submission#8' is not CLS-compliant. (Parameter 'ident').

Is this a bug in my code or in .net interactive?

Notes:

  • All the usings are in place
  • Both of the blocks of code are in the same code field
  • I tried to add an [DataContract] attribute, this had the same result

Please complete the following:

Which version of .NET Interactive are you using?: Version: 1.0.260601+9d1ecd3c06ba93e59bfef3842d2660c08d9e2ce5

  • OS
    • [ ] Windows 11
    • [x] Windows 10
    • [ ] macOS
    • [ ] Linux (Please specify distro)
    • [ ] iOS
    • [ ] Android
  • Frontend
    • [ ] Jupyter Notebook
    • [ ] Jupyter Lab
    • [ ] nteract
    • [x] Visual Studio Code
    • [ ] Visual Studio Code Insiders
    • [ ] Visual Studio
    • [ ] Other (please specify)

Screenshots

Well not a screenshot, but a dump of the stacktrace.

Error: System.ArgumentException: Identifier 'Submission#8' is not CLS-compliant. (Parameter 'ident')
at System.Xml.Serialization.CodeIdentifier.CheckValidIdentifier(String ident)
at System.Xml.Serialization.CodeIdentifier.EscapeKeywords(String identifier, StringBuilder sb)
at System.Xml.Serialization.CodeIdentifier.GetCSharpName(Type t, Type[] parameters, Int32 index, StringBuilder sb)
at System.Xml.Serialization.CodeIdentifier.GetCSharpName(Type t, Type[] parameters, Int32 index, StringBuilder sb)
at System.Xml.Serialization.CodeIdentifier.GetCSharpName(Type t)
at System.Xml.Serialization.TypeDesc.get_CSharpName()
at System.Xml.Serialization.SourceInfo.CastTo(TypeDesc td)
at System.Xml.Serialization.XmlSerializationWriterILGen.WriteElements(SourceInfo source, String enumSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, String arrayName, Boolean writeAccessors, Boolean isNullable)
at System.Xml.Serialization.XmlSerializationWriterILGen.WriteMember(SourceInfo source, String choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc memberTypeDesc, Boolean writeAccessors)
at System.Xml.Serialization.XmlSerializationWriterILGen.GenerateTypeElement(XmlTypeMapping xmlTypeMapping)
at System.Xml.Serialization.XmlSerializationWriterILGen.GenerateElement(XmlMapping xmlMapping)
at System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace)
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 Submission#8.<<Initialize>>d__0.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.CodeAnalysis.Scripting.ScriptExecutionState.RunSubmissionsAsync[TResult](ImmutableArray`1 precedingExecutors, Func`2 currentExecutor, StrongBox`1 exceptionHolderOpt, Func`2 catchExceptionOpt, CancellationToken cancellationToken)

the-programmer avatar Feb 01 '22 14:02 the-programmer

One note I would like to add is that, while attempting to fix my serialization objects, I needed to enable "Use a non-collectible load context for this query" in LINQPad 7.

However since I don't have the full version of LINQPad I can't use the nuget packages I need for the rest of the code.

the-programmer avatar Feb 02 '22 11:02 the-programmer

I have the same issue on F# in F# script. Trying to create serializer for a record

System.ArgumentException: Identifier 'FirstName@' is not CLS-compliant. (Parameter 'ident')
   at System.Xml.Serialization.CodeIdentifier.CheckValidIdentifier(String ident)
   at System.Xml.Serialization.XmlSerializationWriterILGen.WriteStructMethod(StructMapping mapping)
   at System.Xml.Serialization.XmlSerializationWriterILGen.GenerateMethod(TypeMapping mapping)
   at System.Xml.Serialization.XmlSerializationILGen.GenerateReferencedMethods()
   at System.Xml.Serialization.XmlSerializationWriterILGen.GenerateEnd()
   at System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace)
   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 <StartupCode$FSI_0022>.$FSI_0022_ThemisDSClient.main@()

Because for records with [<CLIMutable>] F# compiler creates public fields with names ending with @

xperiandri avatar Sep 15 '22 15:09 xperiandri

I wonder whether the serializer can be configured to work around this issue.

In both of these cases, the problem is that the underlying compiler implementation produces non-CLS compliant symbol names. These are behaviors (for differing reasons) of the C# and F# compilers, which is why I marked the issue as external. I don't expect we would be able to address them any time soon but opening issues in those repos might provide more insight.

jonsequitur avatar Sep 15 '22 16:09 jonsequitur

But why do you need to produce a CLS Compliant assembly?

xperiandri avatar Sep 15 '22 17:09 xperiandri

It is a script. It can be non compliant

xperiandri avatar Sep 15 '22 17:09 xperiandri

It is non-compliant. It's the XML serializer that has a problem with that.

jonsequitur avatar Sep 15 '22 17:09 jonsequitur

Do you mean that the XML serializer creates an assembly on the fly and marks it as CLS Compliant? Makes sense

xperiandri avatar Sep 15 '22 17:09 xperiandri

The script engines create assemblies as code is run. Those assemblies are non-CLS compliant. From the stack trace, it looks to me like the XML serializer doesn't like that. I'm not sure why that restriction would be in place. There might be a way to configure it to ignore it.

jonsequitur avatar Sep 15 '22 17:09 jonsequitur

Is there a workaround to this while we wait for someone in the C# compiler repo to fix it?

awa5114 avatar Sep 22 '23 10:09 awa5114