Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to consume a ASP.NET Core WebAPI in a C# UWP application?

I am trying to understand how it is possible to consume a ASP.NET Core WebAPI within an UWP/UAP application. I thought I would be possible to consume the WebAPI similar to consuming a WCF Service but I haven't found anything about that yet.

Furthermore I tried to install Microsoft.AspNet.WebApi.Core but had no success as it is not compatible with UAP (Version=V10.0).

I am a bit lost now. Maybe someone could give me a hint how I could use the WebApi within the UWP application.

like image 284
Chris Avatar asked Jul 11 '16 14:07

Chris


3 Answers

This is the same as consuming any API call. Simply use the HttpClient class to invoke the endpoint and handle the response, there is no difference in the expected behaviour.

Imagine that you have an ASP.NET Core Web API endpoint defined like this:

public class StackoverflowController : Controller
{    
    // I wanted to exemplify async capabilities.
    // You'd use async/await for getting database values, etc.
    [
        HttpGet,
        AllowAnonymous,
        Route("api/greeting")
    ]
    public Task<GreetingResult> Greeting() =>
        Task.FromResult(new GreetingResult { Message = "Hello world!" });
}

public class GreetingResult
{
    public string Message { get; set; }
}

Assuming this was hosted on `localhost:5000' you could do the following:

public class Consumer
{
    public async Task<string> GetGreetingAsync()
    {
        using (var client = new HttpClient())
        {
            var response = 
                await client.GetStringAsync("http://localhost:5000/api/greeting");
            // The response object is a string that looks like this:
            // "{ message: 'Hello world!' }"
        }
    }
}

Additionally, you could deserialize this as a strongly typed object use Newtonsoft.Json. I have an example of my UWP app doing this very thing here.

like image 60
David Pine Avatar answered Nov 11 '22 08:11

David Pine


I will add some more information to that:

Best way to consume Web Api in UWP is to use HttpClient as mentioned before.

Here are some examples I think might be helpful.

The good practice is to create MobileServiceClient class where you can collect all operations that you can perform on the Web Api level:

public class MobileServiceClient
{
    //access token if you use authentication:
    private string _accessToken;
    //address of your Web Api:
    private string _serviceAddress;

    //Constructor:
    public MobileServiceClient(string accessToken, string serviceAddress)
    {
        _accessToken = accessToken;
        _serviceAddress = serviceAddress;
    }

//Now you can implement methods that you will invoke to perform selected operation related with Web Api:

#region Methods

//You can perform "Get" to retrieve object from the Web Api and then deserialize it (using Json .NET):

public async Task<SampleClass> GetSampleClass()
    {
        SampleClass sampleClass= null;
        try
        {
            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + _accessToken);
                var data = await client.GetAsync(string.Concat(_serviceAddress, "routeName"));
                var jsonResponse = await data.Content.ReadAsStringAsync();
                if (jsonResponse != null)
                    sampleClass= JsonConvert.DeserializeObject<SampleClass>(jsonResponse);
                return sampleClass;
            }
        }

        catch (WebException exception)
        {
            throw new WebException("An error has occurred while calling GetSampleClass method: " + exception.Message);
        }
    }

//You can perform "Get" to retrieve list of objects and then deserialize it:

public async Task<List<SampleClass>> GetSampleClassObjects()
    {
        List<SampleClass> SampleClassObjectsList = null;
        try
        {
            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + _accessToken);
                var data = await client.GetAsync(string.Concat(_serviceAddress, "routeName"));
                var jsonResponse = await data.Content.ReadAsStringAsync();
                if (jsonResponse != null)
                    SampleClassObjectsList = JsonConvert.DeserializeObject<List<SampleClass>>(jsonResponse);
                return SampleClassObjectsList;
            }
        }

        catch (WebException exception)
        {
            throw new WebException("An error has occurred while calling GetSampleClassObjects method: " + exception.Message);
        }
    }

//You can also "Post" some object:

public async Task<bool> PostSomeObject(SampleClass sampleClassObject)
    {
        try
        {
            using (HttpClient client = new HttpClient())
            {
                var sampleClassObjectJson = JsonConvert.SerializeObject(sampleClassObject);
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + _accessToken);
                var content = new StringContent(sampleClassObjectJson, Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.PostAsync(string.Concat(_serviceAddress + "routeName"), content);
                if (response.StatusCode == HttpStatusCode.OK)
                    return true;
                else
                    throw new WebException("An error has occurred while calling PostSomeObject method: " + response.Content);
            }
        }

        catch (WebException exception)
        {
            throw new WebException("An error has occurred while calling PostFeedback method: " + exception.Message);
        }
    }
#endregion
}

Please note that with such implementation you can share the code in the future if you decide for instance to support other platfroms (like Xamarin Android or iOS). I hope this will help you.

like image 31
Daniel Krzyczkowski Avatar answered Nov 11 '22 08:11

Daniel Krzyczkowski


David Pines answer is good enough if you want to do all the stuff manually and/or you don't use swagger.

If you use Swagger (i.e. Swashbuckle Swagger 6.0 for ASP.NET Core) to describe your RESTful API and generate documentation for it, you can use the swagger definition file (swagger.json) to generate an Rest Client. One such tool is AutoRest, created by the Azure team. It will also require Microsoft.Rest.ClientRuntime which already supports DotNet.

I'm not sure if it runs with ASP.NET Core RTM yet, but there were solved/closed issues indicating that it had support for previous versions and betas merged into it.

NuGet Package Links

  • AutoRest
  • Client Runtime for Microsoft AutoRest Generated Clients
like image 35
Tseng Avatar answered Nov 11 '22 09:11

Tseng