如何将WebService XML响应转列表,在MVC中返回城市列表ActionResult
我来一步步帮你解决这个问题,从模型创建到最终在MVC视图里展示,全程给你清晰的代码示例:
1. 创建对应XML结构的模型类
首先,我们需要一个和XML里的<cidade>节点匹配的C#类,这样才能把XML数据映射成对象列表。这里要用到System.Xml.Serialization命名空间的特性来对应XML节点名称:
using System.Xml.Serialization; [XmlRoot("cidades")] public class CityList { [XmlElement("cidade")] public List<City> Cities { get; set; } } public class City { [XmlElement("nome")] public string Name { get; set; } [XmlElement("uf")] public string State { get; set; } [XmlElement("id")] public int Id { get; set; } }
简单解释:[XmlRoot("cidades")]对应最外层的XML根节点,[XmlElement("cidade")]把每个<cidade>节点映射到City对象,最终收集到Cities列表里。
2. 实现XML解析与数据获取逻辑
接下来我们写一个方法,用来请求WebService的XML数据,再把它解析成List<City>。这里提供两种常用的方式,你可以根据需求选择:
方式一:使用XmlSerializer(序列化方式)
这种方式简洁高效,适合结构固定的XML:
using System.Net.Http; using System.Xml.Serialization; public async Task<List<City>> GetCitiesFromWebService() { var url = "http://servicos.cptec.inpe.br/XML/listaCidades"; using var httpClient = new HttpClient(); // 获取XML流 var stream = await httpClient.GetStreamAsync(url); // 反序列化为CityList对象 var serializer = new XmlSerializer(typeof(CityList)); var cityList = (CityList)serializer.Deserialize(stream); return cityList?.Cities ?? new List<City>(); }
方式二:使用XDocument(手动解析方式)
如果需要更灵活的XML处理(比如过滤特定节点、自定义字段转换),可以用System.Xml.Linq的XDocument:
using System.Net.Http; using System.Xml.Linq; public async Task<List<City>> GetCitiesFromWebService() { var url = "http://servicos.cptec.inpe.br/XML/listaCidades"; using var httpClient = new HttpClient(); var xmlString = await httpClient.GetStringAsync(url); var xDoc = XDocument.Parse(xmlString); // 遍历所有<cidade>节点,转换为City对象 var cities = xDoc.Descendants("cidade") .Select(node => new City { Name = node.Element("nome")?.Value, State = node.Element("uf")?.Value, Id = int.TryParse(node.Element("id")?.Value, out var id) ? id : 0 }) .ToList(); return cities; }
3. 在MVC Controller中实现Action
现在把上面的方法集成到Controller里,创建一个Action来获取城市列表并传递给视图:
using Microsoft.AspNetCore.Mvc; // ASP.NET Core MVC使用这个命名空间 // 如果是传统ASP.NET MVC,替换为using System.Web.Mvc; public class CityController : Controller { public async Task<IActionResult> Index() { try { var cities = await GetCitiesFromWebService(); return View(cities); } catch (Exception ex) { // 这里可以添加错误日志记录,或者返回错误提示 ViewBag.ErrorMessage = $"获取城市列表失败:{ex.Message}"; return View(new List<City>()); } } // 把前面写的GetCitiesFromWebService方法放在这里,或者抽离到单独的服务类中 private async Task<List<City>> GetCitiesFromWebService() { // 复制前面任一解析方式的代码即可 } }
4. 创建视图展示城市列表
最后创建对应的Index视图(Views/City/Index.cshtml),接收List<City>模型,用表格清晰展示数据:
@model List<City> @{ ViewBag.Title = "巴西城市列表"; } <h1>城市列表</h1> @if (!string.IsNullOrEmpty(ViewBag.ErrorMessage)) { <div class="alert alert-danger">@ViewBag.ErrorMessage</div> } <table class="table table-striped"> <thead> <tr> <th>ID</th> <th>城市名称</th> <th>州</th> </tr> </thead> <tbody> @foreach (var city in Model) { <tr> <td>@city.Id</td> <td>@city.Name</td> <td>@city.State</td> </tr> } </tbody> </table>
额外小提示
- 推荐把数据获取逻辑抽离到单独的服务类(比如
CityService),让Controller更简洁,符合单一职责原则。 - 记得在项目中添加对应的命名空间引用,比如
System.Xml.Serialization、System.Net.Http等。 - 如果是传统ASP.NET MVC,
HttpClient的使用需要注意生命周期,也可以用WebClient替代,但更推荐使用HttpClient。
内容的提问来源于stack exchange,提问作者Arthuro Verissimo
相关产品推荐
相关产品推荐

