【问题标题】:Is it possible to model bind a soap request with mvc?是否可以使用 mvc 对肥皂请求进行建模?
【发布时间】:2015-01-16 14:00:53
【问题描述】:

客户端有一个服务,它发送我们需要通过我们的 .Net MVC4 项目接收的 xml soap 格式的请求。请求的格式为:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <ReceiveStatusUpdate xmlns="http://test.com">
            <StatusUpdate>
                <Reference>214563</Reference>
                <ThirdPartyReference>YOUR-REFERENCE</ThirdPartyReference>
                <Status>Pending</Status>
            </StatusUpdate>
        </ReceiveStatusUpdate>
    </soap:Body>
</soap:Envelope>

我想知道接收和解析此请求的最佳方式是什么?

【问题讨论】:

  • 出于兴趣,是否有必要通过 MVC 处理此问题? WCF 甚至可能是 Web api 端点呢?有关 web api + soap 的讨论,请参阅此线程。 stackoverflow.com/questions/11317572/asp-net-webapi-soap
  • 如果您必须使用 SOAP,我会创建一个 WebAPI 并让客户端通过 RESTful 接口与其通信,或者创建一个 WCF 服务而不是 MVC 应用程序。开箱即用,MVC 无法处理 SOAP 消息,您应该使用自定义代码来处理。
  • 我处于同样的情况 - 主应用程序是使用 ASP MVC 构建的,我们需要创建一个端点来支持来自我们合作伙伴的 WCF SOAP POST 请求。

标签: c# .net asp.net-mvc asp.net-mvc-4


【解决方案1】:

这样做的方式有点笨拙,但它对我有用,而且它是我需要处理的一次性请求类型。我基本上把请求正文拉出来并用 XDocument 解析它

public ActionResult Update()
{
    var inputStream = Request.InputStream;
    inputStream.Seek(0, SeekOrigin.Begin);
    var request = new StreamReader(inputStream).ReadToEnd();
    var soapRequest = XDocument.Parse(request);
    ...
}

【讨论】:

    【解决方案2】:

    实现这一点的最简单方法是使用老式的 asmx Web 服务。

    通过 Web API 公开需要大量工作,因为它不支持开箱即用的 SOAP 绑定。

    您可以使用 WCF 服务,但它们的配置可能很繁琐且耗时,这是为其灵活性付出的代价。

    简而言之,如果您只需要支持 SOAP 绑定,请使用专为该工作设计的工具 - asmx Web 服务。

    只需将一个新项目添加到您的 Web 服务 (ASMX) 类型的 MVC 项目中,示例如下所示(您显然会将 StatusUpdate 类定义在一个单独的文件中)。

    /// <summary>
    /// Summary description for StatusWebService
    /// </summary>
    [WebService(Namespace = "http://test.com")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class StatusWebService : System.Web.Services.WebService
    {
    
        [WebMethod]
        public void ReceiveStatusUpdate(StatusUpdate StatusUpdate)
        {
            //Do whatever needs to be done with the status update
        }
    }
    
    public class StatusUpdate
    {
        public string Reference { get; set; }
        public string ThirdPartyReference { get; set; }
        public string Status { get; set; }
    }
    

    【讨论】:

    • 谢谢,我会给你赏金,因为你是正确的,因为这会起作用。但是,我通过从请求我的控制器方法解析输入流来解决它,我将在我的解决方案中留下一个单独的答案
    【解决方案3】:

    在我看来-也许有人可以说更多,那就是选择WebAPI。它使用简单,只需一些代码,所以它很轻。你有很多在 .NET 中处理 XML 文档的工具,所以这对你来说不会有任何问题。

    还有一件事。在您的 XML 中有错误,结束标记“ReceiveStatusUpdate”拼写错误。

    这将在开始时有所帮助:http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api 然后您可以使用 Fiddler 将这些 XML 发布到您的 WebAPI。

    【讨论】:

    • 谢谢我已经编辑了,我已经更改了这个问题的实际 xml 标签
    • 好的,你还需要什么?
    【解决方案4】:

    可能不是最好的答案,但这就是我现在正在做的事情。

    [HttpPost]
    public IHttpActionResult HotelAvailRQ(HttpRequestMessage request)
    {
        // Parse the SOAP request to get the data payload
        var xmlPayload = MyHelper.GetSoapXmlBody(request);
    
        // Deserialize the data payload
        var serializer = new XmlSerializer(typeof(OpenTravel.Data.CustomAttributes.OTA_HotelAvailRQ));
        var hotelAvailRQ = (OpenTravel.Data.CustomAttributes.OTA_HotelAvailRQ)serializer.Deserialize(new StringReader(xmlPayload));
    
        return Ok();
    }
    

    助手类

    public static class MyHelper
    {
        public static string GetSoapXmlBody(HttpRequestMessage request)
        {
            var xmlDocument = new XmlDocument();
            xmlDocument.Load(request.Content.ReadAsStreamAsync().Result);
    
            var xmlData = xmlDocument.DocumentElement;
            var xmlBodyElement = xmlData.GetElementsByTagName("SOAP-ENV:Body");
    
            var xmlBodyNode = xmlBodyElement.Item(0);
            if (xmlBodyNode == null) throw new Exception("Function GetSoapXmlBody: Can't find SOAP-ENV:Body node");
    
            var xmlPayload = xmlBodyNode.FirstChild;
            if (xmlPayload == null) throw new Exception("Function GetSoapXmlBody: Can't find XML payload");
    
            return xmlPayload.OuterXml;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      • 2011-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      相关资源
      最近更新 更多