为了账号安全,请及时绑定邮箱和手机立即绑定

ASP.NET - 模型对象列表的 API Url

ASP.NET - 模型对象列表的 API Url

C#
眼眸繁星 2023-09-24 16:06:21
目前我正在通过 jQuery 进行 API 调用,我的问题是,是否可以在 C# 中执行此调用,或者将 API 调用的结果转换为 ASP.NET 模型对象列表?这是我的模型public class TeamStatsClass{        public int id { get; set; }        public string name { get; set; }        public string league { get; set; }        public string division { get; set; }}这是我当前的 ajax 调用$.ajax({        url: "https://statsapi.web.nhl.com/api/v1/teams?sportId=1",        success: function (data) {            for (var team of data.teams) {                console.log(team.name);            }        }    });更新我将我的课程更改为如下所示:public class StatsTeamsClass    {        public IEnumerable<Teams> teams { get; set; }        public string copyright { get; set; }    }    public class Division    {        public int id { get; set; }        public string name { get; set; }        public string link { get; set; }    }    public class Teams    {        public int id { get; set; }        public string name { get; set; }        public string link { get; set; }        public League league { get; set; }        public Division division { get; set; }    }并创建了这个方法,它确实将结果放入模型对象中:public async System.Threading.Tasks.Task<StatsTeamsClass> GetTeams(){            HttpClient Http = new HttpClient();            var json = await Http.GetStringAsync("https://statsapi.web.nhl.com/api/v1/teams?sportId=1");            StatsTeamsClass teams = JsonConvert.DeserializeObject<StatsTeamsClass>(json);            return teams;}但是当我尝试在另一个控制器中调用这个方法时,它只是挂在那里,没有错误,什么也没有,我假设它会在一段时间后超时public class HomeController : Controller{        APIController webService = new APIController();        public ActionResult Index()        {            var item = webService.GetTeams().Result.teams;            return View();        }}(GetTeams() 位于控制器 APIController 内部)那么 A. 在对象模型中获取 API 结果然后调用这些结果的正确方法是什么?
查看完整描述

3 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

控制器操作也需要异步,以避免混合异步等待和阻塞调用,例如.Result.Wait()可能导致死锁。


public class HomeController : Controller {    

    APIController webService = new APIController();


    public async Task<ActionResult> Index() {    

        var model = await webService.GetTeams();

        var teams = model.teams;

        return View();

    }

}

假设APIController是一个实际的ApiContoller


public class APIController : ApiController {


    //Your original code

    public async Task<StatsTeamsClass> GetTeams() {        

        HttpClient Http = new HttpClient();

        var json = await Http.GetStringAsync("https://statsapi.web.nhl.com/api/v1/teams?sportId=1");

        StatsTeamsClass teams = JsonConvert.DeserializeObject<StatsTeamsClass>(json);

        return teams;

    }


    //...

}

我建议不要APIController像这样直接调用HomeController,而是将GetTeams()方法提取到可重用的服务中


public class WebService {

    static Lazy<HttpClient> http = new Lazy<HttpClient>();


    public async Task<T> GetAsync<T>(string url) {        

        var json = await http.Value.GetStringAsync(url);

        return JsonConvert.DeserializeObject<T>(json);

    }


    public Task<StatsTeamsClass> GetTeamsAsync() {        

        var url = "https://statsapi.web.nhl.com/api/v1/teams?sportId=1";

        return GetAsync<StatsTeamsClass>(url);

    }

}

参考您使用 HttpClient 错误


可以正确地用于HomeController


public class HomeController : Controller {        

    public async Task<ActionResult> Index() {

        // Ideally web service should be injected but that topic

        // is outside of the scope of the question at the moment.

        var webService = new WebService();


        var model = await webService.GetTeamsAsync();

        var teams = model.teams;


        //...


        return View(teams);

    }

}

这里的假设是该项目是一个混合的 Asp.Net MVC 和 Web Api 2+


索引.cshtml


@model IEnumerable<Teams>

@{

    ViewBag.Title = "Teams";

}

@if(Model != null && Model.Count() > 0) {

    @foreach (var @team in Model) {

        <p>@team.name</p>

    }

}


查看完整回答
反对 回复 2023-09-24
?
慕容708150

TA贡献1831条经验 获得超4个赞

是的,C# 中的等效方法是使用HttpClient. 您最好创建一个类的静态实例,以便为特定类型的重复调用重用:

private static readonly HttpClient Http = new HttpClient();

然后通过async使用Newtonsoft.Json 的方法使用它,如下所示:

var json = await Http.GetStringAsync("https://statsapi.web.nhl.com/api/v1/teams?sportId=1");

然后,您可以将此 JSON 字符串解析为模型类,如下所示:

var model = JsonConvert.DeserializeObject<TeamStatsClass>(json);


查看完整回答
反对 回复 2023-09-24
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

只是想在此处添加更多点您获得的 json 无法直接转换为 TeamStatsClass 您可能必须引入另一个基类,因为团队是您获得的 json 中的集合。


我将其发布在这里以获得更清晰的视图


    public class ResponseBaseClass

    {

        public IEnumerable<TeamStatsClass> teams { get; set; }

        public string copyright { get; set; }

    }

    public class TeamStatsClass

    {

        public int id { get; set; }

        public string name { get; set; }

        public Division division { get; set; }

    }

    public class Division

    {

        public int id { get; set; }

        public string name { get; set; }

        public string nameShort { get; set; }

        public string link { get; set; }


    }


 HttpClient Http = new HttpClient();

 var json = await Http.GetStringAsync("https://statsapi.web.nhl.com/api/v1/teams?sportId=1");

 var model = JsonConvert.DeserializeObject<ResponseBaseClass>(json);

 var yourTeamModelObj = model.teams;


查看完整回答
反对 回复 2023-09-24
  • 3 回答
  • 0 关注
  • 71 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信