|
pincet 1561 / 1113 / 164 Регистрация: 23.07.2010 Сообщений: 6,382 |
||||
|
1 |
||||
Возникла ошибка при отражении типа20.11.2013, 13:51. Показов 6609. Ответов 4 Метки нет (Все метки)
где руки править?
0 |
|
16739 / 12492 / 3283 Регистрация: 17.09.2011 Сообщений: 20,719 |
|
|
20.11.2013, 14:54 |
2 |
|
Лезьте в свойство InnerException до тех пор, пока оно не станет null.
1 |
|
pincet 1561 / 1113 / 164 Регистрация: 23.07.2010 Сообщений: 6,382 |
||||||||
|
20.11.2013, 15:22 [ТС] |
3 |
|||||||
|
Хм, ошибка вот здесь
XMLSerialization.TW. XmlAttribute/XmlText не может использоваться для кодирования составных типов
убрал [XmlAttribute] «<TabPage xmlns=»> не ожидался.» 1.ЧЯДНТ?
0 |
|
kolorotur
16739 / 12492 / 3283 Регистрация: 17.09.2011 Сообщений: 20,719 |
||||||||||||
|
20.11.2013, 17:20 |
4 |
|||||||||||
|
«<TabPage xmlns=»> не ожидался.» У вас классы называются TW, TP и так далее, а элементы в разметке — TabPage, TreeView и т.д. Либо называйте классы так же, как элементы в разметке, либо элементы в разметке называйте так же, как классы, либо классы пометьте атрибутом XmlType:
Вернет null.
1 |
|
pincet 1561 / 1113 / 164 Регистрация: 23.07.2010 Сообщений: 6,382 |
||||
|
20.11.2013, 17:40 [ТС] |
5 |
|||
|
С этим уже разобрался. Проблема в другом
т.е нужно оборачивать в доп тэги Parent и Node.
0 |
Есть класс, экземпляр которого нужно перенести в XML файл. Однако возникает исключение
Первый этап обработки исключения типа
«System.InvalidOperationException» в System.Xml.dllДополнительные сведения: Возникла ошибка при отражении типа
«Lab2.Model.Circle».
public class Circle:Figure2D
{
private double r;
public double R
{
set
{
if (value >= 0) this.r = value;
else throw new ArgumentNullException("Wrong radius value ( value < 0 ? ) ");
}
get { return r; }
}
public override string Save()
{
string s = string.Format("Circle {0} {1} {2}",this.Center.X, this.Center.Y, this.R);
return s;
}
public override double P()
{
return 2 * Math.PI * R;
}
public override double S()
{
return Math.PI * R * R;
}
public static Circle LoadCircle(string s)
{
string[] ss = s.Split(' ');
int x = Convert.ToInt32(ss[1]);
int y = Convert.ToInt32(ss[2]);
int r = Convert.ToInt32(ss[3]);
return new Circle(new Point(x, y), r);
}
public override void Draw(PaintEventArgs e)
{
e.Graphics.DrawEllipse(new Pen(Color.Black), (int)this.Center.X, (int)this.Center.Y, (int)this.R, (int)this.R);
}
public override void Zoom(double K, bool isfromImage)
{
this.R *= K;
if(isfromImage)
{
this.Center.X *= K;
this.Center.Y *= K;
}
Console.WriteLine("circle zoom of {0}", this.GetType());
}
public override string ToString()
{
string baseInfo = base.ToString();
return baseInfo + string.Format("n R: {0}n", this.R);
}
public Circle() { }
public Circle(Point Center, double R) : base(Center)
{
this.R = R;
}
public Circle(Circle other) : base(other.Center)
{
this.R = other.R;
}
}
If you need to handle specific attributes (i.e. Dictionary, or any class), you can implement the IXmlSerialiable interface, which will allow you more freedom at the cost of more verbose coding.
public class NetService : IXmlSerializable
{
#region Data
public string Identifier = String.Empty;
public string Name = String.Empty;
public IPAddress Address = IPAddress.None;
public int Port = 7777;
#endregion
#region IXmlSerializable Implementation
public XmlSchema GetSchema() { return (null); }
public void ReadXml(XmlReader reader)
{
// Attributes
Identifier = reader[XML_IDENTIFIER];
if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false)
throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT);
if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false)
throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR);
}
public void WriteXml(XmlWriter writer)
{
// Attributes
writer.WriteAttributeString(XML_IDENTIFIER, Identifier);
writer.WriteAttributeString(XML_NETWORK_ADDR, Address.ToString());
writer.WriteAttributeString(XML_NETWORK_PORT, Port.ToString());
}
private const string XML_IDENTIFIER = "Id";
private const string XML_NETWORK_ADDR = "Address";
private const string XML_NETWORK_PORT = "Port";
#endregion
}
There is an interesting article, which show an elegant way to implements a sophisticated way to «extend» the XmlSerializer.
The article say:
IXmlSerializable is covered in the official documentation, but the documentation states it’s not intended for public use and provides no information beyond that. This indicates that the development team wanted to reserve the right to modify, disable, or even completely remove this extensibility hook down the road. However, as long as you’re willing to accept this uncertainty and deal with possible changes in the future, there’s no reason whatsoever you can’t take advantage of it.
Because this, I suggest to implement you’re own IXmlSerializable classes, in order to avoid too much complicated implementations.
…it could be straightforward to implements our custom XmlSerializer class using reflection.
If you need to handle specific attributes (i.e. Dictionary, or any class), you can implement the IXmlSerialiable interface, which will allow you more freedom at the cost of more verbose coding.
public class NetService : IXmlSerializable
{
#region Data
public string Identifier = String.Empty;
public string Name = String.Empty;
public IPAddress Address = IPAddress.None;
public int Port = 7777;
#endregion
#region IXmlSerializable Implementation
public XmlSchema GetSchema() { return (null); }
public void ReadXml(XmlReader reader)
{
// Attributes
Identifier = reader[XML_IDENTIFIER];
if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false)
throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT);
if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false)
throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR);
}
public void WriteXml(XmlWriter writer)
{
// Attributes
writer.WriteAttributeString(XML_IDENTIFIER, Identifier);
writer.WriteAttributeString(XML_NETWORK_ADDR, Address.ToString());
writer.WriteAttributeString(XML_NETWORK_PORT, Port.ToString());
}
private const string XML_IDENTIFIER = "Id";
private const string XML_NETWORK_ADDR = "Address";
private const string XML_NETWORK_PORT = "Port";
#endregion
}
There is an interesting article, which show an elegant way to implements a sophisticated way to «extend» the XmlSerializer.
The article say:
IXmlSerializable is covered in the official documentation, but the documentation states it’s not intended for public use and provides no information beyond that. This indicates that the development team wanted to reserve the right to modify, disable, or even completely remove this extensibility hook down the road. However, as long as you’re willing to accept this uncertainty and deal with possible changes in the future, there’s no reason whatsoever you can’t take advantage of it.
Because this, I suggest to implement you’re own IXmlSerializable classes, in order to avoid too much complicated implementations.
…it could be straightforward to implements our custom XmlSerializer class using reflection.
[Serializable]
public class IPzag
{
public BitArray version = new BitArray(4);//номер версии 4 бита
public BitArray header_length = new BitArray(4);//Длина заголовка 4 бита
public BitArray toS = new BitArray(8);//тип сервиса 8 бит
public ushort total_lenght;//Общая длина 16 бит
public ushort identification;//Идентификатор пакета 16 бит
public BitArray flag = new BitArray(3);//Флаги 3 бита
public BitArray fragment_offset = new BitArray(13);//Смещение фрагмента 13 бит
public byte ttl;//Время жизни 8 бит Time To Live
public byte protocol;//Протокол верхнего уровня 8 бит
public ushort checksum;//Контрольная сумма 16 бит
public uint sourse_address;//айпишник источника 32 бита
public uint destination_adress;//айпишник назначения 32 бита
[DisplayName(«Номер версии»)]
[XmlAttribute()]
public BitArray Version
{
get { return version; }
set { for (int i = 0; i < 4; i++) version[i] = Convert.ToBoolean(value); }
}
[DisplayName(«Длина заголовка»)]
[XmlAttribute()]
public BitArray Header_Length
{
get { return header_length; }
set { for (int i = 0; i < 4; i++) header_length[i] = Convert.ToBoolean(value); }
}
[DisplayName(«Тип сервиса»)]
[XmlAttribute()]
public BitArray ToS
{
get { return toS; }
set { for (int i = 0; i < 4; i++) toS[i] = Convert.ToBoolean(value); }
}
[DisplayName(«Общая длина»)]
[XmlAttribute()]
public ushort Total_lenght
{
get { return total_lenght; }
set { total_lenght = value; }
}
[DisplayName(«Идентификатор пакета»)]
[XmlAttribute()]
public ushort Identification
{
get { return identification; }
set { identification = value; }
}
[DisplayName(«Время жизни»)]
[XmlAttribute()]
public byte TTL
{
get { return ttl; }
set { ttl = value; }
}
[DisplayName(«IP-Протокол верхнего уровня»)]
[XmlAttribute()]
public byte Protocol
{
get { return protocol; }
set { protocol = value; }
}
[DisplayName(«Контрольная сумма»)]
[XmlAttribute()]
public ushort Checksum
{
get { return checksum; }
set { checksum = value; }
}
[DisplayName(«IP-адрес источника»)]
[XmlAttribute()]
public uint Sourse_address
{
get { return sourse_address; }
set { sourse_address = value; }
}
[DisplayName(«IP-адрес назначения»)]
[XmlAttribute()]
public uint Destination_adress
{
get { return destination_adress; }
set { destination_adress = value; }
}
[DisplayName(«Флаги»)]
[XmlAttribute()]
public BitArray Flag
{
get { return flag; }
set { for (int i = 0; i < 4; i++) fragment_offset[i] = Convert.ToBoolean(value); }
}
[DisplayName(«Смещение фрагмента»)]
[XmlAttribute()]
public BitArray Fragment_offset
{
get { return fragment_offset; }
set { for (int i = 0; i < 4; i++) fragment_offset[i] = Convert.ToBoolean(value); }
}
public IPzag()
{
}
}
Есть у меня класс, мне нужно его сохранить в файл, в этом классе используется как свойство класс Font и он нужен,пробвал его заменить, на свой и конверировал его туда обратно, но сериализация всё равно не работает пишет ошибку:
Возникла ошибка при отражении типа "System.Collections.Generic.List`1[WindowsFormsApplication1.MyClass]".
Этим пытался заменить:
[Serializable]
public class SFont
{
public String name { get; set; } //возвращает имя начертания этого шрифт
public float size { get; set; } //Размер максимального пробела данного шрифта
public Byte Style { get; set; } //возвращает сведения о стиле данного шрифта
/// <summary>
/// Конструктор класса SFont
/// </summary>
/// <param name="FontName">Название шрифта</param>
/// <param name="FontSize">Размер шрифта</param>
/// <param name="fontStyle">Стиль шрифта в Byte (нужно использовать Converter)</param>
public SFont(String FontName, float FontSize, Byte fontStyle)
{
name = FontName;
size = FontSize;
Style = fontStyle;
}
}
таким классом конвертировал:
public static class Converter
{
/// <summary>
/// Конвертирует из числа от 1 до 5 в FontStyle
/// </summary>
/// <param name="number">число от 1 до 5</param>
/// <returns>FontStyle</returns>
public static FontStyle ToFontStyle(byte number)
{
FontStyle fs = new FontStyle();
switch (number)
{
case 1: fs = FontStyle.Regular;
return fs;
case 2: fs = FontStyle.Bold;
return fs;
case 3: fs = FontStyle.Italic;
return fs;
case 4: fs = FontStyle.Strikeout;
return fs;
case 5: fs = FontStyle.Underline;
return fs;
}
return fs;
}
public static Byte ToNumber(FontStyle fs)
{
Byte i = 0;
switch (fs)
{
case FontStyle.Regular: i = 1;
return i;
case FontStyle.Bold: i = 2;
return i;
case FontStyle.Italic: i = 3;
return i;
case FontStyle.Strikeout: i = 4;
return i;
case FontStyle.Underline: i = 5;
return i;
}
return i;
}
Пример использования конвертера:
textBoxMsg.Font = new Font(MyClass.FontMsg.name, MyClass.FontMsg.size, Converter.ToFontStyle(MyClass.FontMsg.Style));
SFont sFont = new SFont(fontDialog.Font.Name, fontDialog.Font.Size, Converter.ToNumber(fontDialog.Font.Style));
Кстати в моём классе заменяющем Font видимо чегото не хватает, если кто знает подскажите, не всегда правильно сохраняет шрифт
Вот как сериализовал:
List<MyClass> list = new List<MyClass>();
list.Clear();
foreach (ListViewItem item in listViewUsed.Items)
{
list.Add(new MyClass((MyClass)item.Tag));
}
XmlWriter writer = new XmlTextWriter("serialize.xml", System.Text.Encoding.UTF8);
XmlSerializer serializer = new XmlSerializer(typeof(List<MyClass>));
serializer.Serialize(writer, list);
writer.Close();
Вот мне не понятно почему возникает ошибка? Я убрал из класса который нужно сериализовать вообще любое упоминание Font, даже FonStyle пришлось конвертировать, чтобы не упоминать его в своём классе и всё равно ошибка. Ничего не понимаю. Подскажите как можно сохранить в файл свой класс и потом прочесть от туда.
-
Перемещено
1 октября 2010 г. 21:42
MSDN Forums Consolidation (От:Visual C#)
public class TW
{
[XmlAttribute]
public string Name;
[XmlArrayAttribute]
public P[] Parent;
public void ShowMe()
{
Console.WriteLine("{0}", Name);
foreach (P p in Parent)
p.ShowMe();
}
}
public class P
{
[XmlAttribute]
public string Name;
[XmlAttribute]
public string Text;
[XmlAttribute]
public string Type;
[XmlAttribute]
public string Path;
[XmlArrayAttribute]
public C[] Node;
public void ShowMe()
{
Console.WriteLine("{0} {1} {2} {3}", Name, Text, Type, Path);
foreach (C c in Node)
c.ShowMe();
}
}
public class C
{
[XmlAttribute]
public string Name;
[XmlAttribute]
public string Text;
public void ShowMe()
{
Console.WriteLine("{0} {1}",Name,Text);
}
}
[Serializable]
public class TP
{
[XmlAttribute]
public string Name;
[XmlAttribute]
public string Descr;
[XmlAttribute]
public TW TreeView;
public void ShowMe()
{
Console.WriteLine("{0} {1}", Name, Descr);
TreeView.ShowMe();
}
}
public class GUI
{
public GUI(XElement xe)
{
TP tp = new TP();
XmlSerializer serializer = new XmlSerializer(typeof(TP));
TextReader tr=new StringReader(xe.ToString());
tp=(TP)serializer.Deserialize(tr);
tp.ShowMe();
}
}
class Program
{
static void Main(string[] args)
{
GUI g=new GUI(XDocument.Load("1.xml").Element("TabPage"));
}
}
После обфусцирования с помощью .NET Reactor 5.9.8 возникло исключение при попытке автоматической десериализации xml файла. Изначально файл был сериализован с помощью необфусцированной версии, что, возможно, послужило причиной возникновения ошибки (а может и нет). Но в рамках обратной совместимости, необходимо подерживать ранее созданные файлы.
Отлов исключения показал следующее:
Возникла ошибка при отражении типа «…» в System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(…)
Внутреннее исключение:
Не удается сериализовать член «Devices» типа «System.Collections.Generic.List…». Дополнительные сведения см. во внутреннем исключении.
Следующее внутреннее исключение содержит необходимые сведения:
IveprCalculator.Models.Device недоступен в силу его уровня защиты. Возможна обработка только общих типов.
Это значит, что обфускатор отметил все возможные публичные классы как internal (если включить данную настройку).
Решение: найти параметр исключений в настройках обфускации и указать, что классы-сериализаторы (например, у меня были задействованы три класса) не должны быть обфусцированы и не должны быть отмечены internal.
For some reason XmlText only works on string properties on derived classes, while it can properly convert other types if the class is not derived. This seems weird and inconsistent.
using System; using System.Xml.Serialization; namespace CoreXmlTextTest { public enum TestEnum { Off, On, Both } public class EnumTestUnderived { [XmlText] public TestEnum Test { get; set; } } public class EnumTestBase { } public class EnumTestDerived : EnumTestBase { [XmlText] public TestEnum Test { get; set; } } public class Program { public static void Main(string[] args) { var ser = new XmlSerializer(typeof(EnumTestUnderived)); var sw = new System.IO.StringWriter(); ser.Serialize(sw, new EnumTestUnderived() { Test = TestEnum.On }); Console.WriteLine(sw.ToString()); try { new XmlSerializer(typeof(EnumTestDerived)); } catch (Exception e) { Console.WriteLine(e); return; } } } }
The code above outputs:
<?xml version="1.0" encoding="utf-16"?>
<EnumTestUnderived xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">On</EnumTestUnderived>
System.InvalidOperationException: There was an error reflecting type 'CoreXmlTextTest.EnumTestDerived'. ---> System.InvalidOperationException: Cannot serialize object of type 'CoreXmlTextTest.EnumTestDerived'. Consider changing type of XmlText member 'CoreXmlTextTest.EnumTestDerived.Test' from CoreXmlTextTest.TestEnum to string or string array.
at System.Xml.Serialization.StructMapping.SetContentModel(TextAccessor text, Boolean hasElements)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
at CoreXmlTextTest.Program.Main(String[] args) in c:UserskbDocumentsVisual Studio 2015ProjectsTestCoreXmlTextTestProgram.cs:line 31
Note that the only difference whether it succeeds or not is whether the class derives from Object or from another class.
.net Core version: 2.0.0-preview2-25407-01
NB: This issue is also present in the full .NET Framework.
