如何使用PostAsync()传递多个简单类型参数?
Let's break down what's going wrong here and fix it step by step:
The Core Problem
Your API controller's VerifyLoginCredentials action expects username and password as URL path parameters (defined in the route users/verifyLoginCredentials/{username}/{password}), but:
- You're passing the literal string
"{username}/{password}"in your request URL instead of replacing those placeholders with actual values. - You're sending a
FormUrlEncodedContentbody, but your action has no[FromBody]parameters—so this content is completely ignored by the parameter binder.
The Correct Approach
Since your action is set up to pull both parameters from the URL, you just need to construct a valid URL with the actual credentials and send a POST request (with no required body, since all parameters are in the URL).
Modified Client Code
Here's the fixed version of your client code:
static async Task<Uri> CreateProductAsync(string username, string password) { using (HttpClient client = new HttpClient()) // Use 'using' to properly dispose the client { client.BaseAddress = new Uri(uri); // Ensure 'uri' is your API's base URL (e.g., "https://yourapi.com/") // Safely construct the request URL with escaped credentials (handles special characters) var escapedUsername = Uri.EscapeDataString(username); var escapedPassword = Uri.EscapeDataString(password); var requestUrl = $"users/verifyLoginCredentials/{escapedUsername}/{escapedPassword}"; // Send POST request with no body (parameters are in the URL) var result = await client.PostAsync(requestUrl, null); string resultContent = await result.Content.ReadAsStringAsync(); result.EnsureSuccessStatusCode(); return result.Headers.Location; } }
Key Improvements & Notes
- URL Placeholder Replacement: We use string interpolation to replace
{username}and{password}with actual values from your method parameters. - URL Escaping:
Uri.EscapeDataStringensures special characters (like spaces,&,/, or@) in credentials don't break the URL format. - HttpClient Disposal: Wrapping
HttpClientin ausingblock ensures proper resource cleanup (though in long-running apps, you might want to reuse a single instance instead). - Unnecessary Body Removal: Since your action doesn't use any request body parameters, we pass
nulltoPostAsync—no need forFormUrlEncodedContenthere.
A More Secure Alternative (Optional)
Passing credentials in URL path parameters is not secure (they get logged in server logs, browser history, etc.). If you can modify the API controller, consider updating it to accept credentials via the request body:
Updated Controller Action
public class LoginCredentials { public string Username { get; set; } public string Password { get; set; } } [HttpPost] [Route("users/verifyLoginCredentials")] // Remove path parameters public IHttpActionResult VerifyLoginCredentials([FromBody] LoginCredentials credentials) { // Do Stuff with credentials.Username and credentials.Password...... return Ok("Login Successful"); }
Updated Client Code for This Alternative
static async Task<Uri> CreateProductAsync(string username, string password) { using (HttpClient client = new HttpClient()) { client.BaseAddress = new Uri(uri); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var credentials = new { Username = username, Password = password }; var jsonContent = new StringContent(JsonConvert.SerializeObject(credentials), Encoding.UTF8, "application/json"); var result = await client.PostAsync("users/verifyLoginCredentials", jsonContent); string resultContent = await result.Content.ReadAsStringAsync(); result.EnsureSuccessStatusCode(); return result.Headers.Location; } }
Note: For the JSON approach, you'll need the Newtonsoft.Json NuGet package (or use System.Text.Json if on a newer framework version).
内容的提问来源于stack exchange,提问作者Aboudi

