2013-02-09 10 views
6

Ho un progetto che utilizza MVC4, voglio chiedere come ottenere dati da webapi e tornare alla visualizzazione.come chiamare web api nel controller e tornare in visione MVC4

Modello

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

posso elencare tutto nella mia Index.cshtml utilizzando questo codice

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

posso restituire il mio punto di vista. e ora ho un altro vista chiamata Details.cshtml con questo codice:

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

per questo dettaglio, il mio JSON assomiglia a questo:

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

quando l'eseguo, ottengo questo errore:

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. 

Come posso risolvere questo problema, im nuovo a WebAPI. Mi chiedo perché faccio se li elenco tutti (per indice, io uso API/get) funziona, ma quando voglio mostrarlo in dettaglio, non funziona.

grazie per aiuto

saluti

EDIT

quando il debug in

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

dice la sua Null, c'è qualcosa che non va quando cerco di ottenere la risposta?

risposta

3

Il problema è che:

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

non può essere deserializzato come IList. Il JSON che hai sopra è solo un nome, non una raccolta di nomi. Quindi la deserializzazione di Json.NET fallirà.

Assicurarsi che il controller API Web restituisca un IList o modificare il codice MVC per leggere il contenuto come un singolo Nome. Una collezione di nomi in JSON sarebbe simile a questo, invece:

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

i penso che sia il mio problema ma non faccio il webapi, lo uso solo nel mio mvc. come elencare quel json? grazie bro –

+1

bene leggere il contenuto come Nome, non come IList se non si controlla il servizio Web ... –

+0

io uso var NamesId = response.Consent.ReadAsAsync () .Result; e quando eseguo il debug su NamesId, posso ottenere il risultato. ma come posso tornare nella vista Details.cshtml? –

1

L'API Web restituisce un singolo oggetto di tipo Nome, non una collezione di Nome. Non vedo dove si definisce il modello . Ho aggiunto una definizione di tipo Nome. Prova questo.

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

ciao, provo questo e il risultato è "il valore non può essere nullo". –

+0

Siamo spiacenti, non ho capito la domanda originale. Dai un'occhiata alla mia risposta aggiornata per vedere se questo aiuta. –

1

Il problema sembra essere il fatto che il vostro JSON restituisce solo 1 registrare mentre si sta leggendo il risultato come IList<Name>. Cambiarlo semplicemente in Name dovrebbe risolvere il problema.

Tuttavia si domanda è: "come chiamare API Web nel controller e tornare alla vista MVC4"

vi consiglio di guardare http://restsharp.org/ È possibile semplificare il codice per:

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