You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中用数组元素作为反序列化JSON的RootObject标识符?

问题:C#调用OMDB API后,无法通过字符串数组动态访问反序列化对象的属性

问题描述

我正在用C#开发一个控制台应用,调用OMDB API获取特定电影信息。把JSON反序列化为RootObject后,尝试用数组里的字段名作为标识符访问movie对象时遇到了问题。以下是我的代码:

定义的实体类

public class Rating { 
    public string Source { get; set; } 
    public string Value { get; set; } 
}
public class RootObject { 
    public string Title { get; set; } 
    public string Year { get; set; } 
    public string Rated { get; set; } 
    public string Released { get; set; } 
    public string Runtime { get; set; } 
    public string Genre { get; set; } 
    public string Director { get; set; } 
    public string Writer { get; set; } 
    public string Actors { get; set; } 
    public string Plot { get; set; } 
    public string Language { get; set; } 
    public string Country { get; set; } 
    public string Awards { get; set; } 
    public string Poster { get; set; } 
    public List<Rating> Ratings { get; set; } 
    public string Metascore { get; set; } 
    public string imdbRating { get; set; } 
    public string imdbVotes { get; set; } 
    public string imdbID { get; set; } 
    public string Type { get; set; } 
    public string DVD { get; set; } 
    public string BoxOffice { get; set; } 
    public string Production { get; set; } 
    public string Website { get; set; } 
    public string Response { get; set; } 
}

主程序代码

public static string getJson() { 
    string titleOfDesiredMovie = Console.ReadLine(); 
    WebClient client = new WebClient(); 
    string json = client.DownloadString("http://www.omdbapi.com/?t=" + titleOfDesiredMovie + "&apikey=SECRETKEY"); 
    return json; 
}
static void Main(string[] args) { 
    RootObject movie = new JavaScriptSerializer().Deserialize<RootObject>(getJson()); 
    string[] array = { "Title", "Year", "Rated", "Genre", "Writer", "Plot" }; 
    for (int i = 0; i < array.Length;i++ ) { 
        foreach (var item in movie.array[i]) { 
            Console.Write(item); 
        } 
        Console.WriteLine(); 
    } 
    var key = Console.ReadKey(); 
}

这是我第一次提问,若有优化提问的建议也请告知。


解决方案

你遇到的核心问题是:C#是静态类型语言,不能直接通过movie.array[i]这种字符串形式动态访问对象的属性。下面给你几种可行的解决办法:

方法1:使用反射动态获取属性值

反射可以让你在运行时获取对象的属性信息并读取值,修改你的Main方法如下:

static void Main(string[] args) { 
    RootObject movie = new JavaScriptSerializer().Deserialize<RootObject>(getJson()); 
    string[] array = { "Title", "Year", "Rated", "Genre", "Writer", "Plot" }; 
    
    foreach (var propertyName in array) {
        // 获取属性信息
        var property = typeof(RootObject).GetProperty(propertyName);
        if (property != null) {
            // 读取属性值并输出
            var value = property.GetValue(movie);
            Console.WriteLine($"{propertyName}: {value ?? "N/A"}");
        } else {
            Console.WriteLine($"{propertyName}: 属性不存在");
        }
    }
    
    var key = Console.ReadKey(); 
}

方法2:改用JObject(推荐,更灵活)

如果你使用Newtonsoft.Json(NuGet包可安装),可以直接把JSON反序列化为JObject,这样就能像字典一样用字符串索引访问属性:

// 先安装Newtonsoft.Json包
using Newtonsoft.Json.Linq;

static void Main(string[] args) { 
    string json = getJson();
    JObject movie = JObject.Parse(json);
    string[] array = { "Title", "Year", "Rated", "Genre", "Writer", "Plot" }; 
    
    foreach (var propertyName in array) {
        var value = movie[propertyName];
        Console.WriteLine($"{propertyName}: {value ?? "N/A"}");
    }
    
    var key = Console.ReadKey(); 
}

方法3:使用ExpandoObject

JavaScriptSerializer也可以把JSON反序列化为ExpandoObject,然后转成字典来访问:

static void Main(string[] args) { 
    dynamic movie = new JavaScriptSerializer().Deserialize<ExpandoObject>(getJson());
    var movieDict = (IDictionary<string, object>)movie;
    string[] array = { "Title", "Year", "Rated", "Genre", "Writer", "Plot" }; 
    
    foreach (var propertyName in array) {
        if (movieDict.TryGetValue(propertyName, out var value)) {
            Console.WriteLine($"{propertyName}: {value ?? "N/A"}");
        } else {
            Console.WriteLine($"{propertyName}: 属性不存在");
        }
    }
    
    var key = Console.ReadKey(); 
}

额外优化建议

  • 替换过时的WebClient:WebClient已经被标记为过时,建议改用HttpClient,它更高效且支持异步操作:
    private static readonly HttpClient _httpClient = new HttpClient();
    public static async Task<string> GetJsonAsync() { 
        string titleOfDesiredMovie = Console.ReadLine(); 
        string url = $"http://www.omdbapi.com/?t={Uri.EscapeDataString(titleOfDesiredMovie)}&apikey=SECRETKEY";
        string json = await _httpClient.GetStringAsync(url); 
        return json; 
    }
    
    记得把Main方法改成async Task Main来支持异步。
  • 不要硬编码API密钥:把API密钥放到配置文件(比如appsettings.json)里,避免泄露和方便修改。
  • 添加错误处理:比如处理网络请求失败、JSON反序列化失败、属性不存在等情况,让程序更健壮。

内容的提问来源于stack exchange,提问作者Hristo Bakardzhiev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:42:25