简体   繁体   中英

Mapping object key values in dictionary and mapping properties with JsonPropertyName

I created a basic console app that calls an external API. My Main method is hard coded for testing purpose:

static void Main(string[] args)
{
    // building a login request
    LoginRequest loginRequest = new LoginRequest("myLogin", "myPassword");
    LoginService loginService = new LoginServiceImpl();

    LoginResponse loginResponse = loginService.Authenticate(loginRequest);
        
    Console.WriteLine("Authentication tryout!");
    Console.WriteLine(">> Token : " + loginResponse.AccessToken);
    Console.WriteLine(">> Type  : " + loginResponse.TokenType);
}

I'm passing an object to the service layer. In this class I implemented the method Authenticate:

public LoginResponse Authenticate(LoginRequest request)
{
    LoginResponse returnValue = new  LoginResponse();
    Uri uri = new Uri("http://www.myapi.com/v1/login");
    HttpRequest httpRequest = new HttpRequest();   

    Task<LoginResponse> loginTask = httpRequest.Authentication(request, uri);
    returnValue = loginTask.GetAwaiter().GetResult();

    return returnValue;
}

Now here are my 2 problems while calling Authentication method in HttpRequest:

public async Task<LoginResponse> Authentication(LoginRequest request, Uri url)
{
    var dict = new Dictionary<string, string>();
    dict.Add("login", request.login);
    dict.Add("password", request.Password);

    HttpClient client = new HttpClient(); 
    client.DefaultRequestHeaders.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/json")
    );
    var req = new HttpRequestMessage(HttpMethod.Post, url) { 
        Content = new FormUrlEncodedContent(dict) 
    }; 
    var response = await client.SendAsync(req); 
        
    string output = await response.Content.ReadAsStringAsync();
    Console.WriteLine(JsonConvert.DeserializeObject(output));
    LoginResponse returnValue = JsonConvert.DeserializeObject<LoginResponse>(output);
        
    return returnValue;
 }

My first issue is that my dictionnary is duplicating the key values in the dictionary. I have:

Key: "username"
value: "helloWorld"
Key: "username"
value: "helloWorld"

I also tried to use dictionnary with something like this:

var dictionary = ToDictionary<string>(request);
foreach(KeyValuePair<string, string> entry in dictionary)
{
    dictionary.Add(entry.Key, entry.Value);
    Console.WriteLine(entry.Key);
    Console.WriteLine(entry.Value);
}

The ToDictionnary is the following:

public Dictionary<string, TValue> ToDictionary<TValue>(object obj)
{       
    var json = JsonConvert.SerializeObject(obj);
    var dictionary = JsonConvert.DeserializeObject<Dictionary<string, TValue>>(json);
    if (dictionary != null)
    {
        return dictionary;
    }
    // handle exception here... 
    return null;
}

It also duplicated the key value and throws an exception.

My Second issue is that I don't know how to map JsonPropertyName with the Property name. My call returns a string that i convert to object.

My model is the following:

public class LoginResponse
{
    [JsonPropertyName("access_token")]
    public string AccessToken { get; set; }
    
    [JsonPropertyName("type_token")]
    public string TokenType { get; set; }

    public LoginResponse() { }
}

As a result I do get a string that i map as object but keys are not mapped: I obtain:

{ "access_token": "abcdef", "type_token": "Bearer" }

While I expect:

{ "AccessToken": "abcdef", "TokenType": "Bearer" }

I solved my issue with serialization. I was using System.Text.Json.Serialization... I replaced by using Newtonsoft.Json in my model.

I also changed annotation:

[JsonPropertyName("access_token")]

with:

[JsonProperty(PropertyName = "access_token")]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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