2

セキュリティで保護されたドメインとセキュリティで保護されていないドメインのリスト(両方ともhttp://https://の両方)をアレイ内で実行しており、ステータスコードを返すことを望んでいます。これはASP.Net Core 1.0ではどのように可能ですか?ASP.NetコアでHttpStatusコードを取得する方法は?

これまでのところ、私が持っている

foreach(var item in _context.URLs.ToList()) 
{ 
    // Do something here with item.Domain to check for status 
    // For example, if item.Domain was https://example.com.. 
} 
私はこのアプローチに定期的なASP.Net構文でそれを試してみました

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(item.Domain); 
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

問題があり、GetResponseはASP.Netコアでは動作しません。

返される変数がステータスになるように誰でも効果的な解決策を教えてくれますか?

例:200500404 ...

EDIT - ここでは、私の完全なコントローラとその解決策です:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.AspNetCore.Mvc; 
using MyApp.Models; 
using System.Threading.Tasks; 
using System.Net; 
using System.Net.Http; 
namespace MyApp.Controllers.Api 
{ 
    public class URLsController : Controller 
    { 
     private MyAppDBContext _context; 

     public class newLink 
     { 
      public string Domain { get; set; } 
      public HttpStatusCode Status { get; set; } 
     } 

     public async Task<HttpStatusCode> GetStatusCodes(string url) 
     { 
      var client = new HttpClient(); 
      var response = await client.GetAsync(url); 

      return response.StatusCode; 
     } 

     public URLsController(MyAppDBContext context) 
     { 
      _context = context; 
     } 

     [HttpPost("api/URLs")] 
     public async Task<IActionResult> Post(string url) 
     { 
      if (url != "") 
      { 
       // I pass a URL in through this API and add it to _context.URLs.. 
       // I execute a status code check on the URLs after this if statement 
      } 

      List<newLink> list = new List<newLink>(); 

      foreach (var item in _context.URLs.ToList()) 
      { 
       newLink t = new newLink(); 

       t.Domain = item.Domain; 
       t.Status = await GetStatusCodes(item.Domain); 

       list.Add(t); 
      } 

      return Ok(list); 
     } 
    } 
} 

これは戻って、この形式の配列を返します。

[{"ドメイン": "https://example1.com/"、 "ステータス":200}、

{ "ドメイン": "https://example2.com/"、 "ステータス":200}、

{ "ドメイン": "https://example3.com/"、 "ステータス":200}]

+0

コントローラメソッドのコードを追加してください。 –

+0

URLのドメインが解決できない場合、またはアプリケーションがネットワークにアクセスできない場合はどうなりますか?この場合、どのようなステータスコードが必要ですか? –

+1

「うまくいかない」とはどういう意味ですか?このメソッドは[そこにある](http://stackoverflow.com/questions/41811672/how-to-acquire-httpstatus-codes-in-asp-net-core)、応答を得る他の方法はありません。これで期待通りの結果が得られない場合は、実際の問題点を投稿する必要があります。例外はありましたか? [StatusCode](https://github.com/dotnet/corefx/blob/master/src/System.Net.Requests/src/System/Net/HttpWebResponse.cs#L239)が予期しない結果を返しましたか?正しい* URLを使用していますか? –

答えて

8

あなたはようHttpClient使用することができますこれを使用する方が簡単です(通常はHttpWebRequestと同じように成功しないステータスコードに対してWebExceptionsを捕まえてから、例外からHTTPステータスコードを抽出する必要はありません)。

urlのリストに対応するステータスコードのリストが返されると、ヘルパーメソッドを書くことができます。これはあなたのコードを少しデカップリングします。責任の原則に違反しないでください。メソッドはで、ではなく、1つ以上の特定のことを行う必要があります(あなたの例では、DB呼び出しとHTTP呼び出しを1つの方法に混在させてしまいました。

public async Task<IList<HttpStatusCode>> GetStatusCodes(IList<string> urls) 
{ 
    var client = new HttpClient(); 
    var result = new List<HttpStatusCode>(); 
    foreach (var url in urls) 
    { 
     var response = await client.GetAsync(url); 
     result.Add(response.StatusCode); 
    } 

    return result; 
} 

備考1:お電話しようとしているURLがDNS解決できないか、呼び出し元のアプリケーションがターゲットポート上の指定されたアドレスへのネットワークアクセスを持っていない場合は、明白ための任意のステータスコードを取得することはありません理由。素晴らしい例外があります。このケースを扱うことを考えてください。この場合、結果のコレクションで返すものを決定するのはあなた次第です。

備考2:HTTPステータスコードを特定するためだけにGETリクエストを作成することは、すでにワイヤを介して転送してきたレスポンスボディを捨ててしまうので無駄かもしれません。リモートリソースがHEAD要求に応答する場合は、サーバーが有効かどうかを判断するより効率的な方法かもしれません。しかし、あなたが呼んでいるWebエンドポイントの詳細に依存するので、これを慎重に検討してください。

備考3このメソッドがasyncであることは間違いなく気付いています。あなたが.NET Coreで開発しようとするなら、それに慣れるほうがよいでしょう。

var urls = _context.URLs.ToList(); 
IList<HttpStatusCode> statusCodes = GetStatusCodes(urls).GetAwaiter().GetResult(); 

しかし、これは非常に悪い習慣です。これは非常に悪い習慣です。より慣用的な作業方法は、フレームワーク自体が提供する主な呼び出しメソッドに到達するまで、また非同期でも可能な限り、すべてのメソッドをチェーン全体で非同期にすることです。たとえば、Web APIアクション内でこれを呼び出す場合は、単純にasyncにすることができます。

[HttpGet] 
[Route("api/foos")] 
public async Task<IActionResult> Get() 
{ 
    var urls = _context.URLs.ToList(); 
    IList<HttpStatusCode> statusCodes = await GetStatusCodes(urls); 
    return this.Ok(statusCodes); 
} 
+0

これは素晴らしいことですが、何らかの理由でコードを実装しようとするたびにエラーが発生しました。私は完全なコントローラをあなたに見せてもらった。うまくいけば、エラーを発生させることなくあなたのメソッドをどこに置くことができるのかを助けてくれることを願って。 – NoReceipt4Panda

+0

より正確には、私の主なAPIメソッドの前に 'async'メソッドを追加すると、' async'エラーが出ます。 'POST'メソッドですべてをやろうとすると、addと' async'にエラーがあります。 – NoReceipt4Panda

+0

自分のコードで自分のソリューションを試してみるときに私のフルコードを見たいと思ったら、私にはどんなエラーが表示されるのか教えてください。 – NoReceipt4Panda

関連する問題