ASP.NET MVC2 RenderAction освобождает родительский контекст ViewModel - PullRequest
0 голосов
/ 09 августа 2010

Я - страница моего обозревателя проектов. У меня есть 2 подэлемента, которые требуют собственного контроллера (а не просто пользовательского элемента управления) - Upload и FileBrowser, поэтому я добавил их с помощью Html.RenderAction (Action, Controller). , парам).

Проблема, однако, заключается в том, что для страницы просмотра требуется ProjectViewModel, где для загрузки используется UploadViewModel и т. Д. И т. Д. Таким образом, имея эти элементы Html.RenderAction, страница обзора, по-видимому, немедленно прекращает получать ProjectViewModel - я предполагаю, что она переключается к виртуальной машине последнего действия RenderAction.

Есть ли что-то, что я должен настроить в маршрутизации, чтобы гарантировать, что эти уже строго типизированные представления сохраняют свой контекст?

Обновление с кодом:

Кроме того, может быть, я должен прямо заявить, что модель, идущая в «Upload», отличается? Я не знаю.

Браузер (содержащий Upload и FileBrowser):

<%@ 
Page Title="" 
Language="C#" 
Inherits="System.Web.Mvc.ViewPage<CKD.Web.Files.ViewModels.ProjectViewModel>"
MasterPageFile="~/Views/Project/Project.Master" 
%>

<asp:Content runat="server" ID="Main" ContentPlaceHolderID="MainContent">
    <table>
<tr>
<td id="upload" style="width: 180px" class="ui-widget ui-widget-content ui-corner-all">
    <% Html.RenderAction("Index", "Upload", new {id = Model.Project.Id}); %>
</td>
<td id="fileBrowser" style="width: auto" class="ui-widget ui-widget-content ui-corner-all">
    <% Html.RenderAction("Index", "FileBrowser", new {id = Model.Project.Id}); %>
</td>
</tr>
</table>
</asp:Content>

Загрузить Загрузить:

<%@ 
Page Title="" 
Language="C#" 
Inherits="System.Web.Mvc.ViewPage<CKD.Web.Files.ViewModels.UploadViewModel>" 
MasterPageFile="~/Views/Shared/Control.master"
%>
<%@ Import Namespace="System.IO" %>

<asp:Content runat="server" ID="Scripts" ContentPlaceHolderID="Scripts">
</asp:Content>

<asp:Content runat="server" ID="Main" ContentPlaceHolderID="MainContent">
<div class="uploadControl" style="Margin: 8px">
<h2 style="Margin-Bottom: 0px">Upload</h2>
<hr />

<div id="accordion" style="display: block;">
    <h3><a href="#">Files</a></h3>
    <div>
        <div class="ui-widget-content ui-corner-all" style="min-height: 80px; margin: 4px">
            <% if(Model.Files != null) %>
                <% foreach(FileInfo f in Model.Files) {%>
                    <p><%= f.Name %></p>
                    <hr />
                <% } %>
        </div>
        <ul style="width: 10px; list-style-type:none">
            <li class="ui-widget ui-widget-button ui-corners-all">Clear</li>
            <li class="ui-widget ui-widget-button ui-corners-all">Add</li>
        </ul>
    </div>
    <h3><a href="#">Transmittal</a></h3>
    <div>
        <p>File here</p>
        <p style="width: auto; margin: 8px" class="ui-widget-button">Pick File...</p>
    </div>
    <h3><a href="#">Notification</a></h3>
    <div>
        <p>
        Stuff
        </p>
    </div>
</div>
<div>
<div class="ui-widget ui-corner-all ui-widget-active">Upload Files</div>
</div>

</div>
</asp:Content>

Контроллер загрузки:

using System.Web.Mvc;

namespace CKD.Web.Files.Controllers
{
    using System.Linq;
    using Models;
    using ViewModels;

    public class UploadController : Controller
    {
        private ICKDClientAreaRepository Repository { get; set; }
        private UploadViewModel _viewModel;

                        private UploadViewModel ViewModel
    {
        get { return _viewModel ?? (_viewModel = ViewModel = UploadViewModel.Default(Repository)); }
        set { _viewModel = value; }
    }

                    public UploadController(ICKDClientAreaRepository repository)
    {
        Repository = repository;
    }

        // GET
        public ActionResult Index(int id)
        {
            var project = Repository.Projects.Single(x => x.Id == id);
            ViewModel = UploadViewModel.ForProject(project, Repository);

            return View(ViewModel);
        }
    }
}

Загрузить ВМ:

namespace CKD.Web.Files.ViewModels
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Web.Security;
    using Models;

    public class UploadViewModel
    {
        public Project Project { get; set; }
        public DirectoryInfo Directory { get; set; }
        public User Uploader { get; set; }
        public DateTime Time { get; set; }

        public List<FileInfo> Files { get; set; }
        public FileInfo Transmittal { get; set; }

        public List<User> NotificationList { get; set; }

                        public static UploadViewModel Default(ICKDClientAreaRepository fromRepository)
    {
        var project = fromRepository.Projects.First();

        return ForProject(project, fromRepository);
    }

                                                                public static UploadViewModel ForProject(Project project, ICKDClientAreaRepository fromRepository)
    {
        var dir = project.DirectoryName;
        var uploader = fromRepository.Users.Single(x => x.Username == Membership.GetUser().UserName);
        var time = DateTime.Now;
        var notification = project.Users.ToList();

        return new UploadViewModel
        {
            Project = project,
            Directory = new DirectoryInfo(dir),
            Uploader = uploader,
            Time = time,
            NotificationList = notification
        };
    }
    }
}

1 Ответ

1 голос
/ 09 августа 2010

Попробуйте сделать вид, представленный RenderAction() частичным.

Вы также должны украсить действие атрибутом [ChildActionOnly], чтобы предотвратить его выполнение самостоятельно (когда кто-то запросит http://xxx.com/Upload/Index).

...