65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (36投票s)

2015年8月13日

CPOL

3分钟阅读

viewsIcon

53059

应用程序经常需要来自 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 就是为这些情况而创建的。它具有

  • 用**一行代码**发出简单的 GETPOST 请求。
  • 包含用于**身份验证**的凭据。
  • 可配置的**重试**和**超时**。
  • 可修改的**标头**。
  • 以您选择的**类型**获取返回结果。

使用代码

要在代码中使用 Fetch 类,请将 Fetch.cs 添加到您的项目中,或在您的项目中引用 RedCell.Net.dll

简单用法(静态)

有用于简单请求的 static GetPost 方法。它们有两种类型:通用和二进制。二进制方法返回 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

Recaptcha

今天我想在 MVC Web 应用程序的 Web 表单中添加**新的** reCAPTCHA。NuGet 和 GitHub 上有很多库可以做到这一点,但我真的想复制粘贴一些非常简单的东西。这是使用 Fetch 的简单方法。在此示例中,我的表单使用同一个视图来显示和处理表单,例如:

@if (Request.HttpMethod == "POST")
{
    <p>Thanks!</p>
}
@else
{
    <form> 20 questions </form>
}
我正在使用**Json.NET** (Newtonsoft.Json),该库可通过 NuGet 获取。

三个步骤

1. 注册并获取您的**密钥**。

2. 在提交按钮之前添加到您的 Web 表单**视图**中

<script src="https://www.google.com/recaptcha/api.js"></script>
<div class="g-recaptcha" data-sitekey="put-your-site-token-here" ></div>
3. 添加到您的**控制器**
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();
}

关注点

FetchHttpWebRequestHttpWebResponse 的简单包装器。使用这些类进行基本请求通常需要大约 20 行代码。主要原因是将数据内容读入或读出这些类需要处理 Stream。在内部,Fetch 创建一个 MemoryStream,复制 Web 流,然后将其转换为 byte[]

一个不错的特性是能够使用泛型方法来获取强类型数据。这由 ConvertResponse<T> 方法在内部执行。棘手的部分是任意类型无法强制转换为 T(除非使用 where 约束);但是,**object** 可以强制转换为泛型类型,因此值在强制转换之前会被装箱。

历史

  • 2015 年 8 月 13 日 · v1.0.0 · 原始文章
  • 2015 年 8 月 20 日 · v1.0.1 · 错误修复
© . All rights reserved.