简体   繁体   English

如何使用多个简单类型进行PostAsync()?

[英]How do I PostAsync() with multiple simple types?

How do I PostAsync() with multiple simple types as parameters, I have the action controller below: 如何使用多个简单类型作为参数的PostAsync(),我具有以下动作控制器:

[HttpPost]
[Route("users/verifyLoginCredentials/{username}/{password}")]
public IHttpActionResult VerifyLoginCredentials([FromUri]string username, string password)
{

   //Do Stuff......
   return Ok("Login Successful");

}

I am trying to invoke it from a .Net Framerwork 4.5 Client application as below: 我正在尝试从.Net Framerwork 4.5客户端应用程序中调用它,如下所示:

static async Task<Uri> CreateProductAsync(string username, string password)
{


     HttpClient client = new HttpClient();
     client.BaseAddress = new Uri(uri);
     client.DefaultRequestHeaders.Accept.Clear();
     client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
     client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

     var value = new Dictionary<string, string>
     {
        { "username", "test123" }
     };

     var content = new FormUrlEncodedContent(value);
     var result = await client.PostAsync("users/verifyLoginCredentials/{username}/{password}", content);
     string resultContent = await result.Content.ReadAsStringAsync();

     result.EnsureSuccessStatusCode();

     // return URI of the created resource.
     return result.Headers.Location;
}

I have tried mutiple ways so far and have done a lot of reading, most recently here . 到目前为止,我已经尝试了多种方法,并且做了很多阅读,最近一次是在这里

I understand that it is easier to deal with complex types than it is to deal with simple types and that by default complex types are encoded into the request body/content while simple types are encoded into the URI. 我知道处理复杂类型要比处理简单类型容易,并且默认情况下,将复杂类型编码为请求正文/内容,而将简单类型编码为URI。

I have tried to post data by sending key/value pairs encoded using FormUrlEncodedContent(string) by sending Json through StringContent() , I have tried with both single and multiple parameters but I understand the limitation is only with complex types now. 我试图通过通过StringContent()发送Json来发送通过FormUrlEncodedContent(string)编码的键/值对来发布数据,我已经尝试过使用单个和多个参数,但是我知道限制仅限于复杂类型。

I have read many MSDN posts and tutorials, maybe I am missing a crucial piece of information. 我已经阅读了许多MSDN帖子和教程,也许我错过了至关重要的信息。

The controller action above does get executed but with both paramerters having a string value of "{username}" and "{password}" 上面的控制器动作确实得到执行,但是两个参数的字符串值分别为“ {username}”和“ {password}”

When you write 当你写

[Route("users/verifyLoginCredentials/{username}/{password}")]

You are saying "match the username and password parameters, in the specified order, from the Uri", so whatever you send through the body of the POST will be ignored. 您说的是“按照指定的顺序从Uri中匹配用户名和密码参数”,因此通过POST正文发送的任何内容都将被忽略。

You are explicitly passing {username} and {password} as parameters: 您显式传递了{username}和{password}作为参数:

var result = await client.PostAsync("users/verifyLoginCredentials/{username}/{password}", content);

You should be doing this instead: 您应该这样做:

var message = new HttpRequestMessage(HttpMethod.Post, "users/verifyLoginCredentials/username/test123");
var result = await client.SendAsync(message);
string resultContent = await result.Content.ReadAsStringAsync();

If you want to post the data as the body instead of part of the URL, use this: 如果要将数据作为正文而不是URL的一部分发布,请使用以下命令:

[Route("users/VerifyLoginCredentials")]
public IHttpActionResult VerifyLoginCredentials(string username, string password)

 var value = new Dictionary<string, string>
 {
    { "username", "yourUsername" },
    { "passwird", "test123" }
 };

 var content = new FormUrlEncodedContent(value);
 var result = await client.PostAsync("users/verifyLoginCredentials/", content);
 string resultContent = await result.Content.ReadAsStringAsync();

The simplest way would be to create a model which contains everything you need. 最简单的方法是创建一个包含所需内容的模型。

An example would be: 一个例子是:

public class LoginModel 
{
    [Required]
    public string Username { get;set }

    [Required]
    public string Password { get;set }
}

you can now do: 您现在可以执行以下操作:

[HttpPost]
[Route("users/verifyLoginCredentials")]
public IHttpActionResult VerifyLoginCredentials([FromBody]LoginModel model)
{
   //validate your model    
   if ( model == null || !ModelState.IsValid )     
   {
       return BadRequest();
   }

   //stuff
   return Ok();
}

To use it you would do something like this: 要使用它,您将执行以下操作:

var model = new LoginModel { Username = "abc", Password="abc" } ;

using (var client = new HttpClient())
{               
    var content = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json");               

    var result = await client.PostAsync("your url", content);
    return await result.Content.ReadAsStringAsync();
}

Do not send passwords in the URI as anyone can intercept the request and see what the password is. 不要在URI中发送密码,因为任何人都可以拦截请求并查看密码是什么。

Any data which needs to remain secret you send it in the body of the request and make sure the request is over https as that encodes the headers and the post body so no one can look at the data. 您需要将任何需要保密的数据发送到请求的主体中,并确保请求通过https进行编码,因为该请求会编码标头和主体,因此没有人可以查看该数据。

[HttpPost("{coverPagePath}")] 
public void Post([FromRoute] string coverPagePath, [FromBody] UserCoverpage value)
{
   var args = new[] { WebUtility.UrlDecode(coverPagePath).Replace("\\", "/") };
   userCoverpageService.Create(value, args);
}
...
//test:
var json = item.SerializeToJson(true);
HttpContent payload = new StringContent(json, Encoding.UTF8, "application/json");

// act
var response = await httpClient.PostAsync($"/api/UserCoverpage/{coverPagePath}", payload); 
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(true);
output.WriteLine(data);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM