FETCH! 只需一行代码即可从远程 Web 服务器检索数据(附带 MVC reCAPTCHA 示例)






4.92/5 (36投票s)
应用程序经常需要来自 HTTP 服务器的数据,例如 Web 服务,或抓取内容。.NET 提供了 HttpWebRequest,但执行琐碎操作需要大量代码。此类通过抽象化 HTTP 协议、流和异常,极大地简化了任务。
![]() |
源代码(GitHub 上的 RedCell.Net) |
![]() |
二进制组件(RedCell.Net.dll ) |
![]() |
编译后的帮助文档(RedCell.Net.chm ) |
引言
这是我工具箱里放了很多年的一个类,而且我仍然经常使用它。它的灵感来自 FreeBSD 的 fetch
命令,它比 curl
更直观。它针对 .NET Framework 2.0 版本进行编译,因此几乎可以在任何桌面或 Web 应用程序中使用。它唯一的依赖项是 System.dll
。
背景
有时您只想获取 HTTP 请求的结果并**使用它**。也许您想下载整个网页以抓取其内容中的某些数据,或者您正在处理一个仅返回数字、字符串、某些 XML 或某些 JSON 的 Web 服务。
Fetch
就是为这些情况而创建的。它具有
- 用**一行代码**发出简单的
GET
或POST
请求。 - 包含用于**身份验证**的凭据。
- 可配置的**重试**和**超时**。
- 可修改的**标头**。
- 以您选择的**类型**获取返回结果。
使用代码
要在代码中使用 Fetch
类,请将 Fetch.cs
添加到您的项目中,或在您的项目中引用 RedCell.Net.dll
。
简单用法(静态)
有用于简单请求的 static
Get
和 Post
方法。它们有两种类型:通用和二进制。二进制方法返回 byte[]
。以下是一些 static
用法示例:
using RedCell.Net;
string url = "http://example.com/api";
// Retrieve some binary data.
byte[] image = Fetch.Get(url);
// Retrieve a string.
string slogan = Fetch.Get<string>(url);
// Post some data and expect an int back.
var formData = new Dictionary<string,string> {
{ "firstname", "Yvan" },
{ "lastname", "Rodrigues" }
};
int age = Fetch.Post<int>(url, formData);
如果发生错误,静态方法将返回 null
。可以为 static
调用设置一些默认值。
Fetch.DefaultRetries = 5; // Number of times to retry.
Fetch.DefaultTimeout = 60000; // Time to wait for a response (ms).
Fetch.DefaultRetrySleep = 10000; // Pause between retries (ms).
实例用法
需要实例化该类才能访问其他功能,并进行更底层的选项访问。
using System.Net;
using RedCell.Net;
string url = "http://example.com/api";
// Create a fetcher.
var f = new Fetch(url);
// Set some options.
f.Retries = 1;
f.Timeout = 10;
// Include authentication credentials
f.Credential = new NetworkCredential("yvan", "happy-fun-password");
// Make the request.
// The result will be stored as byte[] in the ResponseData property.
f.Get();
// Exceptions are caught, so we have to check for success.
if(!f.Success)
{
// If the fetch failed, examine f.Response to find out why.
}
float response = f.ConvertResponse<float>();
应用示例:Recaptcha MVC
今天我想在 MVC Web 应用程序的 Web 表单中添加**新的** reCAPTCHA。NuGet 和 GitHub 上有很多库可以做到这一点,但我真的想复制粘贴一些非常简单的东西。这是使用 Fetch
的简单方法。在此示例中,我的表单使用同一个视图来显示和处理表单,例如:
@if (Request.HttpMethod == "POST")
{
<p>Thanks!</p>
}
@else
{
<form> 20 questions </form>
}
Newtonsoft.Json
),该库可通过 NuGet 获取。三个步骤
2. 在提交按钮之前添加到您的 Web 表单**视图**中
<script src="https://www.google.com/recaptcha/api.js"></script>
<div class="g-recaptcha" data-sitekey="put-your-site-token-here" ></div>
protected bool VerifyRecaptcha()
{
const string key = "your-secret-key";
const string url = "https://www.google.com/recaptcha/api/siteverify";
string recaptcha = Request.Form["g-recaptcha-response"];
string ip = Request.ServerVariables["REMOTE_HOST"];
var values = new Dictionary<string, string>
{
{ "secret", key },
{ "response", recaptcha },
{ "remoteip", ip }
};
string response = Fetch.Post<string>(url, values);
if (response == null) return false; // You may wish to do a more sophisticated handler.
var data = JObject.Parse(response);
return data.Value<bool>("success");
}
表单中的 g-recaptcha-response
字段会与私钥和 IP 地址一起 POST
到 Web 服务。我们使用 Fetch.Post
并将 string
作为类型参数,因为我们知道会收到一个 JSON 对象。然后使用 Json.NET 解析响应并检查 success
。
一种很好的方法是为您的控制器创建一个基类,例如 RecaptchaController
,其中包含这个类,然后让您的其他类继承它。
4. 最后,从您的**控制器**调用它
public ActionResult MoreInformation()
{
if (Request.HttpMethod == "POST" && VerifyRecaptcha())
SendConfirmation("Thanks, we'll be in touch);
return View();
}
关注点
Fetch
是 HttpWebRequest
和 HttpWebResponse
的简单包装器。使用这些类进行基本请求通常需要大约 20 行代码。主要原因是将数据内容读入或读出这些类需要处理 Stream
。在内部,Fetch
创建一个 MemoryStream
,复制 Web 流,然后将其转换为 byte[]
。
一个不错的特性是能够使用泛型方法来获取强类型数据。这由 ConvertResponse<T>
方法在内部执行。棘手的部分是任意类型无法强制转换为 T
(除非使用 where
约束);但是,**object** 可以强制转换为泛型类型,因此值在强制转换之前会被装箱。
历史
- 2015 年 8 月 13 日 · v1.0.0 · 原始文章
- 2015 年 8 月 20 日 · v1.0.1 · 错误修复