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

use*_*331 3 c# asp.net ajax jquery curl

目前,我正在通过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; }
}
Run Code Online (Sandbox Code Playgroud)

这是我当前的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);

            }

        }
    });
Run Code Online (Sandbox Code Playgroud)

更新

我将类更改为:

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; }
    }
Run Code Online (Sandbox Code Playgroud)

并创建了此方法,该方法的确将结果放入模型对象中:

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;
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试在另一个控制器中调用此方法时,它只是挂在那儿,没有错误,什么也没有,我假设它会在一段时间后超时

public class HomeController : Controller
{

        APIController webService = new APIController();

        public ActionResult Index()
        {

            var item = webService.GetTeams().Result.teams;

            return View();
        }
}
Run Code Online (Sandbox Code Playgroud)

(GetTeams()在控制器APIController内部)

那么,A。在对象模型中获取API结果然后调用这些结果的正确方法是什么?

Nko*_*osi 7

还需要使控制器动作异步,以避免混淆异步等待和阻塞类似.Result.Wait()可能导致死锁的调用。

参考Async / Await-异步编程最佳实践

public class HomeController : Controller {    
    APIController webService = new APIController();

    public async Task<ActionResult> Index() {    
        var model = await webService.GetTeams();
        var teams = model.teams;
        return View();
    }
}
Run Code Online (Sandbox Code Playgroud)

假设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;
    }

    //...
}
Run Code Online (Sandbox Code Playgroud)

我建议不要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);
    }
}
Run Code Online (Sandbox Code Playgroud)

参考您使用的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Index.cshtml

@model IEnumerable<Teams>
@{
    ViewBag.Title = "Teams";
}
@if(Model != null && Model.Count() > 0) {
    @foreach (var @team in Model) {
        <p>@team.name</p>
    }
}
Run Code Online (Sandbox Code Playgroud)