2010-08-09 25 views
0

我是我的項目瀏覽器頁面我有2個子元素,保證自己的控制器(而不是簡單的用戶控制) - 上傳和FileBrowser,所以我已經使用Html.RenderAction(Action,Controller,param)添加它們。ASP.NET MVC2 RenderAction使父寬鬆ViewModel上下文

然而,問題是瀏覽頁面需要ProjectViewModel,其中Upload使用UploadViewModel等等。所以通過使用這些Html.RenderAction元素,Browse頁面似乎立即停止接收ProjectViewModel - 我猜測它切換到最後一個RenderAction的VM。

有什麼我必須在路由設置,以確保這些已經強烈類型的視圖保持其上下文?

更新,代碼:

而且,也許我必須明確指出,該模型會「上傳」是一個不同?我不知道。 (含有上傳和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); 
     } 
    } 
} 

上傳VM:

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 
     }; 
    } 
    } 
} 
+0

我在我的應用程序中做同樣的事情,沒有這個問題。你可以給我們一些代碼,也許還有更多這樣的東西。 – Sruly 2010-08-09 10:13:56

+0

顯示上傳和FileBrowser索引操作的路由。你使用默認路由嗎?您的控制器對於FileBrowser而言看起來像什麼? – amurra 2010-08-09 13:18:12

+0

是的,我使用默認路由。明天當我回到辦公室時,我會發布FileBrowser控制器!它基本上只是使用默認值填充虛擬機並將其發回。 – 2010-08-09 14:24:36

回答

1

嘗試使由RenderAction()呈現的視圖成爲局部視圖。

你也應該[ChildActionOnly]屬性裝飾作用,以防止它通過它自己(當有人將請求http://xxx.com/Upload/Index)執行。

+0

是不是部分查看ascx/UserControl?據我所知,他們沒有控制器背後,所以我會亂扔主機控制器的功能,它的「孩子」Partials ..不是嗎? – 2010-08-10 00:46:31

+0

當涉及到'RenderAction'時,控制器並不重要。我喜歡使用特殊的控制器來處理'RenderAction'的部分視圖,但是由於您創建的控制器只是基本上用作用戶控件的東西,所以我沒有看到任何問題。只需將其設置爲'ViewUserControl'並將擴展名更改爲'ascx'並查看它是否能解決您的問題。 – Necros 2010-08-10 01:12:08