asp.net-mvc HttpClient 传递多个简单参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26403587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:17:07  来源:igfitidea点击:

HttpClient pass multiple simple parameters

asp.net-mvcpostdotnet-httpclient

提问by Quoter

I'm trying to do a POSTfrom one controllerto another controller. Both controller's are from different projects. One project is serving to simulate the presentation layer (which I will call the test project here).

我正在尝试POST从一个controller到另一个controller。两者controller都来自不同的项目。一个项目用于模拟表示层(这里我将其称为测试项目)。

From the test project I'm trying to pass 2 simple stringparameters to the other controller which I will call the process.

从测试项目中,我试图将 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");
}

And in the process controller, I'm trying to receive it like this:

在过程控制器中,我试图像这样接收它:

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

But it never reaches this controller. I always get a "not found status code".

但它永远达不到这一点controller。我总是收到“未找到状态代码”。

So how can I pass 2 simple parameters with HttpClient()?

那么如何传递 2 个简单的参数HttpClient()呢?

回答by NMK

Use Get instead of Post for simple type parameters.

对于简单的类型参数,使用 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");

    }

In the API side you can do like this.

在 API 方面,您可以这样做。

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

回答by Brady Jerin

When receiving a post you must specify [FromBody] in the parameters for the method to be called

收到帖子时,必须在参数中指定[FromBody] 才能调用方法

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

回答by Developer

Here is another example you can use for WinForms, WPFor Consoleapps

这是您可以用于WinForms,WPFConsole应用程序的另一个示例

Client code

客户端代码

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

回答by SethMW

I'm not sure I am totally in love with it, but I used anonymous types and dynamics to handle this in the past... (Note the config differences for using PostAsJsonAsync(). I forgot these initially.)

我不确定我是否完全爱上它,但我过去使用匿名类型和动态来处理这个问题......(注意使用 PostAsJsonAsync( 的配置差异)。我最初忘记了这些。)

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

Receiving controller:

接收控制器:

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

In WebApiConfig.Register():

在 WebApiConfig.Register() 中:

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

The other approach, which I passed on, is to create a completely new set of strongly types models for every one of these calls. I didn't want to, as I had a ton of them to make to a WebAPI.

我传递的另一种方法是为这些调用中的每一个创建一组全新的强类型模型。我不想这样做,因为我有很多要制作 WebAPI 的内容。