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

时间:2016-09-23 15:24:43

标签: c# .net asp.net-mvc asp.net-web-api exception-handling

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

绑定到此响应对象的是自定义异常对象(&#34;错误&#34;)的列表,这些对象派生自.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操作时,如果其中一个&#34;错误&#34;对象返回,Web API(我相信)正在转换那个&#34;错误&#34;对象的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": []
}

所以我的问题是:我怎样才能改变我的错误&#34;类,以便Web API在发回客户端时不会将其转换回基类?这是否可以被覆盖?

修改

以下是API控制器和数据库中用于创建和返回此对象的代码。代码中没有逻辑将错误对象转换为Exception对象或从Exception对象转换:

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

1 个答案:

答案 0 :(得分:0)

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