簡體   English   中英

XmlSerializer序列化錯誤與IIS / ASP.NET中的繼承類型有關,但在桌面.NET應用程序中沒有

[英]XmlSerializer serialization error with inherited types in IIS/ASP.NET but not in a desktop .NET Application

我主要是問這個問題來記錄一個問題,這個問題花了我幾個小時來解決我在網上找不到解決方案的問題。

我正在使用XmlSerializer序列化和反序列化一個基類,其中有幾個繼承的類:

public abstract class WorkRequest
{}

[WorkRequest]
public class A : WorkRequest
{}

[WorkRequest]
public class B : WorkRequest
{}

派生類的類型通過反射加載。 關鍵點是如何找到並加載DLL的引用:

string path;
Assembly main = Assembly.GetEntryAssembly();

if (main == null) // IIS 
    path = AppDomain.CurrentDomain.RelativeSearchPath;
else // Standard .NET Service
{
    path = main.Location;
    path = path.Substring(0, path.LastIndexOf(Path.DirectorySeparatorChar));
}

string[] fileList = Directory.GetFiles(path, "*.dll");

if (main != null)
    RegisterInterfaces(main);
foreach (string file in fileList)
{
    try
    {
        Assembly asm = Assembly.LoadFile(file);
        RegisterInterfaces(asm);
    }
    catch (Exception e)
    {
    }
}

當應用程序在asp.net中運行時,AppDomain.CurrentDomain.RelativeSearchPath將返回IIS中Web應用程序的bin目錄。 作為標准.NET服務運行時,條目程序集Location用於加載引用的程序集以查找請求類型。 使用WorkRequestAttribute探測DLL中的所有類型的類。

序列化完成如下:

var settings = new XmlWriterSettings()
{
    //Encoding = Encoding.UTF8,
    Indent = false,
    OmitXmlDeclaration = true
};

using (var tw = new StringWriter())
using (var xmlWriter = XmlWriter.Create(tw, settings))
{
   var serializer = GetSerializer(typeof(WorkRequest));
   serializer.Serialize(xmlWriter, input);
   tw.Flush();
   return tw.ToString();
}

序列化程序加載如下:

var serializer = new XmlSerializer(theType, _knownTypes.Value);

按照建議,序列化程序分配一次並緩存,類型為typeof(WorkRequest)。 _knownTypes是從上面代碼使用WorkRequest屬性通過反射找到的WorkRequest繼承的類。

此代碼作為.NET服務運行正常,並且如上所述加載引用的類型。 在IIS中運行時,調用XmlSerializer.Serialize()函數時,會報告以下異常:

A型不是預料之中的。 使用XmlInclude或SoapInclude屬性指定靜態未知的類型。

我還嘗試使用序列化程序用於繼承的類型A和相同的已知類型列表,但報告了以下錯誤:

類型A'和'A'都使用來自命名空間''的XML類型名稱'MyClass'。 使用XML屬性為類型指定唯一的XML名稱和/或命名空間。

似乎IIS應用程序加載DLL的方式與我加載它們的方式不同,並且已知類型不匹配,並且序列化程序無法找到類型。 在IIS中運行時加載類型是否有任何建議?

還有另一種方法可以解決這個問題嗎?

我通過使用作為顯式已知類型傳入的請求的類型並仍然使用typeof(WorkRequest)的序列化器來解決問題。 對已知類型的引用是正確的。 請注意,這不能解決IIS中反序列化的問題,但此時我不需要這樣做。

似乎核心問題是在.NET中加載程序集,類型,即使它們是相同的,.NET也不認為它們是相同的類型,並且不使用已加載的已知類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM