Web API客户端如何从响应中读取复杂类型?

时间:2018-05-13 13:31:15

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

我创建了一个POST Action,它应该返回一个Complex类型,如下所示,作为HTTPContent的一部分:

    [HttpPost]
    [Route("users/verifyLoginCredentials")]
    public IHttpActionResult VerifyLoginCredentials([FromBody]Dictionary<string,string> loginCredentials) // Purely here for testing purouses
    {
        Models.User user = new Models.User();
        string username = (loginCredentials.ContainsKey("userLogin"))? loginCredentials["userLogin"]: "";
        string password = (loginCredentials.ContainsKey("password"))? loginCredentials["password"] : "";

        var verificationResult = Models.User.VerifyLoginCredentials(username, password, out user);
        HttpContent responseContent = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(user));

        if (verificationResult)
        {   
            return Ok(responseContent);
        }

        return BadRequest("Login Failed");
    }

然后在我的客户端应用程序中,我想读取已经序列化为Json对象的Complex类型,因此显而易见的是对它进行反序列化,但它在哪里(用户对象)?

    public static async Task<bool> VerifyCredentials(string userLogin, string password)
    {
        var value = new Dictionary<string, string>
        {
           { "userLogin", userLogin },
           { "password", password }
        };

        var test = Newtonsoft.Json.JsonConvert.SerializeObject(value);
        var content = new StringContent(test, Encoding.UTF8, "application/json");

        var result = await WebApiHelper.Client.PostAsync("users/verifyLoginCredentials", content);
        string resultContent = await result.Content.ReadAsStringAsync();

        var user = (User)Newtonsoft.Json.JsonConvert.DeserializeObject(resultContent);

        if (result.IsSuccessStatusCode)
        {
            return true;
        }

        return false;
    }

1 个答案:

答案 0 :(得分:3)

在客户端

而不是分两步完成:

var result = await WebApiHelper.Client.PostAsync("users/verifyLoginCredentials", content);
/*1: read as string*/string resultContent = await result.Content.ReadAsStringAsync();

/*2: deserialize*/ var user = (User)JsonConvert.DeserializeObject(resultContent);

您可以一步完成:

var result = await WebApiHelper.Client.PostAsync("users/verifyLoginCredentials", content);
/*1: read as User*/User resultContent = await result.Content.ReadAsAsync<User>();

但是:

if (result.IsSuccessStatusCode)
{
    return true;
}

在尝试反序列化之前必须检查,否则您将尝试反序列化&#34;登录失败&#34;作为用户对象 - 当然不是有效的。所以:

public static async Task<bool> VerifyCredentials(string userLogin, string password)
{
    var value = new Dictionary<string, string>
    {
       { "userLogin", userLogin },
       { "password", password }
    };

    var test = Newtonsoft.Json.JsonConvert.SerializeObject(value);
    var content = new StringContent(test, Encoding.UTF8, "application/json");

    var result = await WebApiHelper.Client.PostAsync("users/verifyLoginCredentials", content);

    if (result.IsSuccessStatusCode)
    {
        return true;
    }

    User resultContent = await result.Content.ReadAsAsync<User>();

    return false;
}

我不确定你是否通过反序列化赢得了任何东西

在服务器端

这段代码:

var verificationResult = Models.User.VerifyLoginCredentials(username, password, out user);
HttpContent responseContent = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(user));

if (verificationResult)
{   
    return Ok(responseContent);
}

过于复杂。 Web API已默认JSON序列化模型,您不必完成所有这些操作。代替:

var verificationResult = Models.User.VerifyLoginCredentials(username, password, out user);

if (verificationResult)
{   
    return Ok(user);
}

此外,您应该使用正确的数据传输对象(DTO),而不是接收您无法让框架验证的字典,但这是另一个问题。