2012-06-20 20 views
2

我將XmlDocument發佈到ApiController(從Windows服務,服務工作正常,它張貼正確,我用它在wcf web api中),但xml總是空,我做錯了什麼? 我可以發佈一些類,如tutotials,或獲取任何數據,一切都會好的,但我不能發佈XmlDocument。如何在MVC 4 Web Api中接收XmlDocument?

public class XmlController : ApiController 
{ 
    public void PostXml(XmlDocument xml) 
    { 
     // code 
    } 
} 

回答

1

我發現解決方案:

我們需要使用繼承來繼承MediaTypeFormatter

public class XmlMediaTypeFormatter : MediaTypeFormatter 
{ 
    public XmlMediaTypeFormatter() 
    { 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));  
    } 

    public override System.Threading.Tasks.Task<object> ReadFromStreamAsync(Type type, Stream stream, 
     HttpContentHeaders contentHeaders, 
     IFormatterLogger formatterLogger) 
    { 
     var taskCompletionSource = new TaskCompletionSource<object>(); 
     try 
     { 
      var memoryStream = new MemoryStream(); 
      stream.CopyTo(memoryStream); 
      var s = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray()); 

      XmlDocument xmlDoc = new XmlDocument(); 
      xmlDoc.LoadXml(s); 

      taskCompletionSource.SetResult(xmlDoc); 
     } 
     catch (Exception e) 
     { 
      taskCompletionSource.SetException(e); 
     } 
     return taskCompletionSource.Task; 
    } 

    public override bool CanReadType(Type type) 
    { 
     return type == typeof(XmlDocument); 
    } 

    public override bool CanWriteType(Type type) 
    { 
     return false; 
    } 
} 

然後在Global.asax中註冊它:

GlobalConfiguration.Configuration.Formatters.Insert(0, new XmlMediaTypeFormatter()); 

控制器:

public HttpResponseMessage PostXml([FromBody] XmlDocument xml) 
    {//code...} 
0

是應該是控制器上的動作嗎?如果是這樣,您應該將您的控制器操作標記爲接受HttpPost。從那裏,我將修改的動作如下工作:

[HttpPost] 
public ActionResult PostXml(HttpPostedFileBase xml) 
{ 
    // code 
} 

如果您仍然無法順利接受張貼的文件,啓動調試和檢查請求的文件集:http://msdn.microsoft.com/en-us/library/system.web.httprequest.files.aspx

+0

它不是MVC控制器,它apicontroller,並且在這之後http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web-api- that-supports-crud-operations沒有必要添加[HttpPost]屬性。而且在你的例子中xml也是null。 – Rhot

2

我遵循@Rhot給出的解決方案,但不知何故這是行不通的,所以我喜歡編輯下面這工作對我來說:

public class XmlMediaTypeFormatter : MediaTypeFormatter 
    { 
     public XmlMediaTypeFormatter() 
     { 
      SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml")); 
     } 

     public override bool CanReadType(Type type) 
     { 
      return type == typeof(XDocument); 
     } 

     public override bool CanWriteType(Type type) 
     { 
      return type == typeof(XDocument); 
     } 

     public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger) 
     { 
      var reader = new StreamReader(stream); 
      string value = reader.ReadToEnd();    

      var tcs = new TaskCompletionSource<object>(); 
      try 
      { 
       var xmlDoc = XDocument.Parse(value); 
       tcs.SetResult(xmlDoc); 
      } 
      catch (Exception ex) 
      { 
       //disable the exception and create custome error 
       //tcs.SetException(ex); 
       var xml = new XDocument(
        new XElement("Error", 
         new XElement("Message", "An error has occurred."), 
         new XElement("ExceptionMessage", ex.Message) 
       )); 

       tcs.SetResult(xml); 
      } 

      return tcs.Task; 
     } 

     public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext) 
     { 
      var writer = new StreamWriter(stream); 
      writer.Write(((XDocument)value).ToString()); 
      writer.Flush(); 

      var tcs = new TaskCompletionSource<object>(); 
      tcs.SetResult(null); 
      return tcs.Task; 
     }    
    } 

寄存器global.asax:

GlobalConfiguration.Configuration.Formatters.Insert(0, new XmlMediaTypeFormatter()); 

and below my We BAPI控制器:

public HttpResponseMessage Post(XDocument xml) 
     {    
      return Request.CreateResponse(HttpStatusCode.OK, xml); 
     }