2

Ich führe eine Liste der sicheren und ungesicherten Domänen (beide http:// und https://) in einem Array durch und möchte ihre Statuscodes zurückgeben. Wie ist das in ASP.Net Core 1.0 möglich?Wie HttpStatus Codes in ASP.Net Core erwerben?

so weit, ich habe

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.. 
} 

Ich versuchte es mit regelmäßiger ASP.Net Syntax mit diesem Ansatz:

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

Das Problem ist, GetResponse funktioniert nicht in ASP.Net Kern

Kann mir jemand mit einer effektiven Lösung helfen, so dass die zurückgegebene Variable den Status hätte?

ex: 200, 500, 404 ..

EDIT - Hier ist meine volle Steuerung und Lösung:

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

Dies gibt einen Array zurück in diesem Format:

[{"Domain": "https://example1.com/", "Status": 200},

{ "Domain": "https://example2.com/", "Status": 200},

{ "Domain": "https://example3.com/", "Status": 200}]

+0

Bitte Code für die Controller-Methode hinzufügen. –

+0

Was ist, wenn die Domäne von der URL nicht auflösbar ist oder Ihre Anwendung keinen Netzwerkzugriff darauf hat? Welchen Statuscode erwarten Sie in diesem Fall? –

+1

Was meinst du mit "funktioniert nicht"? Die Methode [gibt es] (http://stackoverflow.com/questions/41811672/how-to-acquire-httpstatus-codes-in-asp-net-core) und es gibt keine andere Möglichkeit, eine Antwort zu erhalten. Wenn dies nicht das ergibt, was Sie erwartet haben, müssen Sie das eigentliche Problem posten. Hast du eine Ausnahme bekommen? Hat [StatusCode] (https://github.com/dotnet/corefx/blob/master/src/System.Net.Requests/src/System/Net/HttpWebResponse.cs#L239) etwas unerwartetes zurückgegeben? Sind Sie sicher, dass Sie eine * korrekte * URL verwendet haben? –

Antwort

8

Sie nutzen könnten HttpClient als Es ist einfacher, mit zu arbeiten (Sie müssen WebExceptions nicht für die Statuscodes ohne Erfolg abfangen, wie Sie es mit der Ebene HttpWebRequest tun müssten, und dann den HTTP-Statuscode aus der Ausnahme extrahieren).

Sie könnten eine Hilfsmethode schreiben, die bei einer Liste von URLs eine Liste der entsprechenden Statuscodes zurückgibt. Dadurch wird Ihr Code ein wenig entkoppelter. Verstoße nicht gegen den Grundsatz der alleinigen Verantwortung. Eine Methode sollte nicht tun mehr als 1 spezifische Sache (in Ihrem Beispiel mixten Sie einige DB-Aufrufe und HTTP-Aufrufe in eine einzige Methode, die schlechte Praxis ist).

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

Bemerkung 1: Wenn die URL, die Sie nicht DNS zu nennen versuchen, ist auflösbar oder Ihre Berufung Anwendung, die Sie für selbstverständlich jeden Statuscode erhalten werden nicht keinen Netzwerkzugriff auf die angegebene Adresse auf dem Zielport hat Gründe dafür. Sie werden eine nette Ausnahme bekommen. Denken Sie darüber nach, diesen Fall zu bearbeiten. Es liegt an Ihnen, in diesem Fall zu entscheiden, was Sie in der resultierenden Sammlung zurückgeben möchten.

Anmerkung 2: Wenn Sie eine GET-Anfrage nur zur Bestimmung des HTTP-Statuscodes stellen, kann dies eine Verschwendung sein, da Sie den Antworttext wegwerfen, den Sie bereits über die Leitung transportiert haben. Wenn die Remote-Ressource auf HEAD-Anforderungen antwortet, ist dies möglicherweise eine effizientere Methode, um festzustellen, ob der Server aktiv ist. Bedenken Sie dies jedoch mit Vorsicht, da dies von den Besonderheiten des Webendpunkts abhängt, den Sie aufrufen.

Bemerkung 3: Sie haben bestimmt bemerkt, dass diese Methode async ist. Nun, wenn Sie beabsichtigen, unter .NET Core zu entwickeln, sollten Sie sich besser daran gewöhnen.Natürlich könnten Sie verletzen die eingebaute in asynchronen Mustern, die den Rahmen Sie bietet durch den aufrufenden Thread blockiert:

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

Aber das ist eine extrem schlechte Praxis. Eine idiomatische Arbeitsweise besteht darin, alle Ihre Methoden über die gesamte Kette asynchron zu machen, bis Sie die Hauptaufrufmethode erreichen, die normalerweise vom Framework selbst bereitgestellt wird und die auch asynchron sein kann. Wenn Sie dies beispielsweise in einer Web-API-Aktion aufrufen, können Sie es einfach async machen:

+0

Das ist fantastisch, aber aus irgendeinem Grund, auf die ich versucht habe, Ihren Code zu implementieren, habe ich Fehler erzeugt. Ich habe meinen vollen Controller für Sie mit einbezogen .. Hoffentlich können Sie mir dabei helfen, wo ich Ihre Methoden platzieren kann, ohne irgendwelche Fehler zu erzeugen. – NoReceipt4Panda

+0

Um genauer zu sein, wenn ich eine 'async' Methode vor meiner Haupt API Methode hinzufüge, gibt es mir einen' async' Fehler. Wenn ich versuche, alles über meine 'POST'-Methode zu machen, gibt es einen Fehler mit add und' async'. – NoReceipt4Panda

+0

Lassen Sie mich wissen, wenn Sie meinen vollständigen Code sehen möchten, wenn Sie Ihre Lösung mit meinem Code ausprobieren und welche Fehler ich sehe. – NoReceipt4Panda