如何在控制器中调用web api并返回视图MVC4



我有一个使用MVC4的项目,我想问如何从webapi中获取数据并返回视图。

型号

public class Name
{
    public Int32 NameId { get; set; }
    public String FirstName{ get; set; }
    public String LastName{ get; set; }
    public String CreatedBy { get; set; }
}
public class IListMyProject
{
    public List<Name> Names { get; set; }
}

我可以使用这个代码列出我的Index.cshtml中的所有内容

public ActionResult Index()
    {
        string securityToken = repo.GetTokens();
        if (securityToken != null)
        {
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "webapiurl/api/Name/Get?$orderby=LastName&$top=10");
            string authHeader = System.Net.HttpRequestHeader.Authorization.ToString();
            httpRequestMessage.Headers.Add(authHeader, string.Format("JWT {0}", securityToken));
            var response = client.SendAsync(httpRequestMessage)
                .ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode())
                .Result;
            if (response.IsSuccessStatusCode)
            {
                model.Names = response.Content.ReadAsAsync<IList<Name>>().Result.ToList();
            }
        }
        return View("Index", model);
    }

我可以返回我的视图。现在我有了另一个名为Details.cshtml的视图,代码是:

 public ActionResult Details(string id)
    {
        string securityToken = repo.GetTokens();
        if (securityToken != null)
        {
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "webapiurl/api/Name/GetById/"+id+"");
            string authHeader = System.Net.HttpRequestHeader.Authorization.ToString();
            httpRequestMessage.Headers.Add(authHeader, string.Format("JWT {0}", securityToken));
            var response = client.SendAsync(httpRequestMessage)
                .ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode())
                .Result;
            if (response.IsSuccessStatusCode)
            {
                model.Names = response.Content.ReadAsAsync<IList<Name>>().Result.ToList();
            }
        }
        return View(model);
    }

对于这个细节,我的Json看起来是这样的:

 application/json, text/json
 {
  "NameId": 1,
  "FirstName": "This is First Name",
  "LastName": "This is Last Name",
  "CreatedBy": "This is Created By"
 }

当我运行它时,我得到这个错误:

 Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IList`1[Models.Name]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
 To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
 Path 'NameId', line 1, position 10.

如何解决这个问题,我是webapi的新手。我想知道为什么如果我列出所有(对于索引,我使用api/get),它是有效的,但当我想详细显示它时,它不起作用。

感谢的帮助

问候

编辑

当我在中调试时

 model.Names = response.Content.ReadAsAsync<IList<Name>>().Result.ToList();

它说Null,当我试图得到响应时有什么问题吗?

问题在于:

{
  "NameId": 1,
  "FirstName": "This is First Name",
  "LastName": "This is Last Name",
  "CreatedBy": "This is Created By"
}

无法反序列化为IList。上面的JSON只是一个名称,而不是名称的集合。因此Json.NET反序列化将失败。

请确保您的Web API控制器返回IList,或者更改MVC代码以将内容读取为单个Name。JSON中的名称集合看起来是这样的:

[{
  "NameId": 1,
  "FirstName": "This is First Name",
  "LastName": "This is Last Name",
  "CreatedBy": "This is Created By"
},
{
  "NameId": 2,
  "FirstName": "This is First Name",
  "LastName": "This is Last Name",
  "CreatedBy": "This is Created By"
}]

Web API返回的是名称类型的单个对象,而不是的集合。我看不出您在哪里定义模型。我添加了类型名称的定义。试试这个。

public ActionResult Details(string id)
{
    string securityToken = repo.GetTokens();
    Name model;
    if (securityToken != null)
    {
        HttpClient client = new HttpClient();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "webapiurl/api/Name/GetById/"+id+"");
        string authHeader = System.Net.HttpRequestHeader.Authorization.ToString();
        httpRequestMessage.Headers.Add(authHeader, string.Format("JWT {0}", securityToken));
        var response = client.SendAsync(httpRequestMessage)
            .ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode())
            .Result;
        if (response.IsSuccessStatusCode)
        {
            model = response.Content.ReadAsAsync<Name>();
        }
    }
    return  View(model);
}

问题似乎是,当您将结果读取为IList<Name>时,JSON只返回1条记录。将其更改为简单的Name应该可以解决问题。

然而,您的问题是:"如何在控制器中调用web api并返回视图MVC4"

我建议你看看http://restsharp.org/您可以将代码简化为:

public ActionResult Details(string id)
{
    string securityToken = repo.GetTokens();
    Name model;
    if (securityToken != null)
    {
        var client = new RestClient("");
        var request = new RestRequest("webapiurl/api/Name/GetById/"+id, HttpMethod.Get);
        string authHeader = System.Net.HttpRequestHeader.Authorization.ToString();
        request.AddHeader(authHeader, string.Format("JWT {0}", securityToken));
        var model = client.Execute<Name>(request);
    }
    return  View(model);
}

最新更新