microsoft / referencesource

Source from the Microsoft .NET Reference Source that represent a subset of the .NET Framework
https://referencesource.microsoft.com/
MIT License
3.18k stars 1.28k forks source link

Bug in ASP.NET WebServices ServerProtocol.GenerateFaultString() method #10

Closed pvones closed 8 years ago

pvones commented 8 years ago

There is bug in ServerProtocol.GenerateFaultString method at line 136

for (Exception inner = e; inner != null; inner = inner.InnerException) {
  string text = htmlEscapeMessage ? HttpUtility.HtmlEncode(inner.Message) : inner.Message;
  if (text.Length == 0) text = e.GetType().Name;

If there is a custom Exception class that overrides Message property and returns null value thrown in a web service method, the .NET Framework code throws NullReferenceException at text.Length expression because text variable has null value. Please fix it, it is supposed to return correct SOAP fault message. Note that it occurs when custom errors mode is on only.

Possible fix

if (String.IsNullOrEmpty(text)) text = e.GetType().Name;

Trace output

System.Web.Services.Asmx Error: 0 : Exception Details:
System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Web.Services.Protocols.ServerProtocol.GenerateFaultString(Exception e, Boolean htmlEscapeMessage)
   at System.Web.Services.Protocols.Soap11ServerProtocolHelper.WriteFault(XmlWriter writer, SoapException soapException, HttpStatusCode statusCode)
   at System.Web.Services.Protocols.SoapServerProtocol.WriteException(Exception e, Stream outputStream)
   at System.Web.Services.Protocols.WebServiceHandler.WriteException(Exception e)
   at System.Web.Services.Protocols.WebServiceHandler.Invoke()
   at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

Steps to reproduce. Create new (legacy) ASP.NET Web Service

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Services;
using System.Reflection;
using System.Web.Services.Protocols;
using System.Xml;

namespace WebService1
{
    public class MyException : Exception
    {
        public MyException()
            : base(null)
        {
        }

        public override string Message
        {
            get
            {
                // the null Message causes exception in .NET framework method when translating exception into SoapMessage
                // ServerProtocol.GenerateFaultString(Exception e, Boolean htmlEscapeMessage), line 136
                //
                return null; 
            }
        }
    }

    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class Service1 : System.Web.Services.WebService
    {
        [WebMethod]
        public string HelloWorld()
        {
            // ! Required setting in web.config to reproduce the issue !
            //  <system.web>
            //    <customErrors mode="On" />

            throw new MyException();
        }
    }
}

SOAP request

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/HelloWorld</Action>
  </s:Header>
  <s:Body>
    <HelloWorld xmlns:d3p1="http://schemas.datacontract.org/2004/07/" i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/" />
  </s:Body>
</s:Envelope>

SOAP response

<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">
  <s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" />
  <soap:Body>
    <soap:Fault>
      <faultcode>soap:Server</faultcode>
      <faultstring>Server was unable to process request. ---&gt; Object reference not set to an instance of an object.</faultstring>
      <detail />
    </soap:Fault>
  </soap:Body>
</soap:Envelope>
blackdwarf commented 8 years ago

@pvones If you are having issues with the Full .NET Framework or .NET Runtime, the best way to file a bug is at Connect (http://connect.microsoft.com/VisualStudio) or through Product Support (https://support.microsoft.com/en-us/contactus?ws=support) if you have a contract.