Reputation: 5
public class ProductViewModel
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public int price { get; set; }
public double discountPercentage { get; set; }
public double rating { get; set; }
public int stock { get; set; }
public string brand { get; set; }
public string category { get; set; }
public string thumbnail { get; set; }
public List<string> images { get; set; }
}
public class RootViewModel
{
public ProductViewModel[] Products { get; set; }
public int total { get; set; }
public int skip { get; set; }
public int limit { get; set; }
}
public class WebProductClient : IWebProductClient
{
private readonly RestClient _client;
private readonly string _url;
public WebProductClient()
{
_url = "https://local/host:7123/";
var options = new RestClientOptions(_url);
_client = new RestClient(options);
}
public async Task<ProductViewModel> GetAllProduct()
{
var request = new RestRequest("Api/Products");
var response = await _client.ExecuteGetAsync(request);
var r = JsonConvert.DeserializeObject<ProductViewModel>(response.Content);
return r;
}
}
ProductsController:
public IActionResult Index()
{
var all = _client.GetAllProduct();
return View(all);
}
Index:
@model IEnumerable<DummyShop.Service.ViewModel.ProductViewModel>
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.id)
</th>
<th>
@Html.DisplayNameFor(model => model.title)
</th>
<th>
@Html.DisplayNameFor(model => model.description)
</th>
<th>
@Html.DisplayNameFor(model => model.price)
</th>
<th>
@Html.DisplayNameFor(model => model.discountPercentage)
</th>
<th>
@Html.DisplayNameFor(model => model.rating)
</th>
<th>
@Html.DisplayNameFor(model => model.stock)
</th>
<th>
@Html.DisplayNameFor(model => model.brand)
</th>
<th>
@Html.DisplayNameFor(model => model.category)
</th>
<th>
@Html.DisplayNameFor(model => model.thumbnail)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.id)
</td>
<td>
@Html.DisplayFor(modelItem => item.title)
</td>
<td>
@Html.DisplayFor(modelItem => item.description)
</td>
<td>
@Html.DisplayFor(modelItem => item.price)
</td>
<td>
@Html.DisplayFor(modelItem => item.discountPercentage)
</td>
<td>
@Html.DisplayFor(modelItem => item.rating)
</td>
<td>
@Html.DisplayFor(modelItem => item.stock)
</td>
<td>
@Html.DisplayFor(modelItem => item.brand)
</td>
<td>
@Html.DisplayFor(modelItem => item.category)
</td>
<td>
@Html.DisplayFor(modelItem => item.thumbnail)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</tbody>
</table>
Returned data from my API:
{
"products": [
{
"id": 1,
"title": "iPhone 9",
"description": "An apple mobile which is nothing like apple",
"price": 549,
"discountPercentage": 12.96,
"rating": 4.69,
"stock": 94,
"brand": "Apple",
"category": "smartphones",
"thumbnail": "://i.dummyjson./data/products/1/thumbnail./jpg",
"images": [
"://i.dummyjson./data/products/1/1./",
"://i.dummyjson./data/products/1/2./",
"://i.dummyjson./data/products/1/3./",
"://i.dummyjson./data/products/1/4./",
"://i.dummyjson./data/products/1/thumbnail./"
]
},
{
"id": 2,
"title": "iPhone X",
"description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...",
"price": 899,
"discountPercentage": 17.94,
"rating": 4.44,
"stock": 34,
"brand": "Apple",
"category": "smartphones",
"thumbnail": "://i.dummyjson/data/products/2/thumbnail.",
"images": [
"://i.dummyjson/data/products/2/1.",
"://i.dummyjson/data/products/2/2.",
"://i.dummyjson/data/products/2/3.",
"://i.dummyjson/data/products/2/thumbnail."
]
},
],
"total": 100,
"skip": 0,
"limit": 30
}
The error I got:
System.Collections.Generic.IEnumerable
1[DummyShop.Service.ViewModel.ProductViewModel].An unhandled exception occurred while processing the request. InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder
1+AsyncStateMachineBox`1[DummyShop.Service.ViewModel.ProductViewModel,DummyShop.Service.ProductClientsWEB.WebProductClient+d__5]', but this ViewDataDictionary instance requires a model item of type
Upvotes: 0
Views: 518
Reputation: 51240
RootViewModel
type. You deserialize the response.Content
as RootViewModel
type.public async Task<RootViewModel> GetAllProduct()
{
var request = new RestRequest("Api/Products");
var response = await _client.ExecuteGetAsync(request);
var r = JsonConvert.DeserializeObject<RootViewModel>(response.Content);
return r;
}
JsonPropertyName
attribute to match the property name in the JSON. Same goes for the other properties, you should name the properties as "Pascal Casing" instead of "camel Case".public class RootViewModel
{
[JsonPropertyName("products")]
public ProductViewModel[] Products { get; set; }
...
}
RootViewModel
value from the controller, modify the ViewModel as RootViewModel
. And enumerate with @Model.Products
for the <thead>
and <tr>
elements.@model RootViewModel
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Products[0].id)
</th>
<th>
@Html.DisplayNameFor(model => model.Products[0].title)
</th>
<th>
@Html.DisplayNameFor(model => model.Products[0].description)
</th>
<th>
@Html.DisplayNameFor(model => model.Products[0].price)
</th>
<th>
@Html.DisplayNameFor(model => model.Products[0].discountPercentage)
</th>
<th>
@Html.DisplayNameFor(model => model.Products[0].rating)
</th>
<th>
@Html.DisplayNameFor(model => model.Products[0].stock)
</th>
<th>
@Html.DisplayNameFor(model => model.Products[0].brand)
</th>
<th>
@Html.DisplayNameFor(model => model.Products[0].category)
</th>
<th>
@Html.DisplayNameFor(model => model.Products[0].thumbnail)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Products)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.id)
</td>
<!-- Following td elements -->
</tr>
}
</tbody>
</table>
Task<IActionResult>
and it is an async
method.public async Task<IActionResult> Index()
{
var all = await _client.GetAllProduct();
return View(all);
}
Upvotes: 1