更具体地说,当异常包含自定义对象时,这些自定义对象本身可以是自身可序列化的
举个例子:
public class MyException : Exception
{
private readonly string resourceName;
private readonly IList<string> validationErrors;
public MyException(string resourceName, IList<string> validationErrors)
{
this.resourceName = resourceName;
this.validationErrors = validationErrors;
}
public string ResourceName
{
get { return this.resourceName; }
}
public IList<string> ValidationErrors
{
get { return this.validationErrors; }
}
}
Run Code Online (Sandbox Code Playgroud)
如果此异常序列化和反序列化,则不会保留两个自定义属性(ResourceName和ValidationErrors).属性将返回null.
是否有用于实现自定义异常序列化的通用代码模式?
我想写一个MS Message Queue的异常.当我尝试它时,我得到一个例外.所以我尝试使用仍然引发异常的XmlSerializer来简化它,但它给了我更多信息:
{"反映类型'System.Exception'时出错."}
与InnerException:
{"无法序列化System.Collections.IDictionary类型的成员System.Exception.Data,因为它实现了IDictionary."}
示例代码:
Exception e = new Exception("Hello, world!");
MemoryStream stream = new MemoryStream();
XmlSerializer x = new XmlSerializer(e.GetType()); // Exception raised on this line
x.Serialize(stream, e);
stream.Close();
Run Code Online (Sandbox Code Playgroud)
编辑:我尽量保持这个简单,但我可能已经过头了.我想要整个位,堆栈跟踪,消息,自定义异常类型和自定义异常属性.我甚至可能想再次抛出异常.
虽然我意识到有一个类似的问题(如何在C#中序列化异常对象?),虽然该页面上的答案很有帮助,但它们并没有完全解决问题或回答提出的问题.
我相信问题是如何序列化对象以允许它被重建(反序列化)到同一个对象中.我试图使用davogones和Antony Booth给出的解决方案,但是没有System.Exception在消费方面添加基类(如:),SerializationException: Exception不可能将这些类型(通过它们自己)用作可以抛出的实际异常对象.
在我继续之前,让我解释一下最后的陈述.我试图在Web服务中使用Antony Booth的解决方案(该服务包含可序列化对象的定义),试图让所有消费者使用相同的异常(希望创建一个可重用的可序列化异常类型,而不是重新创建它) .
不幸的是,由于两种类型都没有明确地衍生出来System.Exception,你不能使用throw它们,这显然是有用的.就像我上面提到的那样,似乎: Exception在消费方面添加类型类定义允许抛出对象,但这需要编辑自动生成的WSDL/Web服务代码,这看起来像是一个糟糕/不可维护的实践对我(如果我错了,请纠正我).
我的第一个问题是,是否可以序列化System.Exception或创建可以序列化的派生类型,如果可能的话,怎么会这样做呢?我应该提一下,我已经看过了重建这个Exception对象的正式方法,但我恐怕不太了解它.
我的第二个问题是关于System.Exception自身的架构.我想知道的是为什么System.Exception类型被标记为何[Serializable]时被记录并且显然被设计为禁止您正确地序列化它(至少使用XML),因为它的Data对象是实现的IDictionary?
来自MSDN:
问:为什么我不能序列化哈希表?
答:XmlSerializer无法处理实现IDictionary接口的类.这部分是由于计划约束,部分原因是哈希表在XSD类型系统中没有对应物.唯一的解决方案是实现一个不实现IDictionary接口的自定义哈希表.
鉴于XML正在成为(如果不是已经是)数据传输的新标准(尽管如此,微软正式推荐),不允许.NET中唯一可以抛出的对象类型不是XML可序列化的,这似乎是非常愚蠢的. .
我期待听到所有SO'rs的一些想法(特别是因为这是我的第一篇文章).
如果您有疑问或需要澄清,请随时告诉我.
注意:我刚刚发现了这个SO帖子,它似乎回答了几个问题,但我想我想对此进行自己的打击.但是,让我知道它是否太接近重复.
C#异常是可序列化的,因此它们也不能同时是DataContracts,因此我不能使用JsonDataContractSerializer。
有什么方法可以将Exceptions序列化为JSON?
我正在尝试微调我的MVC应用程序中的错误处理.
我在web.config中启用了自定义错误,并添加了以下代码Application_Error.
Global.asax中
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError() as Exception;
if (exception != null)
{
Context.ClearError();
Context.Response.TrySkipIisCustomErrors = true;
string path = (exception is HttpException && (exception as HttpException).GetHttpCode() == 404) ?
"~/Error/NotFound" :
"~/Error/Index";
Context.Server.TransferRequest(path, false);
}
}
Run Code Online (Sandbox Code Playgroud)
ErrorController.cs
[AllowAnonymous]
public ActionResult Index()
{
Response.Clear();
Response.StatusCode = 503;
Response.TrySkipIisCustomErrors = true;
return View();
}
[AllowAnonymous]
public ActionResult NotFound()
{
Response.Clear();
Response.StatusCode = 404;
Response.TrySkipIisCustomErrors = true;
return View();
} …Run Code Online (Sandbox Code Playgroud) 我正在为WCF Web服务编写单元测试.我故意向服务器发送无效请求,抛出一个WebExceptionFault<string>.在单元测试中,被抓住的异常是EndpointNotFoundException与标准WebException的InnerException属性.我想验证响应的主体是否匹配我认为应该存在的字符串.
然而,我遇到了一个问题,因为(这是一个)的Response属性是Disposed并且无法读取.WebExceptionSystem.Net.SyncMemoryStream
我的代码:
Clubs actual;
try
{
//"201" is an invalid argument for the first parameter
actual = new Clubs(channel.GetClubs("201", "123"));
}
catch (EndpointNotFoundException e)
{
WebException w = e.InnerException as WebException;
Assert.IsNotNull(w);
HttpWebResponse resp = w.Response as HttpWebResponse;
Assert.IsNotNull(resp);
Assert.AreEqual(resp.StatusCode, HttpStatusCode.NotFound);
//Next line throws an ArgumentException saying Stream not readable
//Investigation shows it has been disposed
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
Assert.AreEqual(sr.ReadToEnd(), "League not allowed …Run Code Online (Sandbox Code Playgroud)