Search code examples
c#tuplesblazor-webassemblywebapi

Tuple not returning from Asp.Net Core Web Api method


I have this method in my web api:

[HttpGet("GetPerson/{id}")]
[Authorize(Roles = "Administrators")]
public async Task<(Person, List<ContactData>)> GetPerson(int id = 0)
{                
    Data.ThePerson person = new Data.ThePerson();
    List<ContactData> cDatas = person.contactDatas.Where(it => it.ContactId == id).ToList();
    var p = person.persons.FirstOrDefault(p => p.Id == id);
    return (p, cDatas);        
}

But the method returns (, ) in the client! How to correct this?

Client:

public async Task<(Person, List<ContactData>)> GetPerson(int id)
{
    var tuple = await Http.GetFromJsonAsync<(Person, List<ContactData>)>($"api/account/GetPerson/{id}");
    return tuple;
}

The server and client methods work when it only returns a Person object but converting it to tuple returns (, ). also I can see in the server that correct tuple builds and returns but in the client it is (, ).


Solution

  • The issue might be related to serialization and deserialization of the tuple when returning it from the API.

    You can use a simple class to hold both the Person and List<ContactData> as properties. Use this class as the return type for your API method instead of a tuple.

    public class PersonData
    {
        public Person Person { get; set; }
        public List<ContactData> ContactData { get; set; }
    }
    

    Modify your API method to return the PersonData class:

    [HttpGet("GetPerson/{id}")]
    [Authorize(Roles = "Administrators")]
    public async Task<PersonData> GetPerson(int id = 0)
    {                
        Data.ThePerson person = new Data.ThePerson();
        List<ContactData> cDatas = person.contactDatas.Where(it => it.ContactId == id).ToList();
        var p = person.persons.FirstOrDefault(p => p.Id == id);
    
        return new PersonData
        {
            Person = p,
            ContactData = cDatas
        };
    }
    

    Update your client method to handle the PersonData class:

    public async Task<PersonData> GetPerson(int id)
    {
        return await Http.GetFromJsonAsync<PersonData>($"api/account/GetPerson/{id}");
    }