MVC 中与 ASP.NET WebAPI 和 httpClient 一起使用的做法是什么,当使用异步调用来获取模型时



故事:

我制作了一个WebAPI来获取各种信息。我被告知,好的做法是作为前端开发人员,只需通过服务/API向后端发送信息请求,并使用async和await关键字等。

这就是我想做的:

在我的家里控制器我有这个:

namespace NHibernateMVC.Controllers
{
public class HomeController : Controller
{
static HttpClient client = new HttpClient();
static async Task RunAsync()
{
// New code:
client.BaseAddress = new Uri("http://localhost:64498/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
static async Task<IEnumerable<Article>> GetArticleAsync(string path)
{
IEnumerable<Article> art = null;
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
art = await response.Content.ReadAsAsync<IEnumerable<Article>>();
}
return art;
}
public ActionResult Index()
{   
// This is where I am supposed to make a call to get the Articles to return a View who's model is of type IEnumerable<Article>
}

底线是我想用IEnumerable<Article>模型初始化索引页面,但使用 httpClient 获取文章,调用 WebAPI(这只是对 api/ArticleAPI 的 GET 请求,JSON 是一个响应(。 在实践中通常如何做到这一点?这是我第一次这样做,我确实需要帮助,并且已经搜索了一下,到目前为止没有发现任何可以帮助我的东西......

控制器需要重构一点,以便可以正确调用它

public class HomeController : Controller {
const string ARTICLE_API_PATH = "api/ArticleAPI";
static HttpClient client; = new HttpClient();
static HomeController() {
// New code:
client.BaseAddress = new Uri("http://localhost:64498/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
async Task<IEnumerable<Article>> GetArticleAsync() {
IEnumerable<Article> articles = new List<Article>();
HttpResponseMessage response = await client.GetAsync(ARTICLE_API_PATH);
if (response.IsSuccessStatusCode) {
articles = await response.Content.ReadAsAsync<List<Article>>();
}
return articles;
}
public async Task<ActionResult> Index() {
//call service method above.
var articles = await GetArticleAsync();
//pass the list as the model to the view
return View(articles);
}
}

以上内容可以作为一个开始,但也可以改进可维护性。

获取文章可以提取到服务抽象中

public interface IArticleService {
Task<IEnumerable<Article>> GetArticleAsync();
}
public class ArticleService : IArticleService {
const string ARTICLE_API_PATH = "api/ArticleAPI";
static HttpClient client; = new HttpClient();
static ArticleService() {
client.BaseAddress = new Uri("http://localhost:64498/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<IEnumerable<Article>> GetArticleAsync() {
IEnumerable<Article> articles = new List<Article>();
HttpResponseMessage response = await client.GetAsync(ARTICLE_API_PATH);
if (response.IsSuccessStatusCode) {
articles = await response.Content.ReadAsAsync<List<Article>>();
}
return articles;
}
}

这样现在控制器可以简化为

public class HomeController : Controller {
private readonly IArticleService articleService;
public HomeController() {
articleService = new ArticleService();
}
public async Task<ActionResult> Index() {
//call service method above.
var articles = await articleService.GetArticleAsync();
//pass the list as the model to the view
return View(articles);
}
}

在更高级的方案中,可以通过将服务注入控制器来反转服务的创建,但该主题不在此问题的讨论范围之内。

它看起来像这样。

public class HomeController : Controller {
private readonly IArticleService articleService;
public HomeController(IArticleService articleService) {
this.articleService = articleService;
}
public async Task<ActionResult> Index() {
//call service method above.
var articles = await articleService.GetArticleAsync();
//pass the list as the model to the view
return View(articles);
}
}

最新更新