2013-07-03 2 views
4

РЕДАКТИРОВАТЬ: Я набрал максимум и минимум для ответа на этот вопрос, и никто, похоже, не сталкивался с подобной проблемой. Мне кажется, что отбрасывание SoapException должно отформатировать ответ по мере необходимости, а не только с сообщением об исключении. Любая помощь с благодарностью получила.Throwing SoapException в .Net веб-сервисе

Я пытаюсь вернуть SoapException, который должен выглядеть следующим образом (пример):

HTTP/1.1 500 Internal Server Error. 
Date: Wed, 26 May 2004 05:12:08 GMT 
Server: Microsoft-IIS/6.0 
X-Powered-By: ASP.NET 
X-AspNet-Version: 1.1.4322 
Cache-Control: private 
Content-Type: text/xml; charset=utf-8 
Content-Length: 488 

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

    <soap:Fault> 
    <faultcode>soap:Server</faultcode> 
    <faultstring>BlahBlahBlahBlahBlah</faultstring> 
    <detail /> 
    </soap:Fault> 

</soap:Body> 
</soap:Envelope> 

Для этого я реализовал подобный код, взятый с сайта MSDN для SoapException:

Imports System 
Imports System.Web.Services 
Imports System.Web.Services.Protocols 
Imports System.ComponentModel 
Imports System.Xml.Serialization 
Imports System.Xml 

<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _ 
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _ 
<ToolboxItem(False)> _ 
Public Class Service1 
    Inherits System.Web.Services.WebService 

    <WebMethod()> 
    Public Sub Process() 
     ' Build the detail element of the SOAP fault. 
     Dim doc As New System.Xml.XmlDocument() 
     Dim node As System.Xml.XmlNode = doc.CreateNode(XmlNodeType.Element, _ 
      SoapException.DetailElementName.Name, _ 
      SoapException.DetailElementName.Namespace) 

     ' Build specific details for the SoapException. 
     ' Add first child of detail XML element. 
     Dim details As System.Xml.XmlNode = doc.CreateNode(XmlNodeType.Element, _ 
      "mySpecialInfo1", "http://tempuri.org/") 

     ' Add second child of detail XML element with an attribute. 
     Dim details2 As System.Xml.XmlNode = doc.CreateNode(XmlNodeType.Element, _ 
      "mySpecialInfo2", "http://tempuri.org/") 
     Dim attr As XmlAttribute = doc.CreateAttribute("t", "attrName", _ 
      "http://tempuri.org/") 
     attr.Value = "attrValue" 
     details2.Attributes.Append(attr) 

     ' Append the two child elements to the detail node. 
     node.AppendChild(details) 
     node.AppendChild(details2) 

     'Throw the exception  
     Dim se As New SoapException("Fault occurred", SoapException.ClientFaultCode, _ 
            Context.Request.Url.AbsoluteUri, node) 
     Throw se 
     Return 
    End Sub 
End Class 

Однако, когда я запускаю это, фактический ответ послали:

HTTP/1.1 500 Internal Server Error 
Server: ASP.NET Development Server/10.0.0.0 
Date: Wed, 03 Jul 2013 13:06:26 GMT 
X-AspNet-Version: 2.0.50727 
Cache-Control: private 
Content-Type: text/plain; charset=utf-8 
Content-Length: 233 
Connection: Close 

System.Web.Services.Protocols.SoapException: Fault occurred 
    at MyService.Service1.Process() in C:\MyLocation\MyService\Service1.asmx.vb:line 42 

Как получить ответ отформатирован как:

<soap:Envelope> 
    <soap:Body> 
     <soap:Fault> 
      <faultcode/> 
      <faultstring/> 
      <detail/> 
     </soap:Fault> 
    </soap:Body> 
</soap:Envelope> 

ответ

1

Ваш код должен работать и дать вам форматированный ошибку согласно примеру MSDN или, если вы хотите результат, как в образце ответа вы в курсе, то сервис как это следует сделать трюк:

Imports System 
Imports System.Web.Services 
Imports System.Web.Services.Protocols 
Imports System.ComponentModel 
Imports System.Xml.Serialization 
Imports System.Xml 

<WebService(Namespace:="http://tempuri.org/")> _ 
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _ 
<ToolboxItem(False)> _ 
Public Class Service1 
    Inherits WebService 

    <WebMethod()> 
    Public Sub Process() 
     Dim detailsNode As XmlNode = Nothing 
     Dim actorString As String = Nothing 
     Throw New SoapException("BlahBlahBlahBlahBlah", SoapException.ServerFaultCode, actorString, detailsNode) 
    End Sub 
End Class 

вызов так:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <tem:Process/> 
    </soapenv:Body> 
</soapenv:Envelope> 

должен вернуть это:

<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> 
     <soap:Fault> 
     <faultcode>soap:Server</faultcode> 
     <faultstring>BlahBlahBlahBlahBlah</faultstring> 
     <detail/> 
     </soap:Fault> 
    </soap:Body> 
</soap:Envelope> 

Вы также должны добавить это в файл Web.config, чтобы удалить StackTrace в строке неисправностей:

<configuration> 
    <system.web> 
     <customErrors mode="On" /> 
     ... 
    ...  
... 

Кроме того, это, как правило, не нужно строить SoapException вручную, но бросить более соответствующие исключения, и пусть ASP.NET оберните его в SoapFault. См. Здесь для получения более подробной информации: Using SOAP faults.

Чтобы позвонить по вашему методу, используйте SoapUI, и вы должны получить вышеуказанный результат. Убедитесь, что вы сделали POST на конечной точке SOAP, например. http://localhost:8080/Service1.asmx, а не URL-адрес тестовой страницы при нажатии кнопки «Вызов», например. http://localhost:8080/Service1.asmx/Process как это не возвращает отформатированные ответы SOAP.

+0

Я использую Fiddler (http://www.fiddler2.com) для отслеживания запроса и ответа, и они приведены в вопросе. Добавление ' anothershrubery

+0

@anothershrubery: см. Мой обновленный ответ. Какую конечную точку вы используете для вызова? Используйте SoapUI прямо на URL asmx, и вы должны получить ошибку SOAP. – Bogdan

+0

Спасибо, я использовал SoapUI и увидел правильный формат. Я думал, что отладочный прокси, такой как Fiddler, вернет точный запрос/ответ? Очевидно нет. Таким образом, я все время принимал правильную вещь, просто не использую правильные вещи для ее просмотра. Приветствия. – anothershrubery