【发布时间】:2020-08-23 11:36:02
【问题描述】:
我创建了一个 ASP.NET Web API 项目,其中创建了两个 api 控制器,一个是获取所有注册用户,第二个是通过用户名和密码登录到应用程序。虽然我用邮递员测试了这两种方法,但工作正常。我正在使用 BaseAddress 属性来放置 URI,并将“api/controllername/action”放在 PostAsJsonAsync() 方法中。当我调试我的 xamarin 应用程序代码时,它在 PostAsJasonAsync() 方法中显示-
{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Connection: close
Date: Sun, 23 Aug 2020 11:13:44 GMT
Forwarded: host=192.168.20.176:45459; proto=http
Server: Microsoft-HTTPAPI/2.0
X-Android-Received-Millis: 1598181223781
X-Android-Response-Source: NETWORK 400
X-Android-Selected-Protocol: http/1.1
X-Android-Sent-Millis: 1598181223764
Content-Length: 374
Content-Type: text/html; charset=us-ascii}.
Web API 控制器代码是:
public class LoginController : ApiController
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["SPCon"].ToString());
SqlCommand cmd = new SqlCommand();
[HttpPost]
public int Login([FromBody] Login user)
{
int ret = 0;
try
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT count(*) FROM Login WHERE UserNames = '" + user.UserName.Trim() + "' and PassWord=" + user.PassWord.Trim();
cmd.Connection = con;
if (con.State == ConnectionState.Open)
{
con.Close();
}
con.Open();
ret = Convert.ToInt32(cmd.ExecuteScalar());
con.Close();
}
catch
{
}
return ret;
}
}
移动应用代码如下:
public void LoginBtnClicked()
{
if (Username.Trim() != "" && Password.Trim() != "")
{
using(var client=new HttpClient())
{
client.BaseAddress = new Uri("http://ipaddress:45459/"); //I'm using conveyor to get this address and I'm running mobile app in android emulator
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
UserLogin user = new UserLogin
{
UserName = Username,
PassWord = Password
};
var response = client.PostAsJsonAsync("api/Login/Login", user).Result;
if (response.IsSuccessStatusCode)
{
var a = response.Content.ReadAsStringAsync();
if (a.Result.ToString().Trim() == "0")
{
Application.Current.MainPage.DisplayAlert("Error", "Invalid Login Credentials", "Cancel");
}
else
{
Application.Current.MainPage.Navigation.PushAsync(new Home());
}
}
else
{
Application.Current.MainPage.DisplayAlert("Error", "Internal Server Error", "Ok");
}
}
}
}
【问题讨论】:
-
服务端的Login类和客户端的UserLogin类定义一样吗?
-
是的,定义相同
-
解决问题的最佳方法是使用像 wireshark 或 fiddler 这样的嗅探器。使用 Postman 将第一个请求中的标头与 c# 标头进行比较。使 c# 代码看起来与 Postman 完全一样。 c# 中的默认标头与 Postman 不同,要么标头错误,要么标头缺失。
-
就像@jdweng 说的,你应该检查你添加的标题。邮递员通常会添加一些通用标题,尤其是未包含的
language在过去给我带来了问题。但就目前而言,没有办法确切知道问题是什么 -
您可能需要指定 TLS 版本 1.2 : HttpClient httpClient = new HttpClient(); //指定使用 TLS 1.2 作为默认连接 System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
标签: c# android asp.net-web-api xamarin.forms httpclient