Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Web API控制器中的异常处理和引发自定义错误消息_C#_Asp.net Web Api_Exception Handling_Soa - Fatal编程技术网

C# Web API控制器中的异常处理和引发自定义错误消息

C# Web API控制器中的异常处理和引发自定义错误消息,c#,asp.net-web-api,exception-handling,soa,C#,Asp.net Web Api,Exception Handling,Soa,在我的一个项目中,我正在使用具有某种SOA架构的Web API。在控制器中,我希望捕获异常(由存储库引发)并返回HttpResposeMessage 我想要的是应该有一个继承ApicController的BaseController(类BaseController:ApicController)并且我的每个控制器都应该由baseController继承,例如类TaskController:baseController,如果我的控制器中发生任何异常,那么它应该由baseController处理。

在我的一个项目中,我正在使用具有某种SOA架构的Web API。在控制器中,我希望捕获异常(由存储库引发)并返回
HttpResposeMessage


我想要的是应该有一个继承ApicController的BaseController(
类BaseController:ApicController
)并且我的每个控制器都应该由baseController继承
,例如
类TaskController:baseController
,如果我的控制器中发生任何异常,那么它应该由
baseController
处理。 演示:

以下是VS解决方案中的项目:(项目结构)

代码: XYZ.模型

public class Error
{
    public string Code { get; set; }
    public string Message { get; set; }

}
XYZ.异常

// To create the custom exception as per our need
public class BaseException : Exception
{
    private Error _error;
    public Error Error
    {
        get { return _error; }
    }

    public BaseException()
    {
        _error = new Error();
    }

    public void SetErrorCode(string code)
    {
        _error.Code = code;
    }

    public void SetErrorMessage(string message)
    {
        _error.Message = message;
    }
}


public class TaskNotFoundException : BaseException
{
    public TaskNotFoundException()
    {
        string errorCode = "T0001";
        base.SetErrorCode(errorCode);
        base.SetErrorMessage((new ExceptionMessage()).GetExceptionMessage(errorCode));
    }
}
存储库

public Task UpdateTaskDetails(Task task)
{
    try
    {
        //--Task updating logic--//
    }
    catch (Exception ex)
    {
        throw new TaskUpdateFailedException();
    }
    return task;
}
XYZ.WebServices

public class BaseController : ApiController
{
    public HttpResponseMessage CreateResponseMessage()
    {
        try
        {
            GetTasksByUserIdAndProjectId(new TaskQuery());
        }
        catch(BaseException exception)
        {
            return Request.CreateResponse(HttpStatusCode.InternalServerError, exception.Error);
        }
    }

    public virtual  List<Task> GetTasksByUserIdAndProjectId(TaskQuery query)
    {
        Console.WriteLine("I can be overridden");
    }
}


public class TaskController : BaseController
{
    [HttpPost]
    public override List<Task> GetTasksByUserIdAndProjectId(TaskQuery query)
    {
        return _taskRepo.GetTasksByUserIdAndProjectId(query.UserId, query.ProjectId);
    }

}
公共类BaseController:ApiController
{
公共HttpResponseMessage CreateResponseMessage()
{
尝试
{
getTaskByUserIDandProjectId(新任务查询());
}
catch(BaseException异常)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError,exception.Error);
}
}
公共虚拟列表GetTaskByUserId和ProjectId(任务查询)
{
Console.WriteLine(“我可以被覆盖”);
}
}
公共类TaskController:BaseController
{
[HttpPost]
公共覆盖列表GetTaskByUserId和ProjectId(任务查询)
{
返回_taskRepo.gettasksbyuserid和ProjectId(query.UserId,query.ProjectId);
}
}
TaskController
中,如果在
gettasksbyuserid和projectid
方法中发生任何异常,它应该将异常抛出到
BaseController CreateReponseMessage()
中,并在那里将
HttpResponseMessage
返回给客户端。

注意:在每个控制器中都有多个Get/Put/Post方法,因此不可能在
BaseController
中声明所有方法(web服务方法)来捕获项目当前结构中的子类异常。


在我的项目中,有没有更好的方法来处理Web API中的异常?我们使用的异常过滤器如下所示:

首先,我们创建自己的异常:

public class UserFriendlyException: Exception
    {
        public UserFriendlyException(string message) : base(message) { }
        public UserFriendlyException(string message, Exception innerException) : base(message, innerException) { }
    }
然后我们创建一个过滤器:

public class UserFriendlyExceptionFilterAttribute: ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext context)
        {
            var friendlyException = context.Exception as UserFriendlyException;
            if (friendlyException != null)
            {
                context.Response = context.Request.CreateResponse(HttpStatusCode.BadRequest, new {Message = friendlyException.Message}); 
            }
        }
    }
最后,在WebApi的配置中,我们添加了这个过滤器

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            ...


            config.Filters.Add(new UserFriendlyExceptionFilterAttribute());

            ...
        }
    }

使用此解决方案,您可以在代码中的任何位置抛出UserFriendlyException,并且响应将根据筛选器进行。

我们使用的异常筛选器如下所示:

首先,我们创建自己的异常:

public class UserFriendlyException: Exception
    {
        public UserFriendlyException(string message) : base(message) { }
        public UserFriendlyException(string message, Exception innerException) : base(message, innerException) { }
    }
然后我们创建一个过滤器:

public class UserFriendlyExceptionFilterAttribute: ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext context)
        {
            var friendlyException = context.Exception as UserFriendlyException;
            if (friendlyException != null)
            {
                context.Response = context.Request.CreateResponse(HttpStatusCode.BadRequest, new {Message = friendlyException.Message}); 
            }
        }
    }
最后,在WebApi的配置中,我们添加了这个过滤器

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            ...


            config.Filters.Add(new UserFriendlyExceptionFilterAttribute());

            ...
        }
    }

使用此解决方案,您可以在代码中的任何位置抛出UserFriendlyException,响应将根据筛选器而定。

使用异常筛选器可以更好地完成此操作。@Nkosi,感谢您的建议,我已经实现了异常筛选器,它工作正常。但我还有一个问题“我们可以在异常过滤器中处理一些验证失败错误之类的事情吗?因为验证失败不是异常,但我希望它在一个普通类中处理。”使用异常过滤器可以更好地做到这一点。@Nkosi,谢谢你的建议,我已经实现了异常过滤器,它工作正常。但我还有一个问题“我们能在异常过滤器中处理一些验证失败错误吗?因为验证失败不是异常,但我希望它在一个普通类中处理。”谢谢你的回答,我已经实现了异常过滤器,它工作得很好。但我还有一个问题“我们能在异常过滤器中处理一些验证失败错误吗?因为验证失败不是异常,但我希望它在一个普通类中处理。”。谢谢你的回答,我已经实现了异常过滤器,它工作得很好。但我还有一个问题,“我们可以在异常过滤器中处理一些验证失败错误之类的事情吗?因为验证失败不是异常,但我希望它在一个公共类中处理。”。