我目前正在构建一个WebApi服务,该服务与我的应用程序的后台连接,允许用户单击按钮触发一系列Web服务请求,触发我的Umbraco网站更新内容。
我的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.";
}
}
.....
}
通过使用AngularJS和HTML调用我的WebApi方法。当用户单击与Web Api方法相关的按钮时,将运行该方法,然后在方法成功或失败时将消息返回给用户。
因此,如果我使用相关按钮运行GetCountries()方法,屏幕上会显示一条消息,表示“国家已成功更新成功”,或者输出其中一条消息定义
我的主要问题是GetAllUpdates()方法一个接一个地运行所有其他方法。这很好,我在成功时返回一条消息,说“所有内容都已更新”,但是当其他方法中出现异常时,设置确实崩溃了。例如,首先运行GetCountries()。如果此处引发异常,则不会向屏幕返回任何消息,应用程序只会移动到下一个方法GetAreas()。这会传播到最终显示成功消息的结尾,从而给用户一个错误的印象,即更新进展顺利。
因此,我的问题是,如果发生异常而不修改其他方法中的返回,我如何暂停GetAllUpdates()方法在链中运行后续方法?这些方法需要返回一个字符串,以便消息在它们自己运行时显示在屏幕上,但是当作为GetAllUpdates()的一部分运行时,catch块中返回的错误消息被视为方法完全成功并且用户不是更聪明的人。
非常感谢任何帮助。
N.B。在完成下面的一个响应之后,我改变了我的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");
}
};
})
答案 0 :(得分:2)
您是否可以返回一个包含客户端结果和消息的简单对象,而不是从您的方法中返回一个字符串?
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;
}
这需要更多的努力和代码,但也会让您更好地控制流量以及返回给客户端的内容。你也可以对它进行很多优化我很确定,我只是为你找到了一个通用的方法......
答案 1 :(得分:0)
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.";
}
}
答案 2 :(得分:0)
我建议您实际摆脱GetAllUpdates()
方法,并从 AngularJS 中单独调用特定的Get****()
方法。
这将具有以下优点:
如果你不想/需要并行调用特定的方法,在我看来,一个接一个地调用它们仍然会更好,将其调用挂在其前一个承诺的后续版本上(参见“链接承诺”:https://docs.angularjs.org/api/ng/service/ $ q)
最后 - 我不会从WebAPI方法返回一个字符串。相反 - 您应该返回HTTP 200代码以获得成功(即使方法无效,并且根本不做任何特殊操作),或者针对发生的任何错误返回特定的HTTP代码。 在Angular中,您可以使用.catch()来处理异常。这样,您的消息将不会在WebAPI代码中决定 - 而是在客户端。
How do you return status 401 from WebAPI to AngularJS and also include a custom message?
编辑:
如果无法使用客户端选项,我将通过服务器代码中的嵌套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];
}
}
有意义吗? (对不起,如果代码没有编译,我不会在编译器中检查它)