2016-12-15 4 views
0

私のコードはいくつかの残りのAPI(GETメソッド)を処理します。このGETメソッド、このような応答を返す:C#は、応答を処理するtry catch内でtry catchを使用する必要がありますか?それは悪い考えですか?

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

とクエリが何も見つからない場合は、返されます。私は値を取得するために、このAPI呼び出しを使用してい

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

コードとレポートを表示する:

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

エラーを再送信するだけです。あなたも外のすべての一緒にキャッチを取り除くことができます – Steve

+0

@スティーブ私はそれについて考えたが、悪い入力、SQLのような他の本当のエラーをキャッチするのはどうですか? –

+0

あなたはこの[回答](http://stackoverflow.com/a/14974163/6936343)を見てください。 –

答えて

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

.Resultは足で自分を撃つ本当に良い方法です...現在のSynchronizationContextがnullでない場合の潜在的なデッドロック – Steve

+0

申し訳ありませんが、それは@Steve – Yaser

+0

のように固定されていますが、この "応答"にはToLowerはありません。どちらのメソッドも含まれていません。 –

0

をごcatchブロックでログインするか、そうでない場合は、例外を捕捉しますが、やりますthrowこのメソッドの戻り値が表示されている場合(投稿したものが表示されているように見える場合)あなたのモデルにフレンドリーなメッセージを書いてください(私はそれがstring message1プロパティのものであると仮定していますか?もしそうでなければ、そのような目的のためにプロパティを追加する可能性があります)。そのようにすれば、ユーザはと書かれたものを見ることができます。これは、例外の詳細よりもはるかに理解しやすいものです。

もう一度試してみると、でも可能ですが、それは不要ですJsonConvert.DeserializeObjectによってスローされる例外は、最終的にはタイプExceptionとなり、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; 
    } 
+0

ここでの扱いにくい部分は、returnValue message1に直接アクセスすることができないようにLISTを渡していることです。私がcatchで何かを行うと、私の場合、どのように各問題を識別できますか? ? –

+0

@Rolando F - 私は確かに提案を提供することができますが、あなたは "私の質問は、この動作を処理するためにtry-catchをtry-catchに置くべきですか?"という質問をしました。問題は、例外がすべてユーザーに表示されているということです「値が見つからない」だけでなく、私はあなたの質問に答えていくつかの提案をしたと信じています。まだ助けが必要な場合は、より詳しく見てフィードバックを増やすことができますが、これを指摘したいと思います。 – geekzster

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

私はちょうど例外が「NOログ」を含まない場合はtrueの場合、新しい例外を作成して検証していますそれを投げなさい。仕事をしているようですが、このようなことに何か問題がありますか?何かご意見は?

関連する問題