故事:
我已经制作了一个WebAPI来获取各种信息。我被告知,良好的做法是作为前端开发人员,只需通过服务/ API向后端发送信息请求,并使用async和等待关键字等。
这就是我想要做的事情:
在我的homeController中我有这个:
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>
模型初始化Index页面,但是使用httpClient获取文章,调用WebAPI(这只是对api / ArticleAPI的GET请求,JSON是一个回应)。
这通常是如何在实践中完成的?这是我第一次这样做,我确实需要帮助,并且搜索了一下,发现到目前为止没有任何可以帮助我...
答案 0 :(得分:1)
控制器需要稍微重构才能正确调用
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);
}
}