Отображение стандартных таблиц данных в MVC - PullRequest
41 голосов
/ 11 февраля 2010

Возможно, это совершенно неправильно, но во времена Webforms вы возвращали набор данных, который затем связывали бы с сеткой. Но теперь в MVC вы не должны передавать таблицу данных, потому что не можете сериализовать ее, и она технически передает объекты в View, где он не принадлежит? Но как же я должен отображать данные в виде ?! Здесь я не могу использовать классы LINQ to SQL, так как это чисто структура данных в памяти.

В идеале мне бы хотелось иметь объект, который я могу перебирать в представлении.

Я действительно в растерянности. Я прочитал статью из "Гу" , и я могу только резюмировать, что мне нужно вместо этого вернуть объект ViewData ?? Я схожу с ума здесь?

Приветствия от Blighty

Jon

Ответы [ 3 ]

69 голосов
/ 11 февраля 2010

Это вовсе не «неправильно», это просто не то, что классные парни обычно делают с 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 и другие объекты, такие как приветственное сообщение.

Надеюсь, это поможет!

39 голосов
/ 18 апреля 2013

Вот ответ в синтаксисе 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>
6 голосов
/ 02 июня 2011

Хотя я попробовал подход, описанный выше, с mvc это стало полной катастрофой. Ваш контроллер, передающий модель, и ваше представление, использующее строго типизированную модель, становятся слишком сложными для работы.

Включите ваш набор данных в список ..... У меня есть шаблон репозитория, и вот пример получения набора данных из веб-службы asmx старой школы только для чтения 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);

Тогда в View это просто:

@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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...