RestSharp - Serialize list without parent element - xml-serialization

I've seen similar questions on SO about this, but this is specifically about RestSharp XmlSerializer.
I want this:
<Item>
...
</Item>
<Item>
...
</Item>
<Item>
...
</Item>
<Item>
...
</Item>
I have this:
public class MyPoco
{
[SerializeAs( Name = "Item")
public List<Item> Items { get; set; }
}
public class Item
{
...
}
What I'm getting is this:
<Item>
<Item>
...
</Item>
<Item>
...
</Item>
<Item>
...
</Item>
</Item>
How do I get rid of the parent element when using RestSharp?

Change SerializeAs to XmlElement:
[XmlElement("Item")]
public List<Item> Items { get; set; }
Then tell RestSharp to use the .NET serializer:
var request = new RestRequest
{
XmlSerializer = new RestSharp.Serializers.DotNetXmlSerializer(),
};
This will output your list of Items without the parent Item node

That will help:
public class MyPoco : List<Item> {}
public class Item { ... }

Related

Bound items display as name of item type, instead of contents of each item

//My Model
public class BookInfo
{
public string BookName { get; set; }
public string BookDescription { get; set; }
}
//my View Model
public ObservableCollection<BookInfo> Bookmodel { get; set; }
public BookRepoInfo()
{
Bookmodel = new ObservableCollection<BookInfo> { //**is this correct way.**
new BookInfo { BookName = "Object-Oriented Programming in C#", BookDescription = "Object-oriented programming is a programming paradigm based on the concept of objects" },
......
};
}
XAML page:
<ContentPage.BindingContext>
<local:BookRepoInfo />
</ContentPage.BindingContext>
<X:YList ItemsSource="{Binding Bookmodel}"></X:YList>
Load the list item using MVVM pattern
Assuming that YList is either a inheritance from ListView or CollectionView, you'll need to provide some sort of template which you want to apply to each cell of that list.
Right now what is happening is that it will just call the ToString() on the object that you put in.
Change your code to be something like:
<X:YList ItemsSource="{Binding Bookmodel}">
<X:YList.ItemTemplate>
<DataTemplate>
<VerticalStackLayout>
<Label Text="{Binding BookName}"/>
<Label Text="{Binding BookDescription}"/>
</VerticalStackLayout>
</DataTemplate>
</X:YList.ItemTemplate>
</X:YList>
More information is here: https://learn.microsoft.com/dotnet/maui/user-interface/controls/collectionview/populate-data?view=net-maui-7.0#define-item-appearance

'Specified cast is not valid' when I reload listview items - Xamarin Forms

I'm trying to make an app that saves subjects into an SQLite database and I'm facing an exception: 'Specified cast is not valid'. That happens when I reload the listview items.
(SubjectViewModel.UpdateSubjects())
I receive the data from SubjectServices static class, with async connection.
I set the contentpage binding context to this viewmodel and then set the listview itemssource's binding the SubjectViewModel's SubjectList.
XAML code:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:resx="clr-namespace:MyApp.Resources"
x:Class="MyApp.View.ShellPages.SubjectsPage">
<ContentPage.ToolbarItems>
<ToolbarItem Text="{x:Static resx:AppResources.NewSubject}"
Command="{Binding SubjectNewSCommand}"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<ListView x:Name="subjectListView" ItemsSource="{Binding SubjectList}"
IsRefreshing="True" RefreshCommand="{Binding SubjectRefreshCommand}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" Detail="{Binding AddedTime, StringFormat='{0:d}'}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
SubjectViewModel:
using MyApp.Model;
using MyApp.View.ShellPages;
using MyApp.ViewModel.Commands;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
namespace MyApp.ViewModel
{
public class SubjectViewModel
{
public ObservableCollection<Subject> SubjectList { get; set; }
public SubjectPageRefreshCommand SubjectRefreshCommand { get; set; }
public SubjectNewSubjectCommand SubjectNewSCommand { get; set; }
public SubjectViewModel()
{
SubjectRefreshCommand = new SubjectPageRefreshCommand(this);
SubjectNewSCommand = new SubjectNewSubjectCommand(this);
SubjectList = new ObservableCollection<Subject>();
}
public async void UpdateSubjects()
{
var subjectList = await SubjectServices.GetSubjects();
SubjectList.Clear();
foreach (var subject in subjectList)
SubjectList.Add(subject);
}
public async void Navigate()
{
await App.Current.MainPage.Navigation.PushAsync(new NewSubjectPage());
}
}
}
Subject class:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using SQLite;
namespace MyApp.Model
{
public class Subject
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
[MaxLength(50)]
public string Name { get; set; }
public DateTime AddedTime { get; set; }
}
}
What could be the problem? I've tried to find any solution but didn't succeed.
I appreciate any kind of help.

XMLArray with different types but same element name and i:type attribute

I am trying to serialize some data I have into this XML format but not able to achive the same.
The Desired XML output is below:
<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Datas>
<Data xmlns="" i:type="DataA">
<Name>A1</Name>
<ADesc>Description for A</ADesc>
</Data>
<Data xmlns="" i:type="DataB">
<Name>B1</Name>
<BDesc>Description for b</BDesc>
</Data>
</Datas>
</Root>
The Classes I created for serialization are as follows:
public class Data
{
[XmlElement("Name")]
public string Name { get; set; }
}
public class DataA : Data
{
[XmlElement("ADesc")]
public string ADesc { get; set; }
}
public class DataB : Data
{
[XmlElement("BDesc")]
public string BDesc { get; set; }
}
[XmlRoot("Root")]
public class Root
{
[XmlArray("Datas")]
[XmlArrayItem(Type = typeof(Data))]
[XmlArrayItem(Type = typeof(DataA))]
[XmlArrayItem(Type = typeof(DataB))]
public List<Data> Datas { get; set; }
}
I use the below method for serializing:
internal static string Serialize(Root obj)
{
var ns = new XmlSerializerNamespaces();
ns.Add("i", "http://www.w3.org/2001/XMLSchema-instance");
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Root));
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, obj, ns);
return textWriter.ToString();
}
}
But the output I get is this (which is not correct):
<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Datas>
<DataA>
<Name>A1</Name>
<ADesc>Description for A</ADesc>
</DataA>
<DataB>
<Name>B1</Name>
<BDesc>Description for b</BDesc>
</DataB>
</Datas>
</Root>
In order to generate the {http://www.w3.org/2001/XMLSchema-instance}type attribute using XmlSerializer, you need to attach [XmlInclude(typeof(XXX))] for all subclasses XXX of Data to a declared type somewhere in your object graph, i.e. on the Root class or the Data class itself:
//[XmlInclude(typeof(DataA))] /* Could also go here if you prefer. */
//[XmlInclude(typeof(DataB))] /* Could also go here if you prefer. */
public class Data
{
[XmlElement("Name")]
public string Name { get; set; }
}
public class DataA : Data
{
[XmlElement("ADesc")]
public string ADesc { get; set; }
}
public class DataB : Data
{
[XmlElement("BDesc")]
public string BDesc { get; set; }
}
[XmlRoot("Root")]
[XmlInclude(typeof(DataA))]
[XmlInclude(typeof(DataB))]
public class Root
{
[XmlArray("Datas")]
public List<Data> Datas { get; set; }
}
For more information, see Declaring Serialization Types in Troubleshooting Common Problems with the XmlSerializer and also Xsi:type Attribute Binding Support.

deserialize existing xml into custom object

I have the following xml:
<state>
<groups>
<group id='1' name='Basic Search Options'>
<control name='Building' label='In' display='true' configurable='false'/>
<control name='SearchType' label='For' display='true' configurable='false'/>
<control id='1' default='C' name='Search By' label='By'>
<option searchtype='C' searchmode='Cnumber' value='CNumber' label='C Number' display='true'/>
<option searchtype='C' searchmode='crossrefnumber' value='CNumber1' label='Cross Reference Number' display='true'/>
<option searchtype='P' searchmode='' value='CaseNumber' label='P Name' display='true'/>
<option searchtype='P' searchmode='' value='CaseNumber' label='A Name' display='false'/>
</control>
</group>
<group id='2' name='Advanced Search Options'>
<control name='Ctatus' label='C Status' display='true'/>
<control name='DateFiled' label='Date Filed' display='true'/>
</group>
</groups>
How would I de-serialize this into the following object? I dont want my xml to have the following tags "ArrayofGroup", instead the xml should have custom tags like mention above.
public class GroupOfControls
{
public int instanceId { get; set; }
public int GroupId { get; set; }
public string Name { get; set; }
public List<SearchControl> Group { get; set; }
}
public class SearchControl
{
public string Name { get; set; }
public string Label { get; set; }
public bool Display { get; set; }
public string Default { get; set; }
public List<SearchOption> SearchOptions { get; set; }
}
public class SearchOption
{
public string Value { get; set; }
public string Label { get; set; }
public bool Display { get; set; }
public string SearchMode { get; set; }
public string SearchType { get; set; }
}
}
If you don't have an XSD file, you need to create one from your XML. You can do this with the Visual Studio Command Line using the following command:
xsd myfilename.xml
Once you have an XSD file this should be easy enough.
I am working with Visual Studio 2010 (C#/.Net 4) and I would do this:
First I would make a new solution in Visual Studio:
Then you need to import the XSD file into your project by right clicking on your solution, and selecting Add => Existing Item and browsing to the XSD.
Once you have the XSD inside your project you need to launch the Visual Studio command prompt, use cd to navigate to your projects directory and then type the following command:
xsd myFilename.xsd /classes
This generates the C# class you are going to deserialize your XML into. Use the Add Existing Item dialogue to import this new class into your solution.
Next you add using System.Xml.Serialization; and using System.IO; to your using statements. Then use the following code to deserialize your XML to an object (assuming the XML validates against your XSD). The most recent XSD I could file I called ResponseData as shown below:
With this in mind, my C# code is below:
using System;
using System.IO;
using System.Xml.Serialization;
namespace XML_Deserialization
{
class Program
{
static void Main(string[] args)
{
ResponseData myResponseData = new ResponseData();
XmlSerializer mySerializer = new XmlSerializer(typeof(ResponseData));
StreamReader myStreamReader = new StreamReader(#"C:\Users\JMK\Documents\Visual Studio 2010\Projects\scratch\XML Deserialization\XML Deserialization\text.xml");
myResponseData = (ResponseData)mySerializer.Deserialize(myStreamReader);
Console.ReadLine();
}
}
}

nhibernate: how to map two tables to a single non-persistent class?

I have two similar tables:
Table1:
[ id ] | [ name ]
Table2:
[ id ] | [ name ]
and I need to read/write data using only one class:
public class TwinTable
{
public virtual int Id { get; set; }
public virtual string Name1 { get; set; }
public virtual string Name2 { get; set; }
}
Plus one of the tables may or may not have an entity with the specified Id, and both tables may or may not have entities, so Name1 can be null and Name2 can be null and both of them can be null.
I can not change the structure of the DB, and it's not a good thing if i have to add something to it.
Hope for your help!
One solution is to map Table1 to a class, and then map Table2 as a joined-subclass of Table1. The joined subclass will then be like your TwinTable as you described above:
<class name="Class1" table="Table1" >
<id name="Id" column="id">
<generator class="identity" />
</id>
<property name="Name1" column="name" not-null="true" />
</class>
<joined-subclass name="Class2" table="Table2">
<key column="Id" />
<property name="Name2" column="name" not-null="true" />
</joined-subclass>