Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom ActionResult equivalent Model for all PartialViews

I created following custom ActionResult which returns multiple partial views.

public class MultiplePartialViewsResult : ActionResult
{
    private const string Separator = "-";
    private PartialViewResult[] _partialViews;

    public MultiplePartialViewsResult(params PartialViewResult[] partialViews)
    {
        _partialViews = partialViews;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        foreach (var partialView in _partialViews)
        {
            partialView.ExecuteResult(context);
            context.HttpContext.Response.Output.Write(Separator);
        }
    }
}

And then I use it as follows:

return new MultiplePartialViewsResult(
             PartialView("~/Views/RowSumView.cshtml", new List<double>() { 1.0 }),
             PartialView("~/Views/ColumnSumView.cshtml", new List<double>() { 2.0 }));

But if I place breakpoint in MultiplePartialViewsResult's constructor I see that model in both cases equals 2.0. It overrides all models with the last model specified in a array.

Try to create couple PartialViews in method and assign it to variable. Then you will notice they all share equivalent model.

like image 345
Maximus Avatar asked Jan 10 '16 14:01

Maximus


1 Answers

You can initialize the MultiplePartialViewsResult object in the following manner with new own ViewData / ViewData.Model instances (works fine for me):

return new MultiplePartialViewsResult(
    //PartialView("~/Views/RowSumView.cshtml", new List<double>() { 1.0 }),
    //PartialView("~/Views/ColumnSumView.cshtml", new List<double>() { 2.0 })
    new PartialViewResult() { ViewName = "~/Views/RowSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 1.0 } } },
    new PartialViewResult() { ViewName = "~/Views/ColumnSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 2.0 } } }
);

Custom Action Result:

public class MultiplePartialViewsResult : ActionResult {
    private const string Separator = "-";
    private PartialViewResult[] _partialViews;

    public MultiplePartialViewsResult(params PartialViewResult[] partialViews) {
        _partialViews = partialViews;
    }

    public override void ExecuteResult(ControllerContext context) {
        foreach(var partialView in _partialViews) {
            partialView.ExecuteResult(context);
            context.HttpContext.Response.Output.Write(Separator);
        }
    }
}

Controller:

public ActionResult Index() {
    return View();
}
public ActionResult FakeAction() {
    return new MultiplePartialViewsResult(
        //PartialView("~/Views/RowSumView.cshtml", new List<double>() { 1.0 }),
        //PartialView("~/Views/ColumnSumView.cshtml", new List<double>() { 2.0 })
        new PartialViewResult() { ViewName = "~/Views/RowSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 1.0 } } },
        new PartialViewResult() { ViewName = "~/Views/ColumnSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 2.0 } } }
    );
}

Views:

Index:

@Html.Action("FakeAction")

ColumnSumView.cshtml / RowSumView.cshtml:

@model List<double>
<ul>
    @foreach(double item in Model) {
        <li>@item</li>
    }
</ul>
like image 121
Mikhail Avatar answered Oct 06 '22 00:10

Mikhail