2013-04-07 2 views
1

에서 xmlns : xsi 및 xmlns : xsd를 제거하는 방법 ASP.NET Web API의 독립 객체 (MVC 모델이 아님)를 직렬화하여 반환되는 XML에서 기본 네임 스페이스를 제거하는 데는 몇 시간이 걸렸습니다. . 응용 프로그램에 대한 샘플 코드는 다음과 같습니다Web API XML serializer

클래스 정의 :

public class PaymentNotificationResponse 
{ 

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

내가 다음 몇 가지 입력을 기반으로 PaymentNotificationResponse의 객체를 만든 다음 요청하는 자에게 객체를 직렬화 웹 API를 CONTROLER를 만들었습니다. 컨트롤러는 아래와 같이 표시됩니다

<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> 
:

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이 필요하지 않습니다)이며,

내가 보내는 시스템에는 xmlns:xsixmlns:xsd이 필요하지 않습니다. 사실, 네임 스페이스를 볼 때 예외를 반환합니다.

XML 태그가 포함 된 문자열을 반환하려고 시도했을 때 응답을 <string></string>에 랩핑하고 모든 < 및>을 인코딩했습니다. 그래서 그건 선택 사항이 아니 었습니다.

나는 this postthis one을 보았다. 전자는 매우 자세하지만 문제는 해결되지 않았습니다. 생성 된 XML에 xmlns을 추가했습니다. 나는 XmlSerializer에서 명시 적으로 .Serialize() 함수를 호출하지 않았기 때문이라고 생각합니다.

나는 해결책을 알아 냈고, 나는 나눌 것이라고 생각했다. 그래서 답변에 명시 할 것입니다. ,

//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을 만들 문자열을 구문 분석 :

답변

3

는이 문제를 해결하려면, 나는 (내가 PaymentNotificationResponse의 정의에이를 포함) 따라서, PaymentNotificationResponse를 직렬화하고 XML 문자열을 반환하는 방법을 추가 그런 다음 루트 요소를 리턴하십시오. 이로 인해 Post() 메서드의 반환 형식이 XElement으로 변경되었습니다. Post() 목록은 다음과 같다 : 내 응답 XML이 만들 것

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; 
    } 

:

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

내가이 사람을 도움이되기를 바랍니다.

+0

훌륭한 솔루션 "return XDocument.Parse (pnr.SerializeToXml()). Root;" 열쇠였다. – FrankyHollywood