如何获取ASP.Net Core 中的HttpStatus 代码?
How to acquire HttpStatus Codes in ASP.Net Core?
我正在 运行 浏览数组中的安全域和不安全域(http://
和 https://
)的列表,并希望 return 它们的状态代码.这在 ASP.Net Core 1.0 中怎么可能?
到目前为止,我有
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 Core
中不起作用
任何人都可以帮我找到一个有效的解决方案,以便变量 returned 成为状态吗?
例如:200
、500
、404
..
编辑 - 这是我的完整控制器和解决方案:
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);
}
}
}
此 returns 数组以这种格式返回:
[{"Domain":"https://example1.com/","Status":200},
{"Domain":"https://example2.com/","Status":200},
{"Domain":"https://example3.com/","Status":200}]
您可以使用 HttpClient
,因为它更易于使用(您不需要像处理普通 HttpWebRequest
那样捕获非成功状态代码的 WebException 和然后从异常中提取 HTTP 状态代码)。
您可以编写一个辅助方法,给定 url 列表将 return 相应状态代码的列表。这将使您的代码更加解耦。不要违反单一职责原则。一个方法应该不做不止一件特定的事情(在你的例子中,你将一些数据库调用和 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 解析,或者您的调用应用程序无法访问目标端口上指定地址的网络,您将不会获得任何状态代码出于显而易见的原因。你会得到一个很好的例外。考虑处理这个案例。在这种情况下,由您决定要在结果集合中 return 什么。
备注 2:仅仅为了确定 HTTP 状态代码而发出 GET 请求可能是一种浪费,因为您正在丢弃已经通过网络传输的响应主体。如果远程资源响应 HEAD 请求,这可能是确定服务器是否活动的更有效方法。但请谨慎考虑,因为它取决于您调用的 Web 端点的具体情况。
备注3:你肯定注意到这个方法是async
。好吧,如果你打算在 .NET Core 下开发,你最好习惯它。您当然可以通过阻止调用线程来违反框架为您提供的 built-in 异步模式:
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);
}
我正在 运行 浏览数组中的安全域和不安全域(http://
和 https://
)的列表,并希望 return 它们的状态代码.这在 ASP.Net Core 1.0 中怎么可能?
到目前为止,我有
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 Core
任何人都可以帮我找到一个有效的解决方案,以便变量 returned 成为状态吗?
例如:200
、500
、404
..
编辑 - 这是我的完整控制器和解决方案:
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);
}
}
}
此 returns 数组以这种格式返回:
[{"Domain":"https://example1.com/","Status":200},
{"Domain":"https://example2.com/","Status":200},
{"Domain":"https://example3.com/","Status":200}]
您可以使用 HttpClient
,因为它更易于使用(您不需要像处理普通 HttpWebRequest
那样捕获非成功状态代码的 WebException 和然后从异常中提取 HTTP 状态代码)。
您可以编写一个辅助方法,给定 url 列表将 return 相应状态代码的列表。这将使您的代码更加解耦。不要违反单一职责原则。一个方法应该不做不止一件特定的事情(在你的例子中,你将一些数据库调用和 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 解析,或者您的调用应用程序无法访问目标端口上指定地址的网络,您将不会获得任何状态代码出于显而易见的原因。你会得到一个很好的例外。考虑处理这个案例。在这种情况下,由您决定要在结果集合中 return 什么。
备注 2:仅仅为了确定 HTTP 状态代码而发出 GET 请求可能是一种浪费,因为您正在丢弃已经通过网络传输的响应主体。如果远程资源响应 HEAD 请求,这可能是确定服务器是否活动的更有效方法。但请谨慎考虑,因为它取决于您调用的 Web 端点的具体情况。
备注3:你肯定注意到这个方法是async
。好吧,如果你打算在 .NET Core 下开发,你最好习惯它。您当然可以通过阻止调用线程来违反框架为您提供的 built-in 异步模式:
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);
}