How to render two Views typed in an Index ()?

1
I'm trying to render two views created with scaffolding, one is for Create and another is for the List in>.

The idea is to add the following to index :

@model BraveryBranded.ASP.Models.News

@{
    ViewBag.Title = "Index";
}

@RenderPage("~/Areas/Admin/Views/News/New.cshtml")
<hr/>
@RenderPage("~/Areas/Admin/Views/News/List.cshtml")

This is generating an error talking about models . Here is the print:

ThisismyList:

@modelIEnumerable<BraveryBranded.ASP.Models.News>@{ViewBag.Title="Lista";
}

<h2>@ViewBag.Title</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.IDNews)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Description)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.PostDate)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.IDNews)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.PostDate)
            </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>
    }

</table>

And this is my Create :

@model BraveryBranded.ASP.Models.News

@{
    ViewBag.Title = "Adicionar";
}

<h2>@ViewBag.Title</h2>

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>News</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.IDNews)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.IDNews)
            @Html.ValidationMessageFor(model => model.IDNews)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Description)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Description)
            @Html.ValidationMessageFor(model => model.Description)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.PostDate)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.PostDate)
            @Html.ValidationMessageFor(model => model.PostDate)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Controller News code:

public ActionResult Index()
{
    return View();
}

public ActionResult List()
{
    var list = UpdateList();
    return View(list);
}

public ActionResult New()
{
    return View();
}
    
asked by anonymous 07.02.2014 / 22:59

2 answers

3

Luiz, I think that you do not want RenderView , but RenderAction . I'll assume this in my answer, if I'm wrong, tell me, okay?

The RenderView will try to just bring the code of that view to where it was called. He will not go through the equivalent action, and that's why I do not think it's his intention. The RenderAction , on the other hand, will execute the action and all the code that is inside it, to only then give you the resulting HTML.

Only this change is easy to do, see:

@{
    Html.RenderAction("New", "SeuController");
    Html.RenderAction("List", "SeuController");
}

However , doing just that can bring an unwanted result. If your project has a layout file, each page will be loaded completely, which will break your design. What would be an interesting solution? Be able to load each page alone or all on that single page. To do this, let's change the actions, like this:

public ActionResult List(bool partial = false)
{
    var list = UpdateList();

    if(partial)
        return PartialView(list);
    else
        return View(list);
}

And the call we've changed to

@{
    Html.RenderAction("New", "SeuController", new { partial = true });
    Html.RenderAction("List", "SeuController", new { partial = true });
}

Is it clear? By forcing the return to be PartialView , it will not load the HTML from the layout, just the one generated on the page. And since we use an optional attribute, the usual calls will not be affected.

    
08.02.2014 / 00:21
0

As indicated in the error message, your view is modeled as an object of class BraveryBranded.ASP.Models.News but apparently you are passing List<BraveryBranded.ASP.Models.News> .

Validate if your controller is passing the correct object or if the definition of your view that aggregates both should not be @model IEnumerable<BraveryBranded.ASP.Models.News> .

Note that the RenderPage method is able to receive the view template as a parameter, for example @RenderPage("~/Areas/Admin/Views/News/List.cshtml", new BraveryBranded.ASP.Models.News[]{ Model } )

    
07.02.2014 / 23:20