2010-08-09 31 views
0

Je suis ma page de navigateur de projet J'ai 2 sous-éléments qui garantissent leur propre contrôleur (et pas simplement un contrôle de l'utilisateur) - Upload et FileBrowser, et j'ai donc ajouté les en utilisant Html.RenderAction (Action, Controller, param). Le problème cependant, est que la page Browse nécessite ProjectViewModel, où Upload utilise UploadViewModel, etc. etc. Donc, en ayant ces éléments Html.RenderAction, la page Browse semble cesser immédiatement de recevoir le ProjectViewModel - je le devine bascule sur la VM du dernier RenderAction.ASP.NET MVC2 RenderAction rend le contexte ViewModel lâche parent

Y a-t-il quelque chose que je dois configurer dans le routage pour m'assurer que ces vues déjà fortement typées gardent leurs contextes?

Mise à jour avec le code:

Aussi, peut-être que je dois dire explicitement que le modèle allait « Upload » est un autre? Je ne sais pas.

Browser (contenant et FileBrowser Upload):

<%@ 
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> 

Télécharger Voir:

<%@ 
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> 

Télécharger Controller:

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); 
     } 
    } 
} 

Télécharger 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

Je fais la même chose dans mon application et je n'ai pas ce problème. Pouvez-vous nous ferrer un peu de code, peut-être qu'il y a quelque chose de plus à cela. – Sruly

+0

Montrez vos itinéraires pour les actions Upload et FileBrowser Index. Utilisez-vous la route par défaut? A quoi ressemble votre contrôleur pour le FileBrowser? – amurra

+0

Oui, j'utilise les routes par défaut. Je posterai le contrôleur FileBrowser demain quand je serai de retour au bureau! Il remplit simplement la machine virtuelle avec des valeurs par défaut et la renvoie. –

Répondre

1

Essayez de rendre la vue rendue par RenderAction() une vue partielle.

Vous devez également décorer l'action avec l'attribut [ChildActionOnly] pour l'empêcher d'être exécuté par lui-même (lorsque quelqu'un demande http://xxx.com/Upload/Index).

+0

N'est-ce pas une vue partielle ascx/UserControl? Pour autant que je sache, ils n'ont pas de Contrôleurs derrière eux, donc je jetterais le contrôleur hôte avec la fonctionnalité de son "enfant" Partials .. non? –

+0

Quand il s'agit de 'RenderAction', le contrôleur n'a pas vraiment d'importance. J'aime avoir un contrôleur spécial pour gérer les vues partielles pour 'RenderAction', mais puisque vous avez créé un contrôleur uniquement pour ce que vous utilisez essentiellement comme un contrôle utilisateur de toute façon, je ne vois aucun problème. Il suffit de le faire 'ViewUserControl' et de changer l'extension en' ascx' pour voir si cela résout le problème. – Necros