如何从 api 中获取单个对象并显示它

How to get single object from an api and display it

我正在尝试构建一个应用程序来帮助您做出晚餐决定。我希望用户能够单击一个按钮,应用程序应使用 API 显示一个随机的晚餐名称。我正在尝试显示来自 API 的数据。到目前为止,这是我的代码。我收到一个空异常。感谢任何帮助:)

namespace jello
{
    public partial class NetworkingManager : ContentPage
    {
        private string name;
        public string url;
        public String Name {
            get { return name; }
            set
                {
                    name = value;
                }
        }

        public class RecipeClass
        {
            public class Data
            {
                public string strMeal { get; set; }
            }
            public Data data { get; set; }
        }

        public const string Url = "https://www.themealdb.com/api/json/v1/1/search.php?f=a";
        public HttpClient client = new HttpClient();
    
        public NetworkingManager()
        {
            InitializeComponent();
            BindingContext = this;
            name = GetDetails();
        }
    
        string temp;

        public async void  GetString()
        {
            var content = await client.GetStringAsync(Url);
            temp = content;
        }
    
        public RecipeClass getObj()
        {  
            var output = JsonConvert.DeserializeObject<RecipeClass>(temp);
            return output;
        }
           
        public String GetDetails()
        {
            var name = getObj().data.strMeal;
            return name;
        }
    }
}

你可以这样做:

    public async void  GetMeal()
    {
        var content = await client.GetStringAsync(Url);
        var output = JsonConvert.DeserializeObject<RecipeClass>(content);
        Name = output.data.strMeal;
    }

这样称呼它:GetMeal() 你不需要把 name = GetMeal(); 你的 属性 名称设置在最后。

你的根本问题是你想从你的构造函数中调用一些异步的东西,而构造函数不能是异步的。您可以使用此异步工厂模式解决该问题:

首先将构造函数设为私有,这样就无法从外部调用它:

private NetworkingManager()
{
    InitializeComponent();
    BindingContext = this;
}

然后你做一个异步方法来初始化它:

private async Task<MyClass> InitializeAsync()
{
    var temp = await GetStringAsync();
    var output = JsonConvert.DeserializeObject<RecipeClass>(temp);
    name = output.data.strMeal;
    return this;
}

public async Task<string> GetStringAsync()
{
    return await client.GetStringAsync(Url);
}

最后是创建它的异步方法:

public static Task<NetworkingManager> CreateAsync()
{
    var manager = new NetworkingManager();
    return manager.InitializeAsync();
}

您通过以下方式从外部构建实例:

NetworkingManager instance = await NetworkingManager.CreateAsync();

最后一条关于命名的注意事项:不要称呼 class 成员 temp。没有什么是暂时的。它与实例一样长。如果方法像此处那样获取特定字符串,则不要调用非常通用的 GetString 方法。将其称为 GetMealString 或 GetMealName 或其他名称。 getObj也是一样的,顺便说一句,它应该以大写字母开头。以清晰具体的方式命名您的成员,程序的结构对您来说会变得更加清晰。