【问题标题】:ASP.NET MVC2 RenderAction makes parent loose ViewModel contextASP.NET MVC2 RenderAction 使父级松散 ViewModel 上下文
【发布时间】:2010-08-09 10:03:16
【问题描述】:

我是我的项目浏览器页面我有 2 个子元素保证它们自己的控制器(而不仅仅是一个用户控件) - 上传和 FileBrowser,所以我使用 Html.RenderAction(Action, Controller , 参数)。

然而,问题是浏览页面需要 ProjectViewModel,其中 Upload 使用 UploadViewModel 等等等。因此,通过拥有这些 Html.RenderAction 元素,浏览页面似乎立即停止接收 ProjectViewModel - 我猜它会切换到最后一个 RenderAction 的 VM。

我必须在路由中设置什么来确保这些已经强类型化的视图保持它们的上下文吗?

更新代码:

另外,也许我必须明确说明要“上传”的模型是不同的模型?我不知道。

浏览器(包含上传和文件浏览器):

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

【问题讨论】:

  • 我在我的应用程序中做同样的事情并且没有这个问题。你能给我们一些代码吗,也许还有更多。
  • 显示上传和文件浏览器索引操作的路由。你用的是默认路由吗? FileBrowser 的控制器是什么样的?
  • 是的,我正在使用默认路由。明天我回到办公室后,我会发布 FileBrowser 控制器!它基本上只是用默认值填充虚拟机并将其发送回。

标签: asp.net-mvc asp.net-mvc-2 datacontext renderaction


【解决方案1】:

尝试将RenderAction() 渲染的视图设为局部视图。

您还应该使用[ChildActionOnly] 属性装饰该操作,以防止它自己执行(当有人请求http://xxx.com/Upload/Index 时)。

【讨论】:

  • 局部视图不是 ascx/UserControl 吗?据我所知,他们后面没有控制器,所以我会用它的“子”Partials 的功能乱扔主机控制器.. 不是吗?
  • 对于RenderAction,控制器并不重要。我喜欢有特殊的控制器来处理RenderAction 的部分视图,但是由于您创建控制器只是为了您基本上用作用户控件的东西,所以我看不到任何问题。只需将其设为ViewUserControl 并将扩展名更改为ascx 看看它是否能解决您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多