HttpClient передает несколько простых параметров

Я пытаюсь сделать POST от controller в другой controller. Оба!--3-->из разных проектов. Один проект служит для имитации уровня презентации (который я буду называть тестовым проектом здесь).

из тестового проекта я пытаюсь пройти 2 простых string параметры для другого контроллера, который я буду называть процессом.

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

и в контроллере процесса я пытаюсь получить его следующим образом:

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

но это никогда не достигает этого controller. Я всегда получаю "не найден код состояния".

Итак, как я могу передать 2 простых параметра с HttpClient()?

4 ответов


используйте Get вместо Post для простых параметров типа.

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

    }

на стороне API вы можете сделать так.

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

Я не уверен, что я полностью влюблен в него, но я использовал анонимные типы и динамику, чтобы справиться с этим в прошлом... (Обратите внимание на различия конфигурации для использования PostAsJsonAsync(). Я забыл их поначалу.)

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

контроллер приема:

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

В WebApiConfig.Регистрация ():

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

другой подход, который я передал, заключается в создании совершенно нового набора моделей strongly types для каждого из этих вызовов. Я не хотел, потому что у меня был ... тонна их, чтобы сделать WebAPI.


при получении поста необходимо указать [FromBody] в параметрах метода, который будет называться

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

вот еще один пример, который вы можете использовать для WinForms, WPF или Console приложения

клиентский код

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

серверный код контроллера

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