2017-01-23 40 views
2

Я просматриваю список как безопасных, так и незащищенных доменов (как http://, так и https://) в массиве и хотел бы вернуть их коды статуса. Как это возможно в ASP.Net Core 1.0?Как получить коды HttpStatus в ASP.Net Core?

до сих пор, у меня есть

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 Ядра

Может ли кто-нибудь помочь мне с эффективным решением, чтобы возвращаемая переменная была статусом?

например: 200, 500, 404 ..

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 в качестве с ним легче работать (вам не нужно ловить 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: Выполнение запроса GET только для определения кода состояния HTTP может быть пустым, поскольку вы выбрасываете тело ответа, которое вы уже переносили по кабелю. Если удаленный ресурс отвечает на запросы HEAD, которые могут быть более эффективным способом определить, жив ли сервер. Но учтите это с осторожностью, поскольку это будет зависеть от специфики конечной точки Интернета, которую вы вызываете.

Примечание 3: Вы, несомненно, заметили, что этот метод async. Ну, если вы собираетесь разрабатывать в .NET Core, вам лучше привыкнуть к нему.Конечно, вы можете нарушить встроенный асинхронные модели, что структура обеспечивает вам блокируя вызывающую нить:

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

Но это очень плохая практика. Более идиоматический способ работы - сделать все ваши методы асинхронными по всей цепочке до тех пор, пока вы не достигнете основного метода вызова, который обычно предоставляется самой картой и который может быть асинхронным. Например, если вы вызываете это в действии веб-API, вы можете просто сделать его асинхронным:

+0

Это фантастика, но почему-то каждый раз, когда я пытался реализовать ваш код, я продолжал генерировать ошибки. Я включил свой полный контроллер, чтобы вы могли видеть. Надеюсь, вы сможете помочь мне, где я могу поместить ваши методы, не создавая никаких ошибок. – NoReceipt4Panda

+0

Чтобы быть более точным, если я добавляю метод 'async' перед моим основным методом API, он дает мне ошибку async. Если я пытаюсь сделать все через мой метод «POST», возникает ошибка с добавлением и 'async'. – NoReceipt4Panda

+0

Сообщите мне, если вы хотите увидеть мой полный код, чтобы попробовать свое решение с моим кодом и какие ошибки я вижу. – NoReceipt4Panda

 Смежные вопросы

  • Нет связанных вопросов^_^