1 /* ****************************************************************************
\r
3 * Copyright (c) Microsoft Corporation. All rights reserved.
\r
5 * This software is subject to the Microsoft Public License (Ms-PL).
\r
6 * A copy of the license can be found in the license.htm file included
\r
7 * in this distribution.
\r
9 * You must not remove this notice, or any other, from this software.
\r
11 * ***************************************************************************/
\r
13 namespace System.Web.Mvc {
\r
15 using System.ComponentModel;
\r
16 using System.Diagnostics.CodeAnalysis;
\r
17 using System.Globalization;
\r
19 using System.Web.Mvc.Resources;
\r
20 using System.Web.UI;
\r
22 [FileLevelControlBuilder(typeof(ViewUserControlControlBuilder))]
\r
23 public class ViewUserControl : UserControl, IViewDataContainer {
\r
24 private AjaxHelper<object> _ajaxHelper;
\r
25 private HtmlHelper<object> _htmlHelper;
\r
26 private ViewContext _viewContext;
\r
27 private ViewDataDictionary _viewData;
\r
28 private string _viewDataKey;
\r
30 public AjaxHelper<object> Ajax {
\r
32 if (_ajaxHelper == null) {
\r
33 _ajaxHelper = new AjaxHelper<object>(ViewContext, this);
\r
39 public HtmlHelper<object> Html {
\r
41 if (_htmlHelper == null) {
\r
42 _htmlHelper = new HtmlHelper<object>(ViewContext, this);
\r
48 public object Model {
\r
50 return ViewData.Model;
\r
54 public TempDataDictionary TempData {
\r
56 return ViewPage.TempData;
\r
60 public UrlHelper Url {
\r
62 return ViewPage.Url;
\r
67 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
\r
68 public ViewContext ViewContext {
\r
70 return _viewContext ?? ViewPage.ViewContext;
\r
73 _viewContext = value;
\r
77 [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
\r
78 Justification = "This is the mechanism by which the ViewUserControl gets its ViewDataDictionary object.")]
\r
80 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
\r
81 public ViewDataDictionary ViewData {
\r
92 public string ViewDataKey {
\r
94 return _viewDataKey ?? String.Empty;
\r
97 _viewDataKey = value;
\r
101 internal ViewPage ViewPage {
\r
103 ViewPage viewPage = Page as ViewPage;
\r
104 if (viewPage == null) {
\r
105 throw new InvalidOperationException(MvcResources.ViewUserControl_RequiresViewPage);
\r
111 public HtmlTextWriter Writer {
\r
113 return ViewPage.Writer;
\r
117 protected virtual void SetViewData(ViewDataDictionary viewData) {
\r
118 _viewData = viewData;
\r
121 protected void EnsureViewData() {
\r
122 if (_viewData != null) {
\r
126 // Get the ViewData for this ViewUserControl, optionally using the specified ViewDataKey
\r
127 IViewDataContainer vdc = GetViewDataContainer(this);
\r
129 throw new InvalidOperationException(
\r
131 CultureInfo.CurrentUICulture,
\r
132 MvcResources.ViewUserControl_RequiresViewDataProvider,
\r
133 AppRelativeVirtualPath));
\r
136 ViewDataDictionary myViewData = vdc.ViewData;
\r
138 // If we have a ViewDataKey, try to extract the ViewData from the dictionary, otherwise
\r
139 // return the container's ViewData.
\r
140 if (!String.IsNullOrEmpty(ViewDataKey)) {
\r
141 object target = myViewData.Eval(ViewDataKey);
\r
142 myViewData = target as ViewDataDictionary ?? new ViewDataDictionary(myViewData) { Model = target };
\r
145 SetViewData(myViewData);
\r
148 private static IViewDataContainer GetViewDataContainer(Control control) {
\r
149 // Walk up the control hierarchy until we find someone that implements IViewDataContainer
\r
150 while (control != null) {
\r
151 control = control.Parent;
\r
152 IViewDataContainer vdc = control as IViewDataContainer;
\r
160 public virtual void RenderView(ViewContext viewContext) {
\r
161 ViewUserControlContainerPage containerPage = new ViewUserControlContainerPage(this);
\r
163 RenderViewAndRestoreContentType(containerPage, viewContext);
\r
166 internal static void RenderViewAndRestoreContentType(ViewPage containerPage, ViewContext viewContext) {
\r
167 // We need to restore the Content-Type since Page.SetIntrinsics() will reset it. It's not possible
\r
168 // to work around the call to SetIntrinsics() since the control's render method requires the
\r
169 // containing page's Response property to be non-null, and SetIntrinsics() is the only way to set
\r
171 string savedContentType = viewContext.HttpContext.Response.ContentType;
\r
172 containerPage.RenderView(viewContext);
\r
173 viewContext.HttpContext.Response.ContentType = savedContentType;
\r
176 [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "textWriter",
\r
177 Justification = "This method existed in MVC 1.0 and has been deprecated.")]
\r
178 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
\r
179 Justification = "This method existed in MVC 1.0 and has been deprecated.")]
\r
180 [Obsolete("The TextWriter is now provided by the ViewContext object passed to the RenderView method.", true /* error */)]
\r
181 public void SetTextWriter(TextWriter textWriter) {
\r
182 // this is now a no-op
\r
185 private sealed class ViewUserControlContainerPage : ViewPage {
\r
186 private readonly ViewUserControl _userControl;
\r
188 public ViewUserControlContainerPage(ViewUserControl userControl) {
\r
189 _userControl = userControl;
\r
192 public override void ProcessRequest(HttpContext context) {
\r
193 _userControl.ID = ViewPage.NextId();
\r
194 Controls.Add(_userControl);
\r
196 base.ProcessRequest(context);
\r