5

In my universal windows app I am storing user data transforming its objects into xml files through XmlSerializer.

The app was compiling, building and running perfectly until somehow (without any change on the code) the build for release started to give me this error: System.InvalidOperationException: Unable to generate a temporary class (result=1).

If I build or run the app on debug it works flawlessly but on release (with has the .NET native tool chain active) I get the error.

I already given permission on C:\Windows\Temp folder to everyone. Even my mother has access to it but the error remains.

If it really is a read/write problem on the XmlSerializer I wonder if there is any way to change the serializer temp folder on UWP project.

Here is the code that I used to serialize objects:

    public static async Task<T> ReadObjectFromXmlFileAsync<T>(string filename)
    {
        // this reads XML content from a file ("filename") and returns an object  from the XML
        T objectFromXml = default(T);
        var serializer = new XmlSerializer(typeof(T));
        StorageFolder folder = ApplicationData.Current.LocalFolder;
        StorageFile file = await folder.GetFileAsync(filename).AsTask().ConfigureAwait(false);
        Stream stream = await file.OpenStreamForReadAsync().ConfigureAwait(false);
        objectFromXml = (T)serializer.Deserialize(stream);
        stream.Dispose();
        return objectFromXml;
    }

    public static async Task SaveObjectToXml<T>(T objectToSave, string filename)
    {
        // stores an object in XML format in file called 'filename'
        var serializer = new XmlSerializer(typeof(T));
        StorageFolder folder = ApplicationData.Current.LocalFolder;
        StorageFile file = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting).AsTask().ConfigureAwait(false);
        Stream stream = await file.OpenStreamForWriteAsync().ConfigureAwait(false);

        using (stream)
        {
            serializer.Serialize(stream, objectToSave);
        }
    } 

    //This uses a subfolder
    public static async Task<T> ReadObjectFromXmlFileAsync<T>(string filename)
    {
        // this reads XML content from a file ("filename") and returns an object  from the XML
        T objectFromXml = default(T);
        var serializer = new XmlSerializer(typeof(T));
        StorageFolder folder = ApplicationData.Current.LocalFolder;
        StorageFolder subFolder = await folder.GetFolderAsync("Notes").AsTask().ConfigureAwait(false);
        StorageFile file = await subFolder.GetFileAsync(filename).AsTask().ConfigureAwait(false); 
        Stream stream = await file.OpenStreamForReadAsync().ConfigureAwait(false);
        objectFromXml = (T)serializer.Deserialize(stream);
        stream.Dispose();
        return objectFromXml;
    }

What am I missing? Can anyone help?

chue x
  • 18,573
  • 7
  • 56
  • 70
Daniel
  • 273
  • 4
  • 18
  • If you turn on Diagnostic level logging there may be more clues. If that's not elucidating, please feel free to mail us at dotnetnative@microsoft.com. Not that folks won't be in the office until Tuesday because of the MLK day holiday. – MattWhilden Jan 16 '16 at 00:03
  • 1
    I think in your case doing a T temp = default(T) will use reflection and the .NET Native compiler will try to build "temp" object to hold whatever data it needs to serialize or deserialize, but knows nothing about, resulting in a KABOOM. obj.GetType would do this for me in VB.net. Make that bad boy a variant without creating a default type and I think you will be ok. – sonofsmog May 25 '17 at 02:19

3 Answers3

0

Are you referencing projects with the XML serialization files being “Added as Link” in them by any chance? (That what caused the aforementioned error in my case) In that case here is the...

...SOLUTION:

Apparently, you still can use the “Added as Link” way of code sharing, but in order to enable “Compile with .NET Native tool chain” without any of those obscure irrelevant errors, the “Added as Link” files need to be moved to the caller project.

Alex Pigida
  • 117
  • 2
  • 5
0

Just came here to help any other that runs into this problem. It seems that when .NET native is compiling you will run into problems if you have classes that will be Xml serialized/deserialized which contain references to stuff like HorizontalAlignment and VerticalAlignment. Really annoying, I am currently using Visual Studio Update 3 and I still have this problem.

For a better explanation see this stack overflow answer:

http://stackoverflow.duapp.com/questions/37680536/cant-build-uwp-in-release-mode/37865469#37865469

Johan O
  • 402
  • 5
  • 7
0

I have the exact same error with this nearly identical code:

Public Async Function SerializeObjectToStorage(ByVal obj As Object, ByVal filename As String) As Task(Of Boolean)
    Dim localFolder As Windows.Storage.StorageFolder
    Try
        Dim objStringWriter As New StringWriter
        Dim x As New XmlSerializer(obj.GetType)
        x.Serialize(objStringWriter, obj)
        localFolder = Windows.Storage.ApplicationData.Current.LocalFolder
        Dim myFile As Windows.Storage.StorageFile = Await localFolder.CreateFileAsync(filename, Windows.Storage.CreationCollisionOption.ReplaceExisting)
        Dim stream = Await myFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite)
        Using outputStream = stream.GetOutputStreamAt(0)
            Dim dataWriter As New DataWriter(outputStream)
            dataWriter.WriteString(objStringWriter.ToString)
            Await dataWriter.StoreAsync()
            Await outputStream.FlushAsync()
            stream.Dispose()
        End Using
    Catch ex As Exception
        Return False
    End Try
    Return True
End Function
Public Async Function DeserializeStorageToObject(ByVal obj As Object, ByVal filename As String) As Task(Of Object)
    Dim localFolder As Windows.Storage.StorageFolder
    Try
        Dim objStringWriter As New StringWriter
        Dim x As New XmlSerializer(obj.GetType)
        x.Serialize(objStringWriter, obj)
        localFolder = Windows.Storage.ApplicationData.Current.LocalFolder
        Dim myFile As Windows.Storage.StorageFile = Await localFolder.GetFileAsync(filename)
        Dim stream = Await myFile.OpenAsync(Windows.Storage.FileAccessMode.Read)
        Dim size = stream.Size

        Using inputStream = stream.GetInputStreamAt(0)
            Dim dataReader As New DataReader(inputStream)
            Dim numBytesLoaded As UInteger = Await dataReader.LoadAsync(CUInt(size))
            Dim text As String = dataReader.ReadString(numBytesLoaded)
            Using tr = New StringReader(text)
                obj = x.Deserialize(tr)
                Return obj
            End Using
            stream.Dispose()
        End Using
    Catch ex As Exception
        Return Nothing
    End Try
    Return True
End Function

My conclusion is that is that the .NET Native compiler actually tries to serialize whatever types you are trying to serialize whatever objects your are trying to serialize with that code. In my case the type was a simple one like this:

Public Class Result
    Public Property ElementName As String
    Public Property Id As Integer
    Public Property Name As String
End Class
Public Class GetValues
    Public Property Count As Integer
    Public Property Message As String
    Public Property SearchCriteria As String
    Public Property Results As Result()
End Class

However, These exact same functions do not fail to serialize an object with a data contract from a WCF service. So I guess maybe it needs to be an ObservableCollection of your type. I haven't tried that yet. I will update this with the answer.

sonofsmog
  • 87
  • 1
  • 2