Отображение стандартных данных в MVC
Возможно, это просто совершенно неправильно, но во времена Webforms вы возвращаете набор данных, который затем привязываете к сетке. Но теперь в MVC вы не должны передавать данные, потому что вы не можете его сериализовать и технически передавать объекты в представление, где оно не принадлежит? Но как я собираюсь отображать данные на виду?! Я не могу использовать классы LINQ to SQL здесь, так как это чистая структура данных в памяти.
В идеале я просто хотел бы иметь объект, который я могу повторить в представлении.
Я действительно немного потерял, я прочитал статью из "Гу" , и я могу только подвести итог, что у меня есть вместо этого вернуть объект ViewData? Я здесь схожу?
Приветствия от Blighty
Джон
Ответы
Ответ 1
Это вовсе не "неправильно", это просто не то, что крутые ребята обычно делают с MVC. В стороне, я хочу, чтобы некоторые из ранних демоверсий ASP.NET MVC не пытались втиснуть в Linq-to-Sql одновременно. Это довольно удивительно и хорошо подходит для MVC, конечно, но это не требуется. В MVC нет ничего, что бы мешало вам использовать ADO.NET. Например:
Действие контроллера:
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
DataTable dt = new DataTable("MyTable");
dt.Columns.Add(new DataColumn("Col1", typeof(string)));
dt.Columns.Add(new DataColumn("Col2", typeof(string)));
dt.Columns.Add(new DataColumn("Col3", typeof(string)));
for (int i = 0; i < 3; i++)
{
DataRow row = dt.NewRow();
row["Col1"] = "col 1, row " + i;
row["Col2"] = "col 2, row " + i;
row["Col3"] = "col 3, row " + i;
dt.Rows.Add(row);
}
return View(dt); //passing the DataTable as my Model
}
Вид: (с моделью, строго типизированной как System.Data.DataTable)
<table border="1">
<thead>
<tr>
<%foreach (System.Data.DataColumn col in Model.Columns) { %>
<th><%=col.Caption %></th>
<%} %>
</tr>
</thead>
<tbody>
<% foreach(System.Data.DataRow row in Model.Rows) { %>
<tr>
<% foreach (var cell in row.ItemArray) {%>
<td><%=cell.ToString() %></td>
<%} %>
</tr>
<%} %>
</tbody>
</table>
Теперь я нарушаю множество принципов и "лучших практик" ASP.NET MVC здесь, поэтому, пожалуйста, поймите, это просто демонстрация. Код, создающий DataTable, должен находиться где-то вне контроллера, а код в представлении может быть лучше изолирован от частичного или html-помощника, чтобы назвать несколько способов, которыми вы должны что-то делать.
Вы абсолютно должны передавать объекты в представление, если представление должно представить их. (Разделение соображений диктует, что представление не должно отвечать за их создание.) В этом случае я передал DataTable как фактическую модель представления, но вы могли бы просто поместить ее в коллекцию ViewData. В качестве альтернативы вы можете создать определенный класс IndexViewModel, содержащий DataTable и другие объекты, такие как приветственное сообщение.
Надеюсь, это поможет!
Ответ 2
Вот ответ в синтаксисе Razor
<table border="1" cellpadding="5">
<thead>
<tr>
@foreach (System.Data.DataColumn col in Model.Columns)
{
<th>@col.Caption</th>
}
</tr>
</thead>
<tbody>
@foreach(System.Data.DataRow row in Model.Rows)
{
<tr>
@foreach (var cell in row.ItemArray)
{
<td>@cell.ToString()</td>
}
</tr>
}
</tbody>
</table>
Ответ 3
Пока я пробовал этот подход выше, он становится полной катастрофой с mvc. Ваш контроллер, передающий модель и ваш взгляд с использованием сильно типизированной модели, становится слишком трудным для работы.
Получите ваш набор данных в список.....
У меня есть шаблон репозитория, и вот пример получения набора данных из старой школы asmx web-сервиса
private readonly CISOnlineSRVDEV.ServiceSoapClient _ServiceSoapClient;
public Get_Client_Repository()
: this(new CISOnlineSRVDEV.ServiceSoapClient())
{
}
public Get_Client_Repository(CISOnlineSRVDEV.ServiceSoapClient serviceSoapClient)
{
_ServiceSoapClient = serviceSoapClient;
}
public IEnumerable<IClient> GetClient(IClient client)
{
// **** Calling teh web service with passing in the clientId and returning a dataset
DataSet dataSet = _ServiceSoapClient.get_clients(client.RbhaId,
client.ClientId,
client.AhcccsId,
client.LastName,
client.FirstName,
"");//client.BirthDate.ToString()); //TODO: NEED TO FIX
// USE LINQ to go through the dataset to make it easily available for the Model to display on the View page
List<IClient> clients = (from c in dataSet.Tables[0].AsEnumerable()
select new Client()
{
RbhaId = c[5].ToString(),
ClientId = c[2].ToString(),
AhcccsId = c[6].ToString(),
LastName = c[0].ToString(), // Add another field called Sex M/F c[4]
FirstName = c[1].ToString(),
BirthDate = c[3].ToDateTime() //extension helper ToDateTime()
}).ToList<IClient>();
return clients;
}
Затем в контроллере я делаю это
IClient client = (IClient)TempData["Client"];
// Instantiate and instance of the repository
var repository = new Get_Client_Repository();
// Set a model object to return the dynamic list from repository method call passing in the parameter data
var model = repository.GetClient(client);
// Call the View up passing in the data from the list
return View(model);
Тогда в представлении это легко:
@model IEnumerable<CISOnlineMVC.DAL.IClient>
@{
ViewBag.Title = "CLIENT ALL INFORMATION";
}
<h2>CLIENT ALL INFORMATION</h2>
<table>
<tr>
<th></th>
<th>Last Name</th>
<th>First Name</th>
<th>Client ID</th>
<th>DOB</th>
<th>Gender</th>
<th>RBHA ID</th>
<th>AHCCCS ID</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.ActionLink("Select", "ClientDetails", "Cis", new { id = item.ClientId }, null) |
</td>
<td>
@item.LastName
</td>
<td>
@item.FirstName
</td>
<td>
@item.ClientId
</td>
<td>
@item.BirthDate
</td>
<td>
Gender @* ADD in*@
</td>
<td>
@item.RbhaId
</td>
<td>
@item.AhcccsId
</td>
</tr>
}
</table>