skip to Main Content

I have a old webservice that will throw an exception under certain condition. However, currently, the exception will include the stacktrace(path, method name, etc). I created a customized exception and overwrite the StackTrace property in an attempt to hide it.

Simplified example:

    [WebMethod]
    public List<Object> GetISShipments(string userToken)
    {
        User user = GetUserFromToken(userToken);
        try
        {
            if (!user.CountryList.Contains("IS"))
            {
                throw new ServiceException($"Access denied for country");
            }
        }catch(Exception ex)
        {
            throw;
        }

        return new List<Object>();
    }

and I tried to overwrite the exception like so

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;

[Serializable]
public class ServiceException : Exception
{
    public ServiceException() { }
    public ServiceException(string message) : base(message) { } 
    public ServiceException(string message, Exception innerException) : base(message, innerException) { }
    public ServiceException(SerializationInfo info, StreamingContext context) : base(info, context) { }

    public override string StackTrace
    {
        get { return String.Empty; }
    }
}

Problem I have:

When invoking the webservice directly in the visual studio with a browser, the exception is hidden. However, when I tried to call it using SoapUI, I am still getting the exception with stacktrace.

HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcR0RJVCBUZW1wXERlc2t0b3BcTmV3RUZUU1xFRlRTXEVmdHNXZWJTZXJ2aWNlc1xDb250aW5nZW5jeVNoaXBtZW50cy5hc214?=
X-Powered-By: ASP.NET
Date: Wed, 22 Feb 2023 18:21:41 GMT
Content-Length: 688

<?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>System.Web.Services.Protocols.SoapException: Server was unable to process request. ---&gt; ServiceException: Access denied for country
   at myNameSpace.MyClass.GetISShipments(String userToken) in C:UsersmyUserDesktopNewProjectProjectMyWebServicesApp_CodeContingencyShipments.cs:line 66
   --- End of inner exception stack trace ---</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>

Other information

.Net Version: 4

I know that it is better to wrap the response into an response object with error message than returning the class object itself. However, this is a very old webservice that is consumed by a lot of old processes for my customer. So I am trying to find a way to achieve this without having my customer to change anything on their end.

So is there a way to achieve this?

2

Answers


  1. If you look at the error thrown it actually says the following End of inner exception stack trace.

    The stack trace is coming from the InnerException, not your custom exception. So although you have overridden the StackTrace, you’ve only done it for the top level exception.

    You can override the .ToString() method instead to only display information you want

    [Serializable]
    public class ServiceException : Exception
    {
        public ServiceException() { }
        public ServiceException(string message) : base(message) { } 
        public ServiceException(string message, Exception innerException) : base(message, innerException) { }
        public ServiceException(SerializationInfo info, StreamingContext context) : base(info, context) { }
    
        public override string ToString()
        {
            // Return anything you need here
            return Message;
        }
    }
    
    Login or Signup to reply.
  2. You could throw a SoapException instead, with null details, then the stack trace won’t show up.

    [WebMethod]
    public List<Object> GetISShipments(string userToken)
    {
        User user = GetUserFromToken(userToken);
        if (!user.CountryList.Contains("IS"))
        {
            throw new SoapException(message: "Access denied for country", code: SoapException.ServerFaultCode, actor: Context.Request.Url.AbosoluteUri, detail: null);
        }
    
        return new List<Object>();
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search