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

Asked

Viewed 2,408 times

1

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

The idea is to join in index the following:

@model BraveryBranded.ASP.Models.News

@{
    ViewBag.Title = "Index";
}

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

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

This is my List:

@model IEnumerable<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 mine 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")
}

Code of Controller News:

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

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

public ActionResult New()
{
    return View();
}
  • Luiz, if you access the independent pages (create e lis) they work? You could paste the action code of this new page you created?

  • @Andrecalil worse is that they are not working!

  • I think Create is in error because the error message speaks from the list. You can add the code of each action as well?

  • @Andrecalil I didn’t finish the actions, however, it was to appear empty, because really the lists are empty, it was to appear their html.

2 answers

3


Luiz, I think that you don’t want the RenderView, but rather the RenderAction. I’ll assume that in my answer, if I’m wrong tell me, okay?

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

Just this change is easy to make, 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? To be able to load each page alone or all on this 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 changed to

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

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

  • Man, it worked right away! Thank you so much, I didn’t even have to validate the View!

  • @Luiznegrini Wonder, happy to help. Thanks for the feedback

  • despite having worked, my validations with helpers on models have stopped working. What happens there?

  • @Luiznegrini Check if the new page has all the JS references that the others. It may be missing some library.

  • Yes I saw this, but I use a known text editor which is Tinymce. In the description field of my Model, it is referenced this way: [Uihint("tinymce_jquery_full"), Allowhtml] .... However the validations are working, but the text edit box no longer loads. If I open the page alone, it normally loads.

0

As indicated in the error message, your view is modelled on an object in the class BraveryBranded.ASP.Models.News but apparently you’re passing a List<BraveryBranded.ASP.Models.News>.

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

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

  • The list I was able to make work by leaving it alone with the following code snippet: @Renderpage("~/Areas/Admin/Views/News/List.cshtml", new Object[]{ Model } )") But when I enter @Renderpage("~/Areas/Admin/Views/News/New.cshtml") appears an error saying the following: The model item passed into the Dictionary is of type 'System.Collections.Generic.List`1[Braverybranded.ASP.Models.News]', but this Dictionary requires a model item of type 'Braverybranded.ASP.Models.News'.

  • You can set, sff, the controller code that invokes the main view?

  • I changed the question, this in the last block.

  • ta in the last code block of the post.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.