2016-09-23 93 views
1

在开发利用Web API的新Web应用程序时,我决定创建一组可容纳事务结果的基本“响应”类是一个好习惯,在将来会有任何警告,错误或任何其他必要的数据。样品下面:Web API将自定义异常对象转换为基本异常

public class VoidResultsVM 
{ 
    public bool IsSuccess { get; set; } 
    public List<string> Results { get; set; } 
    public List<Error> Errors { get; set; } 
    public List<Alert> Alerts { get; set; } 

    public VoidResultsVM() 
    { 
     Results = new List<string>(); 
     Errors = new List<Error>(); 
     Alerts = new List<Alert>(); 
    } 
} 

绑到该响应对象是从在.NET Exception类衍生自定义异常的对象的列表(“错误”)。这些类的主要好处是我们可以确切地确定发生错误的位置,并且可以向用户添加自定义消息来解释错误。下面的示例:

public class Error : Exception 
{ 
    //public Exception Exception { get; set; } 
    public string Origin { get; set; } 
    public string UserMessage {get; set;} 
    private DateTime timeStamp; 
    public DateTime TimeStamp { get { return timeStamp; } set { timeStamp = DateTime.Now; } } 
    public string Resolution { get; set; } 


    public Error(string msg, Exception ex, string origin, string usermessage, DateTime @timestamp, string resolution = "") 
     :base(msg, ex) 
    { 
     Origin = origin; 
     UserMessage = usermessage; 
     TimeStamp = @timestamp; 
     Resolution = resolution; 
    } 
} 

该对象已在开发和调试应用程序的后端是非常有用的,我希望保持这种尽可能。我正在运行的问题是,当尝试通过几个API操作时,如果其中一个“错误”对象返回,Web API(我相信)正在将该“错误”对象转换为其基类Exception。请参阅下面从API输出的JSON:

{ 
    "IsSuccess": false, 
    "Results": [], 
    "Errors": [{ 
     "ClassName": "App.Models.Error", 
     "Message": "Error getting history", 
     "Data": { 

     }, 
     "InnerException": { 
      "ClassName": "System.Exception", 
      "Message": "No records found for criteria", 
      "Data": null, 
      "InnerException": null, 
      "HelpURL": null, 
      "StackTraceString": " at App.Database.DatabaseCore.GetHistory(HistorySearchVM history)", 
      "RemoteStackTraceString": null, 
      "RemoteStackIndex": 0, 
      "ExceptionMethod": "8\nGetShipmentHistory\nApp.Database, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\nApp.Database.DatabaseCore\nApp.Models.ViewModels.VoidResultsVM GetHistory(App.Models.ViewModels.HistorySearchVM)", 
      "HResult": -2146233088, 
      "Source": "App.Database", 
      "WatsonBuckets": null 
     }, 
     "HelpURL": null, 
     "StackTraceString": null, 
     "RemoteStackTraceString": null, 
     "RemoteStackIndex": 0, 
     "ExceptionMethod": null, 
     "HResult": -2146233088, 
     "Source": null, 
     "WatsonBuckets": null 
    }], 
    "Alerts": [] 
} 

所以我的问题是这样的:我怎样才能改变我的“错误”类,以便回发到时该Web API不将其转换回基类客户?这是甚至可以被覆盖的东西吗?

编辑

下面是从API控制器和数据库的代码来创建并返回此对象。有代码中没有逻辑错误对象转换为或从异常对象:

API控制器

public VoidResultsVM Search(SearchVM vm) 
    { 
     DatabaseCore db = new DatabaseCore(); 
     VoidResultsVM results = new VoidResultsVM(); 
     try 
     { 
      if (ModelState.IsValid) 
      { 
       results = db.GetRecordById(vm.Id); 
      } 
      else 
      { 
       throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest)); 
      }; 
     } 
     catch (Error) 
     { 
      throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest)); 
     } 
     catch (Exception) 
     { 
      throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest)); 
     } 
     db = null; 
     return results; 
    } 

数据库

public Record GetRecordById(int id) 
    { 
     Record i = null; 
     using (var transactionScope = TransactionScopeBuilder.CreateReadCommitted()) 
     { 
      AppContext tempContext = null; 
      try 
      { 
       using (tempContext = new AppContext()) 
       { 
        i = tempContext.Records.Where(x => x.Id == id).FirstOrDefault(); 
       } 
      } 
      catch (Exception ex) 
      { 
       Common.Common.Log("", logName, Common.Common.LogLevels.ERROR, ex); 
       throw new Error(ex.Message, ex, "DATABASE", "", DateTime.Now); 
      } 
      finally 
      { 
       transactionScope.Complete(); 
      } 
     } 
     return i; 
    } 
+0

当你调试它是一个'错误'键入你的代码一路?你能提供你实际返回/序列化响应的代码吗? – Wurd

+0

据我所知,只有返回信息是因为您启用了异常详细信息。也许它不会转换异常的标准属性。看看[this](http://www.asp.net/web-api/overview/error-handling/exception-handling#exceptionfilters)并找到关于异常过滤器的部分。你有的例外是好的,但我会将其转换为错误消息模型。暴露API中的异常堆栈跟踪通常是不好的做法。这应该只记录在调试日志中。 – Michael

回答

0

通过一些解决方案的工作后,我决定与迈克尔的建议一起返回一个专用视图模型,该视图模型包含调试使用最多的额外信息,并仅记录完整的错误模型。