在的WebAPI方法异常时返回出错消息给最终用户的(Returning an error messa

2019-10-21 18:28发布

我目前正在建设,与我的应用程序允许用户点击一个按钮的触发一系列触发我一把umbraco网站的内容更新的Web服务请求的后台连接一个的WebAPI服务。

我的WebAPI服务类是设置为这样:

public class MyController : UmbracoApiController{
     // Global variable declarations go here

     private MyController(){
          // assign actual values to global variables here
     }

     public string GetAllUpdates(){
          try{
              GetCountries();
              GetAreas();
              GetCities();
              ...
          }
          catch (TimeoutException ex)
          {
               Log.Error("Web Service Timeout", ex);
               return "Failed to contact web services.";
          }
          catch (Exception ex)
          {
               Log.Error("Exception", ex);
               return "An error has occurred.";
          }
     }

     public string GetCountries(){
         try{
               // Main code here
         }
         catch(TimeoutException ex){
           Log.Error("Web Service Timeout", ex);
           return "Failed to contact web services.";
         }
         catch(Exception ex){
           Log.Error("Exception", ex);
           return "An error has occurred.";
         }
     }

     .....
}

我的WebAPI方法是通过使用AngularJS和HTML的调用。 当用户点击相关的网络API方法的按钮,该方法被运行,那么一条消息被返回到在该方法的成功或失败的用户。

所以,如果我是运行的getCountries使用相应的按钮将屏幕说:“国家成功更新”在成功上显示的消息()方法或代替它会输出都在抓定义返回的消息之一。

我的主要问题是GetAllUpdates()方法运行的所有其他方法一前一后。 这是很好,我在成功时说:“所有更新的内容”,然而设置真的分崩离析,当一个例外的另一种方法是打回的消息。 例如,的getCountries()首先运行。 如果有异常这里提出,没有消息被返回到屏幕上的应用程序简单地移动到下一个方法GetAreas()。 这种传播贯穿始终,然后在显示成功消息给用户一个假象,更新进展顺利。

因此,我的问题是,我该如何停止GetAllUpdates()方法如果出现异常,而不修改我的其他方法回报链运行后续方法? 该方法需要返回,这样当他们在自己的但是,当作为GetAllUpdates的一部分,跑了()返回的catch块的错误消息,如同该方法是完全成功的正在接受治疗的运行屏幕上显示的消息的字符串而用户没有明智的。

任何帮助将不胜感激。

NB遵循以下我改变了我的WebAPI方法做如下的答复之一后:

NEW CLASS

public class ResponseMessage
    {
        public bool Result { get; set; }
        public string Message { get; set; }
    }

回报方法

            ResponseMessage response = new ResponseMessage();
            String json = string.Empty;

            response.Result = true;
            response.Message = "Content update successful";

            json = JsonConvert.SerializeObject(response);
            return json;

我的角代码如下:

 angular.module("umbraco")
.controller("AxumTailorMade",
function ($scope, $http, AxumTailorMade) {
    $scope.getAll = function() {
        $scope.load = true;
        $scope.info = "Retreiving updates";
        AxumTailorMade.getAll().success(function (data) {
            var response = JSON.parse(data);
            $scope.result = response.Result;
            $scope.info = response.Message;
            $scope.load = false;
        });
    };

  });

angular.module("umbraco.services").factory("AxumTailorMade", function ($http) {
    return {
        getAll: function () {
            return $http.get("/umbraco/api/axumtailormade/getallupdates");
        },
        getRegions: function () {
            return $http.get("/umbraco/api/axumtailormade/getregions");
        },
        getCountries: function () {
            return $http.get("/umbraco/api/axumtailormade/getcountries");
        },
        getAreas: function () {
            return $http.get("/umbraco/api/axumtailormade/getareas");
        },
        getCities: function () {
            return $http.get("/umbraco/api/axumtailormade/getcities");
        },
        getCategories: function () {
            return $http.get("/umbraco/api/axumtailormade/getcategories");
        },
        getPackages: function () {
            return $http.get("/umbraco/api/axumtailormade/getpackages");
        },
        getHotels: function () {
            return $http.get("/umbraco/api/axumtailormade/gethotels");
        },
        getActivities: function () {
            return $http.get("/umbraco/api/axumtailormade/getactivities");
        }
    };
})

Answer 1:

而不是返回从你的方法一个字符串,你能代替返回包含了客户端的结果和消息的简单对象?

public class ResponseMessage
{
    public bool Result { get; set; }
    public string Message { get; set; }
}

然后,在执行时GetAllUpdates()则需要检查的结果GetCountries() GetAreas()GetCities()和追加任何错误消息。

public ResponseMessage GetAllUpdates()
{
    ResponseMessage response;

    response = GetCountries();
    if (!response)
    {
        return response;
    }

    response = GetAreas();
    if (!response)
    {
        return response;
    }

    response = GetCities();
    if (!response)
    {
        return response;
    }

    response.Result = true;
    response.Message = "Successful";

    return response;
}

public ResponseMessage GetCountries()
{
    var response = new ResponseMessage();

    try
    {
        // Your main code here, call services etc

        response.Result = true;
        response.Message = "GetCountries successful";
    }
    catch (TimeoutException ex)
    {
        Log.Error("Web Service Timeout", ex);
        response.Result = false;
        response.Message = "Failed to contact web services.";
    }
    catch (Exception ex)
    {
        Log.Error("Exception", ex);
        response.Result = false;
        response.Message = "An error has occurred.";
    }

    return response;
}

这是多一点的努力和代码,但也将让您在福禄的返回到客户端什么更多的控制和。 您还可以优化其相当多的我敢肯定,我只是灭掉你的一般方法...



Answer 2:

You can update your `GetAllUpdate` method something like this

public string GetAllUpdates(){
          try{
              var result = GetCountries();

              if(string.isNullOrEmpty(result)
               return result;


              result  = GetAreas();

              if(string.isNullOrEmpty(result)
               return result;

              result  = GetCities();

              if(string.isNullOrEmpty(result)
               return result;

              ...

              result = "All updated successfully";

              return result;

          }
          catch (TimeoutException ex)
          {
               Log.Error("Web Service Timeout", ex);
               return "Failed to contact web services.";
          }
          catch (Exception ex)
          {
               Log.Error("Exception", ex);
               return "An error has occurred.";
          }
     }


Answer 3:

我建议你居然摆脱了GetAllUpdates()方法,并调用特定的Get****()AngularJS分开的方法。

这将具有以下优点:

  1. 你可以并行执行(更好的性能)的方法,并处理返回值(或可能的错误消息)分开。
  2. 按照我的理解 - 那的getCountries()失败并不意味着GetAreas(事实)发生故障或不应该执行; 它只是需要这个GetAllUpdates()方法。 因此,您可以独立处理每个错误,同时让尽可能多的方法,成功成为可能。

如果你不希望/需要调用并行的具体方法,但它仍然会比较好,在我看来,打电话给他们一个接一个,挂在调用以后每一个关闭其前任的承诺(见“链接承诺”在这里: https://docs.angularjs.org/api/ng/service/ $ q)

最后 - 我将无法返回的WebAPI方法的字符串。 相反 - 你应该返回成功的HTTP 200码(即做出无效的方法,根本没有做什么特别的),或因任何错误已经发生特定的HTTP代码。 在角然后可以使用.catch()来处理异常。 这样,你的消息将不会在的WebAPI代码来决定 - 但在客户端。

如何从的WebAPI返回状态401 AngularJS,还包括一个自定义消息?

编辑:

如果客户端选项是不可能的,我会做从服务器代码嵌套的try / catch块的调用:

 public string GetAllUpdates()
 {
      try
      {
          GetCountries();
          try 
          {
              GetAreas();
              // ... and so on
          }
          catch(Exception ex)
          {
              return "Error getting areas";
          }

      }
      catch(Exception ex) 
      {
          return "Error getting countries";
      }

或者,你可以把电话和相应的错误信息到列表:

var calls = new List<Action> { GetCountries, GetAreas, Get... };
var errorMessages = new List<string> { "Error getting countries", "Error getting areas", "Error getting ..."} ;

然后调用for循环的方法:

for(var i = 0; i < calls.Count; i++) 
{
    try 
    {
        var call = calls[i];
        call();
    }
    catch(Exception ex) 
    {
        return errorMessages[i];
    } 
}

说得通? (很抱歉,如果代码不编译,我不是一个编译器检查它不幸)



文章来源: Returning an error message to an end user upon exception in WebApi methods