Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NEt MVC using Web API to return a Razor view

How to make the View returned by the controller and generated by Razor get the data from the api i want to keep the razor engine view and use the api the original mvc controller returns the view with the data as parameter now i want the data from the api

MVC controller

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

Api Controller

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

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

Model:

@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>
like image 513
user3353484 Avatar asked Mar 03 '14 12:03

user3353484


People also ask

How do I return a rendered Razor view from Web API controller?

ASP.NET MVC4 Web API controller should return Razor view as html in json result property. Message=The method or operation is not implemented. var viewResult = ViewEngines.

Can Web API return view in MVC?

You can return one or the other, not both. Frankly, a WebAPI controller returns nothing but data, never a view page. A MVC controller returns view pages. Yes, your MVC code can be a consumer of a WebAPI, but not the other way around.

How do I return a view from ASP Net Web API?

So, if you want to return a View you need to use the simple ol' Controller . The WebApi "way" is like a webservice where you exchange data with another service (returning JSON or XML to that service, not a View). So whenever you want to return a webpage ( View ) for a user you don't use the Web API.


3 Answers

You could send an HTTP request to your Web API controller from within the ASP.NET MVC controller:

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);
    }
}

Also if you can take advantage of the .NET 4.5 async/await it is strongly recommended to do so to avoid blocking calls:

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);
    }
}
like image 138
Darin Dimitrov Avatar answered Oct 21 '22 11:10

Darin Dimitrov


Read here on how to use the Razor view engine inside your Web API controller. The interesting part is using the RazorEngine NuGet package to do the heavy lifting.

like image 28
twoflower Avatar answered Oct 21 '22 10:10

twoflower


The basis of the link supplied by twoflower is to have your handlers create and return an instance of a custom IHttpActionResult implementation. A simplified example is shown below:

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);
    }
}
like image 22
andrew pate Avatar answered Oct 21 '22 10:10

andrew pate