C# ASP.NEt MVC使用Web API返回Razor视图

C# ASP.NEt MVC使用Web API返回Razor视图,c#,html,asp.net-mvc,razor,asp.net-web-api,C#,Html,Asp.net Mvc,Razor,Asp.net Web Api,如何使控制器返回并由Razor生成的视图从api获取数据我想保留Razor引擎视图并使用api 原始的mvc控制器返回带有数据作为参数的视图,现在我想要api中的数据 MVC控制器 public class ProductController : Controller { public ActionResult Index() { return View(); } Api控制器 public class ProductsController : ApiC

如何使控制器返回并由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;
    }
}
公共类产品控制器:ApiController
{
私有ApplicationDbContext db=新ApplicationDbContext();
//获取api/产品
公共IEnumerable GetProducts()
{
返回数据库产品;
}
}
型号:

@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>
@model IEnumerable
@{
ViewBag.Title=“Index”;
}
指数

@ActionLink(“新建”、“创建”)

@DisplayNameFor(model=>model.Name) @DisplayNameFor(model=>model.Category) @DisplayNameFor(model=>model.Price) @foreach(模型中的var项目){ @DisplayFor(modelItem=>item.Name) @DisplayFor(modelItem=>item.Category) @DisplayFor(modelItem=>item.Price) @ActionLink(“编辑”,“编辑”,新的{id=item.id})| @ActionLink(“详细信息”,“详细信息”,新的{id=item.id})| @ActionLink(“删除”,“删除”,新的{id=item.id}) }
您可以从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);
    }
}
公共类ProductController:控制器
{
公共行动结果索引()
{
var client=新的HttpClient();
var response=client.GetAsync(“http://yourapi.com/api/products三、结果;
var products=response.Content.ReadAsAsync().Result;
返回视图(产品);
}
}
此外,如果您可以利用.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);
    }
}
公共类ProductController:控制器
{
公共异步任务索引()
{
var client=新的HttpClient();
var response=wait client.GetAsync(“http://yourapi.com/api/products");
var products=wait response.Content.ReadAsAsync();
返回视图(产品);
}
}

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

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

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);
    }
}
公共类TestHttpActionResult:IHttpActionResult
{
私有只读HttpRequestMessage\u请求;
私有只读字符串_responseString;
公共测试HttpActionResult(HttpRequestMessage请求、字符串响应)
{
_请求=请求;
_responseString=responseString;
}
公共任务执行同步(CancellationToken CancellationToken)
{
var response=\u request.CreateResponse(HttpStatusCode.Created);
response.Content=新字符串内容(\u responseString);
response.Content.Headers.ContentType=新的MediaTypeHeaderValue(“文本/普通”);
返回Task.FromResult(响应);
}
}

我创建了一个html客户端,它使用url/api/产品调用api,但(“)有一个问题我到底应该在这里放什么?你应该把返回产品列表的Web API端点的url放在这里。谢谢!!我可以用@url.Action替换url吗?这取决于Web API是否与你的ASP.NET MVC应用程序托管在同一个ASP.NET主机上。否则,你不能指望客户端应用程序知道任何有关Web API的信息在服务器端配置的路由。如果两个应用程序托管在同一主机上,则可以使用
RouteUrl
helper:
string productsUrl=Url.RouteUrl(“DefaultApi”,new{httproute=”“,controller=“products”})
。开始使用负载平衡器或反向代理时要小心,因为它们被分配了
yourapi.com
DNS名称,并且具有阻止来自单个客户端的过多请求的特定规则,或者在重写请求等时(SSL卸载就是这样一个例子)。在这种情况下,还要注意网络往返对性能的影响。感谢有用的链接。你的答案肯定比从MVC到API控制器的HTTP请求更好。我不知道为什么这个答案有这么多的向上投票,但从性能角度看,这样做是毫无意义的。我正在进行一个项目,学习m,V,我相信你标记的“模型:”应该改为“视图”。本例中的模型只是控制器生成的模型、产品对象的列表。