2017-01-23 65 views
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 ..

編輯 - 這是我的全部控制及解決方法:

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

這將返回數組回到這個格式:

[{「Domain」:「https://example1.com/」,「Status」: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)是否會返回意外的內容?你確定你使用了*正確的*網址嗎? –

回答

8

您可以使用HttpClient作爲它更容易處理(您不需要爲非成功狀態代碼捕獲WebExceptions,就像您對純文本HttpWebRequest必須執行的操作,然後從異常中提取HTTP狀態代碼一樣)。

你可以編寫一個幫助器方法,給出一個url列表將返回一個相應的狀態碼列表。這會使你的代碼更加分離。不要違反單一責任原則。一個方法應該不是做超過1特定的事情(在你的例子中,你正在混合一些數據庫調用和HTTP調用到一個單一的方法這是不好的做法)。

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操作中調用此方法,則可以簡單地將其設置爲異步:

[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

相關問題