这是这篇文章的后续内容:MVC 4 Web API 的新内容 对 HTTPRequestMessage 感到困惑
以下是我想要做的总结:有一个网站,我想通过 MVC 4 Web API 与之交互。在该站点,用户可以使用用户名和密码登录,然后转到一个名为“原始数据”的链接以从该站点查询数据。
在“原始数据”页面上,有一个用于“设备”的下拉列表、一个用于“从”日期的文本框和一个用于“到”日期的文本框。给定这三个参数,用户可以单击“获取数据”按钮,并将数据表返回到页面。我要做的是在 Azure 上托管一项服务,该服务将以编程方式将这三个参数的值提供给站点,并将 CSV 文件从站点返回到 Azure 存储。
托管该站点的公司已提供文档以通过编程方式与该站点交互以检索这些原始数据。该文档描述了如何针对他们的云服务提出请求。必须使用自定义 HTTP 身份验证方案对请求进行身份验证。以下是身份验证方案的工作原理:
- 根据用户密码计算 MD5 哈希。
- 将请求行附加到第一步中的值的末尾。
- 在第二步中将日期标题附加到值的末尾。
- 将消息正文(如果有)附加到步骤 3 中的值的末尾。
- 计算来自步骤 4 的结果值的 MD5 散列。
- 使用“:”字符作为分隔符将步骤 5 中的值附加到用户电子邮件。
- 根据步骤 6 中的值计算 Base64。
我要列出的代码是在 Visual Studio 2012、C#、.NET Framework 4.5 中完成的。这篇文章中的所有代码都在我的“FileDownloadController.cs”控制器类中。'getMd5Hash' 函数接受一个字符串,并返回一个 MD5 哈希:
//Create MD5 Hash: Hash an input string and return the hash as a 32 character hexadecimal string.
static string getMd5Hash(string input)
{
// Create a new instance of the MD5CryptoServiceProvider object.
MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
此函数接受一个字符串,并返回 BASE64:
//Convert to Base64
static string EncodeTo64(string input)
{
byte[] str1Byte = System.Text.Encoding.ASCII.GetBytes(input);
String plaintext = Convert.ToBase64String(str1Byte);
return plaintext;
}
下一个函数创建一个 HTTPClient,发出一个 HTTPRequestMessage,并返回授权。注意:以下是从“原始数据”页面返回数据时从 Fiddler 返回的 URI:GET /rawdata/exportRawDataFromAPI/?devid=3188&fromDate=01-24-2013&toDate=01-25-2013 HTTP/1.1
让我先来看看这个函数发生了什么:
- “WebSiteAuthorization”函数需要一个“deviceID”、一个“fromDate”、一个“toDate”和一个“password”。
- 接下来,我声明了三个变量。我不清楚我是否需要“消息正文”,但我有这个设置的通用版本。其他两个变量保存 URI 的开头和结尾。
- 我有一个名为“dateHeader”的变量,它包含数据头。
- 接下来,我尝试创建一个 HTTPClient,为其分配带有参数的 URI,然后将“application/json”分配为媒体类型。我仍然不太清楚应该如何构建它。
在下一步中,根据 API 文档的要求创建授权,然后返回结果。
public static string WebSiteAuthorization(Int32 deviceid, string fromDate, string toDate, string email, string password) { var messagebody = "messagebody"; // TODO: ??????????? Message body var uriAddress = "GET/rawdata/exportRawDataFromAPI/?devid="; var uriAddressSuffix = "HTTP/1.1"; //create a date header DateTime dateHeader = DateTime.Today; dateHeader.ToUniversalTime(); //create the HttpClient, and its BaseAddress HttpClient ServiceHttpClient = new HttpClient(); ServiceHttpClient.BaseAddress = new Uri(uriAddress + deviceid.ToString() + " fromDate" + fromDate.ToString() + " toDate" + toDate.ToString() + uriAddressSuffix); ServiceHttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //create the authorization string string authorizationString = getMd5Hash(password); authorizationString = authorizationString + ServiceHttpClient + dateHeader + messagebody; authorizationString = email + getMd5Hash(authorizationString); authorizationString = EncodeTo64(authorizationString); return authorizationString; }
我还没有在 Azure 上测试过。我还没有完成获取文件的代码。我知道我需要做的一件事是确定创建 HttpRequestMessage 并使用 HttpClient 发送它的正确方法。在我阅读的文档和我查看的示例中,以下代码片段似乎是解决此问题的可能方法:
Var serverAddress = http://my.website.com/;
//Create the http client, and give it the ‘serverAddress’:
Using(var httpClient = new HttpClient()
{BaseAddress = new Uri(serverAddress)))
Var requestMessage = new HttpRequestMessage();
Var objectcontent = requestMessage.CreateContent(base64Message, MediaTypeHeaderValue.Parse (“application/json”)
或者 - -
var formatters = new MediaTypeFormatter[] { new jsonMediaTypeFormatter() };
HttpRequestMessage<string> request = new HttpRequestMessage<string>
("something", HttpMethod.Post, new Uri("http://my.website.com/"), formatters);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var httpClient = new HttpClient();
var response = httpClient.SendAsync(request);
或者 - - -
Client = new HttpClient();
var request = new HttpRequestMessage
{
RequestUri = "http://my.website.com/",
Method = HttpMethod.Post,
Content = new StringContent("ur message")
};
我不确定这部分代码采用哪种方法。
谢谢您的帮助。