Reputation: 469
I have a Web Api that retrieves data from SQL database. I need to consume web api in xamrin for android. I am not sure how to call the GET and Post methods based on button click event. Right now with the code I have written, when I click the button to populate the list, I am getting an empty screen in the App. My API is working fine in Postman, but I don't know how to make it work on Xamarin Android App.
I have created a separate Library in my solution which has my Models and API Service class.
Web API Get List method
// GET: api/Books
[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);
}
API Service class
public static async Task<BookDTO> GetBooks()
{
var client = new HttpClient();
var msg = await client.GetAsync(url);
if (msg.IsSuccessStatusCode)
{
using (var stream = await msg.Content.ReadAsStreamAsync())
{
using (var streamReader = new StreamReader(stream))
{
var str = await streamReader.ReadToEndAsync();
var obj = JsonConvert.DeserializeObject<BookDTO>(str);
return obj;
}
}
}
return null;
}
MainActivity.cs
public class MainActivity : Activity
{
static readonly List<string> _bookTitles = new List<string>();
private ListView _list;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get the button from the layout Resource and attach an event to it
Button getBooks = FindViewById<Button>(Resource.Id.GetBooks);
_list = FindViewById<ListView>(Resource.Id.listView1);
getBooks.Click += async (sender, e) =>
{
var books = await BooksApiService.GetBooks();
ShowTitles(books);
};
}
private void ShowTitles(BookDTO books)
{
_bookTitles.Clear();
foreach (var book in books.Title)
{
_bookTitles.Add(book.ToString());
}
}
Upvotes: 0
Views: 882
Reputation: 11941
Your Web API method's return type is IEnumerable<BookDTO>
. This means that you are returning an IEnumerable List of books to the client app.
Make these slight changes:
API Service class
public static async Task<IEnumerable<BookDTO>> GetBooks()
{
var client = new HttpClient();
Change the return type of your Task to IEnumerable<BookDTO>
as shown above.
if (msg.IsSuccessStatusCode)
{
using (var stream = await msg.Content.ReadAsStreamAsync())
{
using (var streamReader = new StreamReader(stream))
{
var str = await streamReader.ReadToEndAsync();
var obj = JsonConvert.DeserializeObject<IEnumerable<BookDTO>>(str);
return obj;
}
}
}
Change the type to be deserialized to, from BookDTO
to IEnumerable<BookDTO>
as shown above.
MainActivity.cs
private void ShowTitles(IEnumerable<BookDTO> books)
{
...
/*Change this block accordingly.*/
foreach (var book in books)
{
_bookTitles.Add(book.Title.ToString());
}
...
}
The ShowTitles() should take IEnumerable<BookDTO>
as a parameter, since you might want to iterate through each book and retrieving the respective Title and adding that to the _bookTitles list.
getBooks.Click += async (sender, e) =>
{
/*This is will work, but it's not recommended. I'll update it later.*/
var books = await BooksApiService.GetBooks();
ShowTitles(books.Result);
};
However, the section above will remain as is since you've used the var type which means the compiler will determine the explicit type of the variable, based on the usage.
Upvotes: 2
Reputation: 10841
My API is working fine in Postman, but I don't know how to make it work on Xamarin Android App.
The problem is, on server side, you return an IEnumerable<BookDTO>
object. But on Client side, you deserialize it into a BookDTO
object using var obj = JsonConvert.DeserializeObject<BookDTO>(str);
.
Please try deserialize it into an IEnumerable<BookDTO>
with var obj = JsonConvert.DeserializeObject<IEnumerable<BookDTO>>(str);
If the problem still persists, please debug to check what the str
is by var str = await streamReader.ReadToEndAsync();
Upvotes: 1