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>

所以应该更改所有调用登录方法的方法,因为现在这个方法采用登录模型而不是用户名和密码