.Net Framework Standard
[C#] WebService .asmx 오류 전역 (예외)처리
달빛에취하다
2019. 6. 17. 17:19
SoapExtension을 상속받아 오류를 전역 단에서 예외처리 하는 부분입니다.
WebService 2.0 인 .asmx는 http 500 에러가 발생할 경우 Global.aspx의 Application_Error 에서 캡쳐가 선행되지 않고 클라이언트로 내려 갑니다.
가끔 보안상의 이유로 오류 세부 내용을 감춰야 하는 등의 처리나 별도 로그를 남기기 위해 사용됩니다.
※ SoapExceptionHandler.cs
public class SoapExceptionHandler : SoapExtension
{
Stream _oldStream;
Stream _newStream;
public override Stream ChainStream(Stream stream)
{
_oldStream = stream;
_newStream = new MemoryStream();
return _newStream;
}
public override void ProcessMessage(SoapMessage message)
{
if (message.Stage == SoapMessageStage.AfterSerialize)
{
_newStream.Position = 0;
if (message.Exception != null && message.Exception.InnerException != null)
{
// 오류가 있을경우
InsertDetailExceptionStream(message.Exception.InnerException);
}
else
{
CopyStream(_newStream, _oldStream);
}
}
else if (message.Stage == SoapMessageStage.BeforeDeserialize)
{
CopyStream(_oldStream, _newStream);
_newStream.Position = 0;
}
}
private void CopyStream(Stream from, Stream to)
{
TextReader reader = new StreamReader(from);
TextWriter writer = new StreamWriter(to);
writer.WriteLine(reader.ReadToEnd());
writer.Flush();
}
private void InsertDetailExceptionStream(Exception exception)
{
XmlDocument doc = new XmlDocument();
doc.Load(_newStream);
XmlNode faultstringNode = doc.SelectSingleNode("//faultstring");
faultstringNode.InnerText = "오류 입니다.~!";
XmlNode detail = doc.SelectSingleNode("//detail");
detail.InnerText = "오류 세부 내용 입니다.";
XmlWriter writer = new XmlTextWriter(_oldStream, Encoding.UTF8);
doc.WriteTo(writer);
writer.Flush();
}
#region Not Used
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return null;
}
public override object GetInitializer(Type serviceType)
{
return null;
}
public override void Initialize(object initializer)
{
}
#endregion
}
※ ExceptionHandlingAttribute.cs
[AttributeUsage(AttributeTargets.Method)]
public class ExceptionHandlingAttribute : SoapExtensionAttribute
{
public override Type ExtensionType { get { return typeof(SoapExceptionHandler); } }
public override int Priority { get { return 0; } set { } }
}
※ 사용방법
[ExceptionHandling] //Attribute 로 사용
[WebMethod(EnableSession = true)]
public byte[] GetLog()
{
if (isSession())
{
return Compress.DataSet(Log.Log.GetLog());
}
return null;
}
[ExceptionHandling] //Attribute 로 사용
[WebMethod(EnableSession = true)]
public bool SetLog(string value1, string value2, string value3, string value4, string value5, string value6, string value7)
{
if (isSession())
{
return Log.Log.SetLog(value1.Decrypt(), value2.Decrypt(), value3.Decrypt(), value4.Decrypt(), value5.Decrypt(), value6.Decrypt(), value7.Decrypt());
}
else
{
return false;
}
}
출처 - https://haacked.com/archive/2005/06/29/ExceptionInjectionUsingCustomSoapExtension.aspx/