【问题标题】:ASP.NEt MVC using Web API to return a Razor viewASP.NEt MVC 使用 Web API 返回 Razor 视图
【发布时间】:2014-04-04 12:06:45
【问题描述】:

如何让控制器返回并由 Razor 生成的视图从 api 获取数据我想保留 razor 引擎视图并使用 api 原来的 mvc 控制器以数据作为参数返回视图,现在我想要来自 api 的数据

MVC 控制器

public class ProductController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

API 控制器

public class ProductsController : ApiController
{
    private ApplicationDbContext db = new ApplicationDbContext();

    // GET api/Products
    public IEnumerable<Product> GetProducts()
    {
        return db.Products;
    }
}

型号:

@model IEnumerable<WebApplication2.Models.Product>

@{
ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
    <th>
        @Html.DisplayNameFor(model => model.Name)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Category)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Price)
    </th>
    <th></th>
</tr>

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Name)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Category)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Price)
    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
        @Html.ActionLink("Details", "Details", new { id=item.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.Id })
    </td>
</tr>
}
</table>

【问题讨论】:

  • 我正在一个项目中学习 Razor 中 M、V 和 C 的角色。我相信您标记为“模型:”的内容应该标记为视图。此示例中的模型只是控制器生成的 Models.Product 对象的列表。

标签: c# html asp.net-mvc razor asp.net-web-api


【解决方案1】:

您可以从 ASP.NET MVC 控制器中向您的 Web API 控制器发送 HTTP 请求:

public class ProductController : Controller
{
    public ActionResult Index()
    {
        var client = new HttpClient();
        var response = client.GetAsync("http://yourapi.com/api/products").Result;
        var products = response.Content.ReadAsAsync<IEnumerable<Product>>().Result;
        return View(products);
    }
}

此外,如果您可以利用 .NET 4.5 async/await,强烈建议您这样做以避免阻塞调用:

public class ProductController : Controller
{
    public async Task<ActionResult> Index()
    {
        var client = new HttpClient();
        var response = await client.GetAsync("http://yourapi.com/api/products");
        var products = await response.Content.ReadAsAsync<IEnumerable<Product>>();
        return View(products);
    }
}

【讨论】:

  • 我创建了一个 html 客户端,它使用 url /api/products 调用 api 它可以工作,但是 ("yourapi.com/api/products") 有问题,我应该把什么放在这里??
  • 你应该把你的 Web API 端点的 url 返回产品列表。
  • 谢谢!!我可以用@Url.Action 替换网址吗??
  • 这取决于 Web API 是否托管在与您的 ASP.NET MVC 应用程序相同的 ASP.NET 主机中。否则,您不能期望客户端应用程序知道有关在服务器端配置的路由的任何信息。如果两个应用程序都托管在同一主机上,您可以使用 RouteUrl 助手:string productsUrl = Url.RouteUrl("DefaultApi", new { httproute = "", controller = "products" });
  • 当您开始使用负载均衡器或反向代理时要小心,这些负载均衡器或反向代理分配了 yourapi.com DNS 名称,并且具有特定规则来阻止来自单个客户端的过多请求或重写请求等(SSL卸载就是这样一个例子)。在这种情况下,还要注意网络往返对性能的影响。
【解决方案2】:

阅读here,了解如何在 Web API 控制器中使用 Razor 视图引擎。有趣的部分是使用RazorEngine NuGet package 来完成繁重的工作。

【讨论】:

  • 感谢您提供有用的链接。
  • 您的答案绝对比从 MVC 到 API 控制器的 HTTP 请求更好。我不知道为什么这个答案有这么多的赞成票,但从表现来看,这样做是无稽之谈。
【解决方案3】:

twoflower 提供的链接的基础是让您的处理程序创建并返回自定义 IHttpActionResult 实现的实例。一个简化的例子如下所示:

public class TestHttpActionResult : IHttpActionResult
{
    private readonly HttpRequestMessage _request;
    private readonly string _responseString;

    public TestHttpActionResult(HttpRequestMessage request, string responseString)
    {
        _request = request;
        _responseString = responseString;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = _request.CreateResponse(HttpStatusCode.Created);
        response.Content = new StringContent(_responseString);
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
        return Task.FromResult(response);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 2018-04-08
    相关资源
    最近更新 更多