asp.net 核心 api 从 kotlin 获取空值
asp.net core api get null value from kotlin
我创建了一个 API 和 ASP.net 核心,可以很好地与 postman 配合使用。但是当我使用 Kotlin 和 Retrofit 传递数据时,API 得到空值。所有数据都可以通过 Kotlin 发送到服务器。
Kotlin 和 ASP.net Core 中的所有模型都相同。
这是我的改造 class:
class ApiClient {
companion object{
var retrofit:Retrofit? = null
var baseUrl = "http://10.0.2.2:5000/api/"
fun getClient():Retrofit{
if(retrofit == null){
var okHttpClient = OkHttpClient().newBuilder()
.addInterceptor {
var oldRequest = it.request()
var newRequestBuilder = oldRequest.newBuilder()
if (Utils.myToken != null) {
newRequestBuilder.addHeader("token", Utils.myToken!!)
}
newRequestBuilder.addHeader("Accept", "application/json")
newRequestBuilder.method(oldRequest.method, oldRequest.body)
return@addInterceptor it.proceed(newRequestBuilder.build())
}.build()
retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
}
return retrofit!!
}
}
}
这是改造接口代码:
@FormUrlEncoded
@POST("authentication/login")
fun login(
@Field("username") username:String,
@Field("password") password:String
):Call<Result>
这是我的 Kotlin 代码:
loginViewModel.login(username,password).observe(viewLifecycleOwner,{
if(it.Status < 0){
Toast.makeText(context,it.Message,Toast.LENGTH_SHORT).show()
}else{
val manager = activity?.supportFragmentManager
loginViewModel.setToken(it.Message)
loginViewModel.setRoleId(it.Status)
Utils.createAnimation(activity?.findViewById(R.id.frm_mainActivity_mainLayout),Techniques.SlideInRight,700,0)
Utils.createFragment(manager!!,HomeFragment(),false)
}
})
这是ASP.net核心API代码:
[HttpPost("login")]
public async Task<ActionResult<Result>> Login(string username,string password){
var user = await _repository.Login(username,password);
Result result = new Result();
if(user == null)
{
result.Status = -1;
result.Message = "نام کاربری یا کلمه عبور اشتباه است";
return NotFound(result);
}
else
{
result.Status = user.RoleId;
result.Message = user.Token;
return Ok(result);
}
}
那么为什么 API 得到空值?
首先创建一个 DTO 作为登录名,然后将其传递给 ASP.net Core 中的登录函数,而不是像这样的用户名和密码:
public class Login
{
public string Username { get; set; }
public string Password { get; set; }
}
controller中的login函数变化如下:
[HttpPost("login")]
public async Task<ActionResult<Result>> Login(Login login){
var user = await _repository.Login(login.Username,login.Password);
Result result = new Result();
if(user == null)
{
result.Status = -1;
result.Message = "نام کاربری یا کلمه عبور اشتباه است";
return NotFound(result);
}
else
{
result.Status = user.RoleId;
result.Message = user.Token;
return Ok(result);
}
}
然后在 Kotlin 中应该创建一个模型,例如 ASP.net Core
中的 Login DTO
class Login(var username:String,var password:String)
现在应该更改 Retrofit 界面并使用 @Body 而不是 @Field,如下所示:
@POST("authentication/login")
fun login(@Body login: Login):Call<Result>
所以应该更改所有调用登录方法的方法,因为现在这个方法采用登录模型而不是用户名和密码
我创建了一个 API 和 ASP.net 核心,可以很好地与 postman 配合使用。但是当我使用 Kotlin 和 Retrofit 传递数据时,API 得到空值。所有数据都可以通过 Kotlin 发送到服务器。 Kotlin 和 ASP.net Core 中的所有模型都相同。
这是我的改造 class:
class ApiClient {
companion object{
var retrofit:Retrofit? = null
var baseUrl = "http://10.0.2.2:5000/api/"
fun getClient():Retrofit{
if(retrofit == null){
var okHttpClient = OkHttpClient().newBuilder()
.addInterceptor {
var oldRequest = it.request()
var newRequestBuilder = oldRequest.newBuilder()
if (Utils.myToken != null) {
newRequestBuilder.addHeader("token", Utils.myToken!!)
}
newRequestBuilder.addHeader("Accept", "application/json")
newRequestBuilder.method(oldRequest.method, oldRequest.body)
return@addInterceptor it.proceed(newRequestBuilder.build())
}.build()
retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
}
return retrofit!!
}
}
}
这是改造接口代码:
@FormUrlEncoded
@POST("authentication/login")
fun login(
@Field("username") username:String,
@Field("password") password:String
):Call<Result>
这是我的 Kotlin 代码:
loginViewModel.login(username,password).observe(viewLifecycleOwner,{
if(it.Status < 0){
Toast.makeText(context,it.Message,Toast.LENGTH_SHORT).show()
}else{
val manager = activity?.supportFragmentManager
loginViewModel.setToken(it.Message)
loginViewModel.setRoleId(it.Status)
Utils.createAnimation(activity?.findViewById(R.id.frm_mainActivity_mainLayout),Techniques.SlideInRight,700,0)
Utils.createFragment(manager!!,HomeFragment(),false)
}
})
这是ASP.net核心API代码:
[HttpPost("login")]
public async Task<ActionResult<Result>> Login(string username,string password){
var user = await _repository.Login(username,password);
Result result = new Result();
if(user == null)
{
result.Status = -1;
result.Message = "نام کاربری یا کلمه عبور اشتباه است";
return NotFound(result);
}
else
{
result.Status = user.RoleId;
result.Message = user.Token;
return Ok(result);
}
}
那么为什么 API 得到空值?
首先创建一个 DTO 作为登录名,然后将其传递给 ASP.net Core 中的登录函数,而不是像这样的用户名和密码:
public class Login
{
public string Username { get; set; }
public string Password { get; set; }
}
controller中的login函数变化如下:
[HttpPost("login")]
public async Task<ActionResult<Result>> Login(Login login){
var user = await _repository.Login(login.Username,login.Password);
Result result = new Result();
if(user == null)
{
result.Status = -1;
result.Message = "نام کاربری یا کلمه عبور اشتباه است";
return NotFound(result);
}
else
{
result.Status = user.RoleId;
result.Message = user.Token;
return Ok(result);
}
}
然后在 Kotlin 中应该创建一个模型,例如 ASP.net Core
中的 Login DTOclass Login(var username:String,var password:String)
现在应该更改 Retrofit 界面并使用 @Body 而不是 @Field,如下所示:
@POST("authentication/login")
fun login(@Body login: Login):Call<Result>
所以应该更改所有调用登录方法的方法,因为现在这个方法采用登录模型而不是用户名和密码