2014-10-16 25 views
5

Ich versuche, eine POST von einem controller zu einem anderen controller zu tun. Beide controller stammen aus verschiedenen Projekten. Ein Projekt dient dazu, die Präsentationsschicht zu simulieren (die ich hier als Testprojekt bezeichnen werde).HttpClient mehrere einfache Parameter übergeben

Vom Testprojekt versuche ich 2 einfache string Parameter an die andere Steuerung zu übergeben, die ich den Prozess nennen werde.

var values = new List<KeyValuePair<string, string>>(); 
values.Add(new KeyValuePair<string, string>("id", param.Id.Value)); 
values.Add(new KeyValuePair<string, string>("type", param.Type.Value)); 
var content = new FormUrlEncodedContent(values); 
using (var client = new HttpClient()) 
{ 
     client.BaseAddress = new Uri(url); 
     client.DefaultRequestHeaders.Clear(); 
     client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("nl-NL")); 

     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

     string token = param.token.Value; 
     client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); 

     var response = client.PostAsync("/api/Process/Product", content).Result; 

     if (response.IsSuccessStatusCode) 
     { 
      var result = response.Content.ReadAsStringAsync().Result; 
      return Request.CreateResponse(HttpStatusCode.OK, result); 
     } 

     return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "fail"); 
} 

Und in der Prozesssteuerung, ich versuche es so zu erhalten:

Aber es erreicht dieses controller nie. Ich bekomme immer einen "nicht gefundenen Statuscode".

Also wie kann ich 2 einfache Parameter mit HttpClient() übergeben?

+0

Warum nicht GetAsync verwenden? Bedeutung Ändern Sie Verb von Post zu Get. – NMK

+0

Weil ich nur 1 Parameter mit 'GET' übergeben kann. Ich habe zwar deine Lösung versucht, aber nicht funktioniert. Es kommt nicht in dem Prozess "Controller" – Quoter

Antwort

7

Verwenden Sie Get anstelle von Post für einfache Typparameter.

using (var client = new HttpClient()) 
    { 
     BaseAddress = new Uri(url); 
     client.BaseAddress = new Uri(url); 
    client.DefaultRequestHeaders.Clear(); 
    client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("nl-NL")); 

    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

    string token = param.token.Value; 
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); 

     // New code: 
     var response = await client.GetAsync(string.format("api/products/id={0}&type={1}",param.Id.Value,param.Id.Type)); 
if (response.IsSuccessStatusCode) 
    { 
     var result = response.Content.ReadAsStringAsync().Result; 
     return Request.CreateResponse(HttpStatusCode.OK, result); 
    } 

    return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "fail"); 

    } 

In der API-Seite können Sie so tun.

[HttpGet] 
public HttpResponseMessage Product(string id, string type) 
{ 
    return null; 
} 
+0

Muss ich etwas mit Route in Attribut machen? Wie sie in diesem Beitrag beschreiben: http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2 – Quoter

+0

Ja, Sie verwenden Attribut Routing oder Sie können Ihre Routing-Konfiguration aktualisieren, um diese anzupassen. – NMK

+0

Oder Sie können versuchen, wie Produkt/ID = Wert & Typ = Wert – NMK

0

Ich bin mir nicht sicher, ob ich total verliebt bin, aber ich habe in der Vergangenheit anonyme Typen und Dynamiken verwendet ... (Beachten Sie die Konfigurationsunterschiede für die Verwendung von PostAsJsonAsync(). Ich habe diese anfangs vergessen.)

client.DefaultRequestHeaders.Accept.Clear(); 
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));  
client.PostAsJsonAsync("api/User/UpdateLastLogin", new { UserId = userId, ApplicationId = applicationId }); 

Empfangs-Controller:

[HttpPost] 
    public void UpdateLastLogin([FromBody]dynamic model) 
    { 
     _userRepository.UpdateLastLogin((int)model.UserId, (int)model.ApplicationId); 
    } 

In WebApiConfig.Register():

var json = config.Formatters.JsonFormatter; 
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; 
config.Formatters.Remove(config.Formatters.XmlFormatter); 

Der andere Ansatz, den ich weitergegeben habe, besteht darin, für jeden dieser Aufrufe ein völlig neues Set von Typen mit starken Typen zu erstellen. Ich wollte nicht, da ich eine Menge von ihnen zu einem WebAPI machen musste.

+0

Erprobte Ihre Lösung auch, aber auch nicht funktioniert. Es trifft niemals den Haltepunkt im Prozess "Controller". – Quoter

+0

Debuggen Sie beide Anwendungen? – SethMW

+0

Ja.Jede andere Methode mit einem Haltepunkt innerhalb des Prozesses "Controller" wird getroffen. Nur dieses tut es nicht. Fiddler markiert die URL auch rot. Aber wenn ich es inspiziere, zeigt es nichts, das mir sagt, was das Problem sein könnte. – Quoter

0

Wenn eine Stelle erhalten, müssen Sie angeben, [FromBody] in den Parametern für die Methode

[HttpPost] 
public HttpResponseMessage Product([FromBody]string id, [FromBody]string type) 
{ 
    return null; 
} 
+0

Dies wird nicht funktionieren ... Sie können nicht mehr als ein [FromBody] -Attribut haben https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter -binding-in-aspnet-web-api – Bartosz

0

hier genannt werden, ist ein weiteres Beispiel Sie WinForms für verwenden können, WPF oder Console Apps

Kundencode

async Task<CalendarView> GetData(int month, int year, int deviceTypeID) 
     { 
      var result = new MSOCommon.CalendarView(); 
      try 
      { 
       HttpClient client = new HttpClient(); 

       var calendarRequest = new CalendarRequest() 
       { 
        Month = month, 
        Year = year, 
        DeviceTypeID = deviceTypeID, 
        UserInfo = Program.UserInfo 
       }; 

       var url = Properties.Settings.Default.ServerBaseUrl + string.Format("/api/calendar/Calendar"); 

       HttpResponseMessage response = await client.PostAsync(url, calendarRequest.AsJson()); 
       if (response.IsSuccessStatusCode) // Check the response StatusCode 
       { 
        var serSettings = new JsonSerializerSettings() 
        { 
         TypeNameHandling = TypeNameHandling.All 
        };  

        string responseBody = await response.Content.ReadAsStringAsync(); 

        result = JsonConvert.DeserializeObject<MSOCommon.CalendarView>(responseBody, serSettings); 
       } 
       else 
       { 
        logger.Error(Properties.Resources.DATACannotGetCalendar); 
       } 
      } 
      catch (Exception ex) 
      { 
       logger.Error(Properties.Resources.DATACannotGetCalendar + " " + ex.Message); 
       logger.Error(ex); 
      } 

      return result; 
     } 

-Controller serverseitigen Code

[HttpPost()] 
     public CalendarView Calendar(CalendarRequest calendarRequest) 
     { 
      logger.Info(string.Format("Get calendar for month {0} and year {1} ", calendarRequest.Month, calendarRequest.Year)); 
      // TODO Check username 
      var result = new CalendarView(); 

      using (var db = new MSOnlineEntities()) 
      { 
       result = db.Calendars.Include("CalendarDetails") 
        .Where(x => x.CMonth == calendarRequest.Month && x.CYear == calendarRequest.Year && x.CDeviceTypeID == calendarRequest.DeviceTypeID).ToList() 
        .ConvertAll(x => new CalendarView 
        { 
         ID = x.ID, 
         CMonth = x.CMonth, 
         CYear = x.CYear, 
         CDays = x.CDays, 
         CDeviceTypeID = x.CDeviceTypeID, 
         ClosedAtTime = x.ClosedAtTime, 
         ClosedByUser = x.ClosedByUser, 
         IsClosed = x.IsClosed, 
         CalendarDetails = x.CalendarDetails.ToList().ConvertAll(d => new CalendarDetailView 
         { 
          ID = d.ID, 
          CalendarID = d.CalendarID, 
          MachineID = d.MachineID, 
          MachineName = d.DATA_MACHINE.Name, 
          D1 = d.D1 ?? -1, 
          D2 = d.D2 ?? -1, 
          D3 = d.D3 ?? -1, 
          D4 = d.D4 ?? -1, 
          D5 = d.D5 ?? -1, 
          D6 = d.D6 ?? -1, 
          D7 = d.D7 ?? -1, 
          D8 = d.D8 ?? -1, 
          D9 = d.D9 ?? -1, 
          D10 = d.D10 ?? -1, 
          D11 = d.D11 ?? -1, 
          D12 = d.D12 ?? -1, 
          D13 = d.D13 ?? -1, 
          D14 = d.D14 ?? -1, 
          D15 = d.D15 ?? -1, 
          D16 = d.D16 ?? -1, 
          D17 = d.D17 ?? -1, 
          D18 = d.D18 ?? -1, 
          D19 = d.D19 ?? -1, 
          D20 = d.D20 ?? -1, 
          D21 = d.D21 ?? -1, 
          D22 = d.D22 ?? -1, 
          D23 = d.D23 ?? -1, 
          D24 = d.D24 ?? -1, 
          D25 = d.D25 ?? -1, 
          D26 = d.D26 ?? -1, 
          D27 = d.D27 ?? -1, 
          D28 = d.D28 ?? -1, 
          D29 = d.D29 ?? -1, 
          D30 = d.D30 ?? -1, 
          D31 = d.D31 ?? -1 
         }) 
        }).FirstOrDefault(); 

       return result; 
      } 
     } 
Verwandte Themen