How to call web api in the controller and return to MVC4 view

I have a project using MVC4, I want to ask how to get data from webapi and return to the view.

Model

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; } } 

I can list everything in my Index.cshtml with this code

 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); } 

I can get my opinion back. and now I have another view called Details.cshtml with this code:

  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); } 

For this detail, my Json looks like this:

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

when I run it, I get this error:

  Cannot deserialize the current JSON object (eg {"name":"value"}) into type 'System.Collections.Generic.IList`1[Models.Name]' because the type requires a JSON array (eg [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (eg [1,2,3]) or change the deserialized type so that it is a normal .NET type (eg 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. 

How to fix this, I'm new to webapi. I wonder why if I list everything (for the index, I use api / get), it works, but when I want to show it in detail, it does not work.

thank for help

Hi

EDIT

when i debug

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

Null tells him, is there something wrong when I try to get an answer?

+6
source share
3 answers

The problem is that:

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

cannot be deserialized as an IList. The JSON you have is just one name, not a collection of names. Thus, Json.NET deserialization will fail.

Make sure your web API controller returns IList or modified the MVC code to read the contents as one name. The collection of names in JSON will look like this:

 [{ "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" }] 
+3
source

The web API returns a single object of type Name , not a collection of Name . I do not see where you are defining the model . I added a definition of type Name . Try it.

 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); } 
+1
source

The problem is that your JSON returns only 1 record while you read the result as IList<Name> . Changing this function simply to Name should fix the problem.

However, you are wondering: " how to call web api in the controller and return to MVC4 view "

I recommend you check out http://restsharp.org/ . You can simplify your code:

 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); } 
+1
source

All Articles