Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
35
Save column filter to XML not working
posted

Hello all,

currently I'm developing a feature to persist the UltraGrid filter configuration to a local file. Due to the fact that even more configurations (beside the grid configuration) already stored in a XML file the goal is to extend the XML with the UltraGrid filter configuration.

I tried different ways to achieve the goal but I run into multiple problems and currently there is no idea how to handle them.

The overall algorithem to store the data in the XML file (1-3) and load the saved data (4-6) looks like the folling steps:

  1. Create a object of the structure which contains the configurations
  2. Assign the data to the structure properties
  3. Serialize the object to an XML file using the XMLSerializer

  4. Load the XML file as a stream
  5. Deserialize the XML using the XMLSerializer
  6. Assign the values of the properties to the grid

I tried the following ways to include the filter settings into this algorithem (step 2):

Use DisplayLayout.SaveAsXML Method
This is not working because the method isn't supported in .net5:

==> We using WinGrid Version 21.1.24 - is this method supported in newer versions? In case of yes, I think using the method would solve our problem.

Use DisplayLayout.Save Method - No base 64 encoding

Due to the restrictions mentiond, I tried to use the Save method to serialize the filter. The input stream of the Save method is casted to a StreamReader and later on to a string. This string is assigned to as property of the class which will serialized to the XML.

As a result I get a HTML encoded string in the XML file (the HTML encoding is automatically done by the XMLSerializer). When the XMLSerializer tries to deserialize the XML file (step 5) there is an exception that the XML is invalid (I think based on the HTML encoding).

The same exception is thrown when I HTMLDecode the XML before the deserialization.

This is the relevant part of the code:

/ /SERIALIZATION
using (var memStream = new MemoryStream()) {
this.DisplayLayout.Save(memStream, PropertyCategories.ColumnFilters);
StreamWriter sw = new StreamWriter(memStream);
sw.Flush();

memStream.Position = 0;
StreamReader sr = new StreamReader(memStream);

string temp = sr.ReadToEnd();

gridSettings.FilterSettings = temp;
//gridSettings.FilterSettings = Convert.ToBase64String(Encoding.UTF8.GetBytes(temp));

sr.Dispose();
sw.Dispose();
}

using (var stream = new MemoryStream())
{
var serializer = new XmlSerializer(gridColumnSettings.GetType());
serializer.Serialize(stream, gridColumnSettings);

var s = Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length);
return s;
}

// DESERIALIZATION
using (var stream = new StringStream(serializedData))
{
var serializer = new XmlSerializer(typeof(GridSettings));
var deserializedGridSettings = (GridSettings)serializer.Deserialize(stream);

using (var ms = new MemoryStream())
{
var sw = new StreamWriter(ms);

var temp = WebUtility.HtmlDecode(deserializedGridSettings.FilterSettings);
//var temp = Encoding.UTF8.GetString(Convert.FromBase64String(deserializedGridSettings.FilterSettings));

sw.Write(temp);
sw.Flush();
ms.Position = 0;

this.DisplayLayout.Load(ms, PropertyCategories.ColumnFilters);
}
}

=> Not working for our use case

Use DisplayLayout.Save Method - With base 64 encoding

To bypass the problem with the HTML encoding I tried to use a base64 encoding. The algorithm includes the following steps:

  1. Call DisplayLayout.Save Method to get the configuration stream
  2. Save the stream to a string and convert it to a Base64 string
  3. Write the Base64 string to the property and save it to the XML file

This is working fine and as a result the Base64 string is saved to the XML (without some HTML encoding).

Loading the XML and deserialize it is working now, but when the Base64 string is decoded and passed to the DisplayLayout.Load Method by wrapping it in a stream an exception with the message No map for object '201326592'. is thrown (see also Post here). By debugging the application I see that the string which is passed to the Load method is the same as the string that is created by the Save method.

--> Code see code snipet above with the base64 comments

=> Not working for my use case. Is there maybe a but at the Load method?

Serialize the FilterConditionsCollection or ColumnFilter class using the XMLSerializer

As a last way I tried to assign the ColumnFilter or FilterConditionsCollection object of the colum to the custom structure property which is serialized to the XML (step 2) but during the serialization process an exception is thrown because there is no parameterless constructure available for ColumnFilter or FilterConditionsCollection and subclasses of them.

=> Not working.

As a result my questions are:

  • Is the SaveAsXML method supported in net5.0 within a newer version?
  • Is the No map for object '201326592' error a bug and maybe solved in a newer version?
  • What is the recommended way to handle the use case?

by the way, saving the configuration by the Save method to a new txt file and load that file again is working without problems, but this is no solution for our problem. 

Thank you and best regards

Sebastian

Parents
  • 7375
    Offline posted

    Hello , 

    Thank you for your post. Yes you are right LoadFromXml and SaveAsXml methods are not present on the UltraGrid.DisplayLayout in .NET 5/.net 6. The reason for this is because Microsoft discontinued the SoapFormatter class in .NET Core, which the methods in question used extensively.

    Luckily, we do expose other methods to save and load the layout of the UltraGridLayout via the Save and Load methods. These will save to binary, and so if you have an XML file that needs to be loaded, I would recommend that you first load it in a .NET Framework application and then re-save it using the Save method.

Reply Children
No Data