Web API将自定义Exception对象转换为基Exception

本文关键字:Exception 转换 对象 Web 自定义 API | 更新日期: 2023-09-27 18:08:34

在利用web API开发一个新的web应用程序时,我认为创建一组基本的"响应"类是一个很好的做法,这些类可以容纳事务的结果,以及将来的任何警告、错误或任何其他必要的数据。下面的示例:

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>();
    }
}

绑定到这个响应对象的是自定义异常对象("Error")的列表,这些对象派生自。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(我相信)正在将该"错误"对象转换为异常的基类。下面是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控制器和数据库创建和返回这个对象的代码。代码中没有逻辑将错误对象转换为Exception对象或从Exception对象转换为error对象:

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;
    }

Web API将自定义Exception对象转换为基Exception

在研究了几个解决方案之后,我决定采用Michael的建议,即返回一个专用的视图模型,该模型包含最有调试用途的额外信息,并仅记录完整的错误模型。