簡體   English   中英

如何從Web API XML序列化程序中刪除xmlns:xsi和xmlns:xsd

[英]How to remove xmlns:xsi and xmlns:xsd from Web API XML serializer

幾個小時后,我一直在努力從ASP.NET Web Api中序列化我的獨立對象(不是MVC模型)返回的XML中刪除默認命名空間。 該應用程序的示例代碼是:

類定義:

public class PaymentNotificationResponse
{

    [XmlArray("Payments")]
    [XmlArrayItem("Payment", typeof(PaymentResponse))]
    public PaymentResponse[] Payments { get; set; }
}

然后,我創建了一個Web Api Controler,它根據某些輸入創建了PaymentNotificationResponse的對象,然后將該對象序列化到請求方。 控制器如下:

public class PaymentController : ApiController
{

    public PaymentNotificationResponse Post()
    {
        //Read request content (only available async), run the task to completion and pick the stream.
        var strmTask = Request.Content.ReadAsStreamAsync();
        while (strmTask.Status != TaskStatus.RanToCompletion) { }
        Stream strm = strmTask.Result;

        //Go back to the beginning of the stream, so that the data can be retrieved. Web Api reads it to the end.
        if (strm.CanSeek)
            strm.Seek(0, SeekOrigin.Begin);

        //Read stream content and convert to string.
        byte[] arr = new byte[strm.Length];
        strm.Read(arr, 0, arr.Length);
        String str = Encoding.UTF8.GetString(arr);

        //Change the default serializer to XmlSerializer from DataContractSerializer, so that I don't get funny namespaces in properties.
        //Then set a new XmlSerializer for the object
        Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
        Configuration.Formatters.XmlFormatter.SetSerializer<PaymentNotificationResponse>(new XmlSerializer(typeof(PaymentNotificationResponse)));

        //Now call a function that would convert the string to the required object, which would then be serialized when the Web Api is invoked.
        return CreatePaymentNotificationFromString(str);
    }
}

問題是,當我用有效的字符串參數調用Api時,它返回這種格式的XML(有效的XML,但不需要xmlns):

<PaymentNotificationResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Payments>
        <Payment>
            <PaymentLogId>8325</PaymentLogId>
            <Status>0</Status>
        </Payment>
    </Payments>
</PaymentNotificationResponse>

我發送給它的系統不需要xmlns:xsixmlns:xsd 實際上,它在看到名稱空間時會返回異常。

我嘗試使用XML標記返回一個字符串,它只是將響應包裝在<string></string>並編碼所有<和>。 所以這不是一個選擇。

我看到了這篇文章這篇 文章 雖然前者非常詳細,但它並沒有解決我的問題。 它只是向生成的XML引入了一個額外的xmlns 我認為這是因為我沒有在XmlSerializer顯式調用.Serialize()函數。

我想出了一個解決方案,我想我應該分享。 所以我會在答案中說明。

為了解決這個問題,我添加了一個方法來序列化PaymentNotificationResponse並返回一個XML字符串,因此(我將其包含在PaymentNotificationResponse的定義中):

//I added this method after I tried serialize directly to no avail
    public String SerializeToXml()
    {
        MemoryStream ms = new MemoryStream();

        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("", "");

        new XmlSerializer(typeof(PaymentNotificationResponse)).Serialize(ms, this, ns);
        XmlTextWriter textWriter = new XmlTextWriter(ms, Encoding.UTF8);

        ms = (System.IO.MemoryStream)textWriter.BaseStream;

        return new UTF8Encoding().GetString(ms.ToArray());
    }

我解析了字符串以創建XDocument ,然后返回根元素。 這使我將Post()方法的返回類型更改為XElement Post()列表將是:

public XElement Post()
    {
        //...Same as it was in the question, just the last line that changed.

        var pnr = CreatePaymentNotificationFromString(str);
        return XDocument.Parse(pnr.SerializeToXml()).Root;
    }

這將使我的響應XML:

<PaymentNotificationResponse>
    <Payments>
        <Payment>
            <PaymentLogId>8325</PaymentLogId>
            <Status>0</Status>
        </Payment>
    </Payments>
</PaymentNotificationResponse>

我希望這可以幫助別人。

暫無
暫無

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

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