XML 反序列化代码在控制台应用中有效,但在 Xamarin.Forms 中引发 NullReferenceException

Code for XML deserialization works in Console App but throws NullReferenceException in Xamarin.Forms

提问人:Adream 提问时间:11/17/2019 最后编辑:Adream 更新时间:11/18/2019 访问量:102

问:

我有将XMLDocument反序列化为数组的代码。但是每当我在 Xamarin.Forms Android 项目中调用它时,它都会引发 NullReferenceException。经过几天的调试,我创建了一个 .NET 控制台应用程序,将有问题的代码复制到其中,瞧瞧,它运行良好。谁能帮我解决这个问题? 这是我正在使用的 XMLDocument:

<?xml version="1.0" encoding="utf-8" ?>
<Otazky>
  <Otazka>
    <Typ>ABC</Typ>
    <Bodu>1</Bodu>
    <Ukol> Ve kterém z následujících souvětí není chyba v interpunkci?</Ukol>
    <Moznosti>
      <Moznost>A) Po vyčerpávajících mrazech</Moznost>
      <Moznost>B) Mé obavy se každým dnem stupňovaly,</Moznost>
      <Moznost>C) Pokud snížím množství sladkostí</Moznost>
      <Moznost>D) Rodiče celý víkend usilovně přemýšleli</Moznost>
    </Moznosti>
    <Spravna>C</Spravna>
  </Otazka>

<Otazka>
  <Typ>Vyber</Typ>
  <Bodu>2</Bodu>
  <Ukol> Ukol2 </Ukol>
  <Moznosti>
    <Moznost>A) Po vyčerpávajících mrazech</Moznost>
    <Moznost>B) Mé obavy se každým dnem stupňovaly</Moznost>
    <Moznost>C) Pokud snížím množství sladkostí</Moznost>
    <Moznost>D) Rodiče celý víkend usilovně přemýšleli</Moznost> 
  </Moznosti> 
  <Spravna>D</Spravna>
</Otazka>
</Otazky>

以下是我用来存储每个 Otazka 元素的类:

public class Otazka
{
    [XmlElement(ElementName = "Typ")]
    public string Typ { get; set; }
    [XmlElement(ElementName = "Bodu")]
    public int Bodu { get; set; }
    [XmlElement(ElementName = "Ukol")]
    public string Ukol { get; set; }

    [XmlElement(ElementName = "Moznosti")]
    public Moznosti Moznosti { get; set; }
    [XmlElement(ElementName = "Spravna")]
    public string Spravna { get; set; }
}

[XmlRoot(ElementName = "Otazky")]
public class Otazky
{
    [XmlElement(ElementName = "Otazka")]
    public List<Otazka> Otazka { get; set; }
}

最后是将 XML 反序列化到我的类中的代码:

Otazka[] LoadXMLData()
{
                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("DDKTCKE_APP.MyResources.Otazky.xml"))
                {
                    XDocument doc = XDocument.Load(stream);

                    var result = from q in doc.Descendants("Otazka")
                             select new Otazka
                             {
                                 Typ = q.Element("Typ").Value,
                                 Bodu = Convert.ToInt32(q.Element("Bodu").Value),
                                 Ukol = q.Element("Ukol").Value,
                                 Moznosti = new Moznosti(q.Element("Moznosti").Elements().Select(x => x.Value).ToList()),                                                            
                                 Spravna = q.Element("Spravna").Value
                             };

                    return result.ToArray();

                }
}

在返回结果的行中引发 NullReferenceException。ToArray() 中。此外,当我将整个功能包含在 Try 中时......抓住块,它什么也没抓到。

C# XML Xamarin.Forms 反序列化 NullReferenceException

评论


答:

1赞 jdweng 11/17/2019 #1

xml 包含 unicode 字符,而 ident(第一行)表示 utf-8。因此,您需要跳过标识行,以免发生冲突。请参阅下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            Otazka[] otazka = LoadXMLData(FILENAME);
        }
        static Otazka[] LoadXMLData(string filename)
        {
            using (var stream = File.OpenRead(filename))
            {
                StreamReader reader = new StreamReader(stream);
                reader.ReadLine();  //read line to skip xml identification line which is utf-8
                                    //file contains unicode characters
                XDocument doc = XDocument.Load(reader);

                //_Counter = doc.ToString().Length;


                var result = (from q in doc.Descendants("Otazka")
                             select new Otazka
                             {
                                 Typ = q.Element("Typ").Value,
                                 Bodu = Convert.ToInt32(q.Element("Bodu").Value),
                                 Ukol = q.Element("Ukol").Value,
                                 //Moznosti = new Moznosti(q.Element("Moznosti").Elements().Select(x => x.Value).ToList()),
                                 Spravna = q.Element("Spravna").Value
                             }).ToArray();

                return result;

            }
        }
    }

    public class Otazka
    {
        [XmlElement(ElementName = "Typ")]
        public string Typ { get; set; }
        [XmlElement(ElementName = "Bodu")]
        public int Bodu { get; set; }
        [XmlElement(ElementName = "Ukol")]
        public string Ukol { get; set; }

        //[XmlElement(ElementName = "Moznosti")]
        //public Moznosti Moznosti { get; set; }
        [XmlElement(ElementName = "Spravna")]
        public string Spravna { get; set; }
    }

    [XmlRoot(ElementName = "Otazky")]
    public class Otazky
    {
        [XmlElement(ElementName = "Otazka")]
        public List<Otazka> Otazka { get; set; }
    }
}

评论

0赞 Adream 11/17/2019
我不认为我使用了 UTF-8 中不存在的任何字符。此编码支持所有变音符号。可悲的是,您的解决方案无法解决任何问题,我仍然遇到同样的错误。尽管像您一样注释掉 Moznosti 变量会使其运行而不会出现任何错误。所以至少我知道问题在于反序列化 List<string> Moznosti。
0赞 jdweng 11/17/2019
打开记事本并粘贴 xml。然后使用 File:SaveAs 并选择编码 utf-8。然后保存。您将收到一条警告,指出代码包含 unicode 字符。
-1赞 Adream 11/18/2019 #2

我创建了一个新的空Xamarin.Forms项目(与以前相同),将旧项目中的所有代码复制到其中。它起作用了。

评论

0赞 Adriaan 11/18/2019
请以礼貌的方式提及您的挫败感,并避免在此处的帖子中出现淫秽内容。它们会很快被发现,并可能导致大量的反对票和可能的行为禁令。
1赞 TylerH 11/18/2019
更好的是 - 不要提到挫败感,因为它是噪音(与答案无关)。
1赞 dbc 11/19/2019
在这种情况下,旧项目的资源文件中可能存在错误或缺少字节顺序标记。请参见:从 Resource 读取文件时指定编码