C# 如何在Xamarin Android中填充ListView?

C# 如何在Xamarin Android中填充ListView?,c#,android,xamarin.android,C#,Android,Xamarin.android,我有一个从SQL数据库检索数据的Web Api。我需要在android的xamrin中使用web api。我不知道如何基于按钮单击事件调用GET和Post方法。现在,使用我编写的代码,当我单击按钮填充列表时,我在应用程序中看到一个空屏幕。我的API在Postman中运行良好,但我不知道如何在Xamarin Android应用程序上运行 我在我的解决方案中创建了一个单独的库,其中包含我的模型和API服务类 Web API获取列表方法 // GET: api/Books [HttpGet] [Rou

我有一个从SQL数据库检索数据的Web Api。我需要在android的xamrin中使用web api。我不知道如何基于按钮单击事件调用GET和Post方法。现在,使用我编写的代码,当我单击按钮填充列表时,我在应用程序中看到一个空屏幕。我的API在Postman中运行良好,但我不知道如何在Xamarin Android应用程序上运行

我在我的解决方案中创建了一个单独的库,其中包含我的模型和API服务类

Web API获取列表方法

// 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);
 } 
//GET:api/Books
[HttpGet]
[路线(“api/books”)]
public IHttpActionResult Get()
{
数不清的书;
books=来自数据库books中的b
选择newbookdto()
{
Id=b.Id,
头衔,头衔,
AuthorName=b.Author.Name
};
返回Ok(书籍);
} 
API服务类

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;
}
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());
        }

    }
public static async Task<IEnumerable<BookDTO>> GetBooks()
{
    var client = new HttpClient();
 private void ShowTitles(IEnumerable<BookDTO> books)
    {
       ...
        /*Change this block accordingly.*/
        foreach (var book in books)
        {                 
            _bookTitles.Add(book.Title.ToString());
        }    
      ...
    }
公共静态异步任务GetBooks() { var client=新的HttpClient(); var msg=await client.GetAsync(url); if(消息IsSuccessStatusCode) { 使用(var stream=await msg.Content.ReadAsStreamAsync()) { 使用(var streamReader=新streamReader(stream)) { var str=wait streamReader.ReadToEndAsync(); var obj=JsonConvert.DeserializeObject(str); 返回obj; } } } 返回null; } MainActivity.cs

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;
}
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());
        }

    }
public static async Task<IEnumerable<BookDTO>> GetBooks()
{
    var client = new HttpClient();
 private void ShowTitles(IEnumerable<BookDTO> books)
    {
       ...
        /*Change this block accordingly.*/
        foreach (var book in books)
        {                 
            _bookTitles.Add(book.Title.ToString());
        }    
      ...
    }
公共类main活动:活动
{
静态只读列表_bookTitles=新列表();
私有列表视图_列表;
创建时受保护的覆盖无效(捆绑包)
{
base.OnCreate(bundle);
//从“主”布局资源设置视图
SetContentView(Resource.Layout.Main);
//从布局资源中获取按钮并向其附加事件
按钮getBooks=findviewbyd(Resource.Id.getBooks);
_list=findviewbyd(Resource.Id.listView1);
getBooks.Click+=async(发送方,e)=>
{
var books=wait BooksApiService.GetBooks();
展览名称(书籍);
};
}
私人作废书名(书籍到书籍)
{
_书名;
foreach(书籍中的var书籍。标题)
{
_bookstitles.Add(book.ToString());
}
}
我的API在Postman中运行良好,但我不知道如何在Xamarin Android应用程序上运行

问题是,在服务器端,您返回一个
IEnumerable
对象。但在客户端,您使用
var obj=JsonConvert.DeserializeObject(str);
将其反序列化为
BookDTO
对象

请尝试使用
var obj=JsonConvert.DeserializeObject(str);

如果问题仍然存在,请通过
var str=wait streamReader.ReadToEndAsync();

我的API在Postman中运行良好,但我不知道如何在Xamarin Android应用程序上运行

问题是,在服务器端,您返回一个
IEnumerable
对象。但在客户端,您使用
var obj=JsonConvert.DeserializeObject(str);
将其反序列化为
BookDTO
对象

请尝试使用
var obj=JsonConvert.DeserializeObject(str);


如果问题仍然存在,请调试以通过
var str=wait streamReader.ReadToEndAsync();

检查
str
是什么。这意味着您正在将IEnumerable图书列表返回到客户端应用程序。 进行以下细微更改:

API服务类

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;
}
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());
        }

    }
public static async Task<IEnumerable<BookDTO>> GetBooks()
{
    var client = new HttpClient();
 private void ShowTitles(IEnumerable<BookDTO> books)
    {
       ...
        /*Change this block accordingly.*/
        foreach (var book in books)
        {                 
            _bookTitles.Add(book.Title.ToString());
        }    
      ...
    }
ShowTitles()应将
IEnumerable
作为一个参数,因为您可能希望遍历每本书,检索相应的标题,并将其添加到\u bookTitles列表中

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);
    };

但是,由于您使用了var类型,这意味着编译器将根据使用情况确定变量的显式类型,因此上述部分将保持原样。

您的Web API方法的返回类型为
IEnumerable
。这意味着您将向客户端应用程序返回IEnumerable图书列表。 进行以下细微更改:

API服务类

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;
}
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());
        }

    }
public static async Task<IEnumerable<BookDTO>> GetBooks()
{
    var client = new HttpClient();
 private void ShowTitles(IEnumerable<BookDTO> books)
    {
       ...
        /*Change this block accordingly.*/
        foreach (var book in books)
        {                 
            _bookTitles.Add(book.Title.ToString());
        }    
      ...
    }
ShowTitles()应将
IEnumerable
作为一个参数,因为您可能希望遍历每本书,检索相应的标题,并将其添加到\u bookTitles列表中

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);
    };

但是,由于您使用了var类型,这意味着编译器将根据用法确定变量的显式类型。

ShowTitles(书籍)中
,我收到此错误消息
无法从system.threading.tasks.task转换为system.Collections.Generic.IEnumerable
我已经更新了我的答案,请检查并让我知道它是如何运行的。它删除了错误消息。但当我单击按钮时,仍然会看到一个空屏幕。我想我必须更深入地研究一下这个问题。我注意到你移除了适配器部件,你能返回它吗?我怀疑这可能是问题所在。你也可以在
return obj
上放置一个断点,检查它是否确实有项目。如果有帮助,别忘了接受答案。在
ShowTitles(书籍)中
,我收到此错误消息
无法从system.threading.tasks.task转换为system.Collections.Generic.IEnumerable
我已经更新了我的答案,请检查并让我知道它是如何运行的。它删除了错误消息。但当我单击按钮时,仍然会看到一个空屏幕。我想我必须更深入地研究一下这个问题。我注意到你拆下了适配器部件,你能退回吗?我怀疑这可能是pr