简体   繁体   中英

How to create a Client side WebService to call API?

I am working on calling a Web API from MVC5 service using HttpClient . I had first created a MVC Controller and the Get method was working with the HttpClient , but now I have to move the logic into a service class and I am getting errors with async actions and returning a list of books in the Get() method.

Do I need to use HttpWebRequest instead for the service class?

Can someone please assist me in this issue.

API Get()

[HttpGet]    
[Route("api/books")]
public IHttpActionResult Get()
{
    IEnumerable<BookDTO> books;
    books = from b in db.Books
        select new BookDTO()
        {
            Id = b.Id,
            Title = b.Title,
            AuthorName = b.Author.Name
        };
    return Ok(books);
}

Client BookService

HttpClient client;

public IEnumerable<Book> GetBooks()
{
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + MyToken.myToken);

    HttpResponseMessage responseMessage = client.GetAsync(url).Result;

    if (responseMessage.IsSuccessStatusCode)
    {
        var responseData = responseMessage.Content.ReadAsStringAsync().Result;

        var books = JsonConvert.DeserializeObject<IEnumerable<Book>>(responseData);

        return books;
    }            
}

It is also asking me to have a return after the if body?

You don't have to use a service if you don't want to. it could be a nice way ot package up all your calls to a specific webservice.

As for the compiler error, return something after your if statement.

It could be an empty list.

public IEnumerable<Book> GetBooks()
{
      client.DefaultRequestHeaders.Add("Authorization", "Bearer " + MyToken.myToken);

      HttpResponseMessage responseMessage = client.GetAsync(url).Result;

      if (responseMessage.IsSuccessStatusCode)
      {
         var responseData = responseMessage.Content.ReadAsStringAsync().Result;

         var books = JsonConvert.DeserializeObject<IEnumerable<Book>>(responseData);

         return books;
      }    

      return new List<Book> {};        

}

or you could throw an exception if you want.

Both will satisfy the compiler error.

You should dispose HttpClient object if you no longer need it.

If you use async, the best practice is async all the way back to UI layer . You should not mix blocking and async code.

public async Task<IEnumerable<Book>> GetBooks()
{
    IEnumerable<Book> books = new List<Book>();
    using (HttpClient client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + MyToken.myToken);
        HttpResponseMessage responseMessage = await client.GetAsync(url);
        if (responseMessage.IsSuccessStatusCode)
        {
            var responseData = await responseMessage.Content.ReadAsStringAsync();
            books = JsonConvert.DeserializeObject<IEnumerable<Book>>(responseData);
        }
    }
    return books;
}

Here is the sample console app if you want to test it.

static void Main(string[] args) => Task.Run(() => MainAsync(args)).Wait();

static async Task MainAsync(string[] args)
{
    var result = await GetResponseFromURI(new Uri("http://www.google.com"));
    Console.WriteLine(result);
    Console.ReadLine();
}

static async Task<string> GetResponseFromURI(Uri u)
{
    var response = "";
    using (var client = new HttpClient())
    {
        HttpResponseMessage result = await client.GetAsync(u);
        if (result.IsSuccessStatusCode)
        {
            response = await result.Content.ReadAsStringAsync();
        }
    }
    return response;
}

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