C#应该在try catch中使用try catch来处理响应吗?这是个坏主意吗?

时间:2016-12-15 21:25:06

标签: c# .net model try-catch

我的代码处理一些其他API(GET方法)。这个GET方法返回如下响应:

{"error":0,"Logs":[{"LoggerIdx":"91","OfficeID":"MIA1A0955","Agent":"581A78AD"}]}

如果查询没有找到任何内容,则返回:

{"error":0,"Logs":[{"No values found"}]}

我正在使用的代码调用此API来检索值并显示报告:

private string uri = "http://localhost";

    public async Task<List<T>> GetWSObjects<T>(string uriActionString)
    {
        return new List<T> { await this.GetWSObject<T>(uriActionString) };
    }

public async Task<T> GetWSObject<T>(string uriActionString)
    {
        T returnValue =
            default(T);
        try
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(uri);                    
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                HttpResponseMessage response = await client.GetAsync(uriActionString);
                response.EnsureSuccessStatusCode();

                returnValue = JsonConvert.DeserializeObject<T>(((HttpResponseMessage)response).Content.ReadAsStringAsync().Result);
            }
            return returnValue;
        }
        catch (Exception e)
        {
            throw (e);
        }
    }

returnValue尝试使用响应中的值填充我的模型。但是,当响应仅包含“未找到值”时,它会中断(显然)。我的问题是,我应该在这个try-catch中放置一个try-catch来处理这种行为吗?问题在于向用户显示整个异常,而不仅仅是“未找到值”。建议?我的模特是:

    public class BuildingReportModel
{
    public string message1 { get; set; }
    public Log[] Logs { get; set; }        
}

public class Log
{
    public string ProdLoggerIdx { get; set; }
    public string OfficeID { get; set; }     
    public string Agent { get; set; }
}

3 个答案:

答案 0 :(得分:3)

最好的处理方法是在解析之前检查响应:

var responseString = await ((HttpResponseMessage)response).Content.ReadAsStringAsync();
if(response.ToLower().Contains("no values found")) {
    //do something here like returning an empty model
}
else
{
    returnValue = JsonConvert.DeserializeObject<T>(responseString);
}

答案 1 :(得分:0)

catch块中,记录或以其他方式捕获异常,但如果显示此方法的返回值,则不要throw(来自您发布的内容似乎是)。然后给你的模型写一条友好的消息(我假设这是string message1属性的用途?如果没有,你可以为此目的添加一个属性)。这样,您的用户就会看到所写的内容,这种内容比异常的细节更容易被理解。

就另一个尝试捕捉 - 你可以,但是没有必要JsonConvert.DeserializeObject引发的任何异常最终都属于Exception类型,并且会被catch捕获。如果你想捕获一个特定的异常类型,在你的异常捕获块之前添加另一个catch语句 ,并以相同的方式处理它。

关于如何重新投掷的文章和意见(这是你当前的代码所做的)到处都是 - 做一些研究并找到适合你情况的最佳模式。

此外,@ Yaser提供的答案也是一个好主意 - 如果你可以首先防止例外,其余的都没有实际意义。

以下是我发布的代码示例,我稍后对其进行了修改和评论,这可能有助于澄清(有改进的余地,但这超出了您的问题范围):

  public async Task<T> GetWSObject<T>(string uriActionString)
    {
        var returnValue = default(T);
        try
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(uri);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/json"));
                var response = await client.GetAsync(uriActionString);
                response.EnsureSuccessStatusCode();

                // this does not need a try catch, 
                // because whatever exception is thrown here 
                // will still be caught
                returnValue = JsonConvert.DeserializeObject<T>(
                    response.Content.ReadAsStringAsync().Result);
            }

        }
        catch (Exception e)
        {
            // log or otherwise capture the exception details
            // if you don't need to log/capture the e variable
            returnValue.message1 = "A user-friendly description of the problem";
        }
        //catch // could also do it this way
        //{
        //    // if you don't need to log/capture the exception,
        //    // then don't bother with the overload
        //    returnValue.message1 = "A user-friendly description of the problem";
        //}

        return returnValue;
    }

答案 2 :(得分:0)

不确定这是否是解决此问题的最佳方法,但它正在发挥作用:

catch (Exception e)
        {                
            if (e.Message.ToString().Contains("No Logs"))
            {
                Exception e2 = (Exception)Activator.CreateInstance(e.GetType(), "No Logs Found ...", e);
                throw e2;                    
            }
            throw (e);
        }

我只是验证例外是否包含&#34;没有记录&#34;如果为true,则创建一个新的异常并抛出它。似乎工作,但这样做是否有任何缺点?有什么想法吗?