C# - 向REST服务

时间:2016-09-10 12:50:45

标签: c# rest asp.net-web-api

所以我正在为我的Web API ReST服务编写客户端用户身份验证代码。

请求和响应应该是这样的,我已经编写了这段代码来注册用户,并且工作正常。

Http请求:

POST https://localhost:44305/api/Account/Register HTTP/1.1
Host: localhost:44305
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101     Firefox/32.0
Accept: */*
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: https://localhost:44305/
Content-Length: 84
{"Email":"alice@example.com","Password":"Password1!","ConfirmPassword":"Password1!"}

Http回应:

HTTP/1.1 200 OK
Server: Microsoft-IIS/8.0
Date: Wed, 01 Oct 2014 00:57:58 GMT
Content-Length: 0

完成此任务的代码:

byte[] data = Encoding.UTF8.GetBytes("{\"Email\":\"alssice@example.com\"," + "\"Password\":\"Password1!\"," + "\"ConfirmPassword\":\"Password1!\"}");
WebRequest request = WebRequest.Create("http://localhost:8091/api/Account/Register");
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
request.ContentLength = data.Length;
using (Stream stream = request.GetRequestStream())
   {
     stream.Write(data, 0, data.Length);
   }
string responseContent = null;

using (WebResponse response = request.GetResponse())
 {
    using (Stream stream = response.GetResponseStream())
       {
         using (StreamReader sr99 = new StreamReader(stream))
           {
             responseContent = sr99.ReadToEnd();
           }
        }
 }

Console.WriteLine(responseContent);

此工作正常,用户帐户在数据库中创建,但我没有收到回复。

下一个问题是发送登录详细信息以获取不记名令牌?我怎么能这样做?
这就是请求和响应应该是什么样的

HTTP请求认证:

POST https://localhost:44305/Token HTTP/1.1
Host: localhost:44305
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101     Firefox/32.0
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://localhost:44305/
Content-Length: 68

grant_type=password&username=alice%40example.com&password=Password1!

用于认证的HTTP响应:

HTTP/1.1 200 OK
Content-Length: 669
Content-Type: application/json;charset=UTF-8
Server: Microsoft-IIS/8.0 
Date: Wed, 01 Oct 2014 01:22:36 GMT

{
 "access_token":"imSXTs2OqSrGWzsFQhIXziFCO3rF...",
 "token_type":"bearer",
 "expires_in":1209599,
 "userName":"alice@example.com",
 ".issued":"Wed, 01 Oct 2014 01:22:33 GMT",
 ".expires":"Wed, 15 Oct 2014 01:22:33 GMT"
 }

那我该如何发送令牌请求?

1 个答案:

答案 0 :(得分:3)

如果您要在应用中使用自己的http rest客户端,我建议您使用HttpClient。

使用HttpClientJson.net的解决方案:

public class TokenResponse
{
    public string access_token { get; set; }
    public string token_type { get; set; }
    public int expires_in { get; set; }
    public string userName { get; set; }
    public string issued { get; set; }
    public string expires { get; set; }
}


private async Task Login()
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri("https://localhost:44305");
        var content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("grant_type", "password"),
            new KeyValuePair<string, string>("username", "alice@example.com"),
            new KeyValuePair<string, string>("password", "password1")
        });
        var result = await client.PostAsync("/token", content);
        string resultContent = await result.Content.ReadAsStringAsync();
        var tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(resultContent);
    }
}

如果您需要使用HttpWebRequest

如果是这种情况,您的解决方案可能如下所示。

private void Login()
{
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://localhost:44305/Token");
    request.Method = "POST";
    request.AllowAutoRedirect = false;
    request.Accept = "*/*";
    request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";

    StringBuilder postData = new StringBuilder();
    postData.Append("grant_type=" + HttpUtility.UrlEncode("password") + "&");
    postData.Append("username=" + HttpUtility.UrlEncode("alice@example.com") + "&");
    postData.Append("password=" + HttpUtility.UrlEncode("password"));

    using (StreamWriter stOut = new StreamWriter(request.GetRequestStream(), Encoding.UTF8))
    {
        stOut.Write(postData);
        stOut.Close();
    }
}

更新

现在我不确定你在哪里以及如何尝试这个。如果您从控制台应用程序main方法调用此方法,请确保以下内容,这样您就不必返回到相同的异步上下文,并且应始终从异步方法本身调用此方法:

var result = await client.PostAsync("https://localhost:44305/token", content).ConfigureAwait(false);

我在github gist中更新了我的解决方案。它正在为我工​​作,因为它正试图立即发布请求。