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.Diagnostics.CodeAnalysis;
\r
16 using System.Globalization;
\r
20 using System.Web.UI;
\r
22 [FileLevelControlBuilder(typeof(ViewPageControlBuilder))]
\r
23 public class ViewPage : Page, IViewDataContainer {
\r
25 private string _masterLocation;
\r
27 private static int _nextId;
\r
28 private ViewDataDictionary _viewData;
\r
30 public AjaxHelper<object> Ajax {
\r
35 public HtmlHelper<object> Html {
\r
40 public string MasterLocation {
\r
42 return _masterLocation ?? String.Empty;
\r
45 _masterLocation = value;
\r
49 public object Model {
\r
51 return ViewData.Model;
\r
55 public TempDataDictionary TempData {
\r
57 return ViewContext.TempData;
\r
61 public UrlHelper Url {
\r
66 public ViewContext ViewContext {
\r
71 [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
\r
72 Justification = "This is the mechanism by which the ViewPage gets its ViewDataDictionary object.")]
\r
73 public ViewDataDictionary ViewData {
\r
75 if (_viewData == null) {
\r
76 SetViewData(new ViewDataDictionary());
\r
85 public HtmlTextWriter Writer {
\r
90 public virtual void InitHelpers() {
\r
91 Ajax = new AjaxHelper<object>(ViewContext, this);
\r
92 Html = new HtmlHelper<object>(ViewContext, this);
\r
93 Url = new UrlHelper(ViewContext.RequestContext);
\r
96 internal static string NextId() {
\r
97 return (++_nextId).ToString(CultureInfo.InvariantCulture);
\r
100 [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers")]
\r
101 protected override void OnPreInit(EventArgs e) {
\r
104 if (!String.IsNullOrEmpty(MasterLocation)) {
\r
105 MasterPageFile = MasterLocation;
\r
109 public override void ProcessRequest(HttpContext context) {
\r
110 // Tracing requires IDs to be unique.
\r
113 base.ProcessRequest(context);
\r
116 protected override void Render(HtmlTextWriter writer) {
\r
119 base.Render(writer);
\r
126 public virtual void RenderView(ViewContext viewContext) {
\r
127 ViewContext = viewContext;
\r
130 bool needServerExecute = false;
\r
132 SwitchWriter switchWriter = viewContext.HttpContext.Response.Output as SwitchWriter;
\r
133 if (switchWriter == null) {
\r
134 switchWriter = new SwitchWriter();
\r
135 needServerExecute = true;
\r
138 using (switchWriter.Scope(viewContext.Writer)) {
\r
139 if (needServerExecute) {
\r
140 // It's safe to reset the _nextId within a Server.Execute() since it pushes a new TraceContext onto
\r
141 // the stack, so there won't be an ID conflict.
\r
142 int originalNextId = _nextId;
\r
145 viewContext.HttpContext.Server.Execute(HttpHandlerUtil.WrapForServerExecute(this), switchWriter, true /* preserveForm */);
\r
148 // Restore the original _nextId in case this isn't actually the outermost view, since resetting
\r
149 // the _nextId may now cause trace ID conflicts in the outer view.
\r
150 _nextId = originalNextId;
\r
154 ProcessRequest(HttpContext.Current);
\r
159 [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "textWriter",
\r
160 Justification = "This method existed in MVC 1.0 and has been deprecated.")]
\r
161 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
\r
162 Justification = "This method existed in MVC 1.0 and has been deprecated.")]
\r
163 [Obsolete("The TextWriter is now provided by the ViewContext object passed to the RenderView method.", true /* error */)]
\r
164 public void SetTextWriter(TextWriter textWriter) {
\r
165 // this is now a no-op
\r
168 protected virtual void SetViewData(ViewDataDictionary viewData) {
\r
169 _viewData = viewData;
\r
172 internal class SwitchWriter : TextWriter {
\r
173 public SwitchWriter()
\r
174 : base(CultureInfo.CurrentCulture) {
\r
177 public override Encoding Encoding {
\r
179 return InnerWriter.Encoding;
\r
183 public override IFormatProvider FormatProvider {
\r
185 return InnerWriter.FormatProvider;
\r
189 internal TextWriter InnerWriter {
\r
194 public override string NewLine {
\r
196 return InnerWriter.NewLine;
\r
199 InnerWriter.NewLine = value;
\r
203 public override void Close() {
\r
204 InnerWriter.Close();
\r
207 public override void Flush() {
\r
208 InnerWriter.Flush();
\r
211 public IDisposable Scope(TextWriter writer) {
\r
212 WriterScope scope = new WriterScope(this, InnerWriter);
\r
214 if (writer != this) {
\r
215 InnerWriter = writer;
\r
221 public override void Write(bool value) {
\r
222 InnerWriter.Write(value);
\r
225 public override void Write(char value) {
\r
226 InnerWriter.Write(value);
\r
229 public override void Write(char[] buffer) {
\r
230 InnerWriter.Write(buffer);
\r
233 public override void Write(char[] buffer, int index, int count) {
\r
234 InnerWriter.Write(buffer, index, count);
\r
237 public override void Write(decimal value) {
\r
238 InnerWriter.Write(value);
\r
241 public override void Write(double value) {
\r
242 InnerWriter.Write(value);
\r
245 public override void Write(float value) {
\r
246 InnerWriter.Write(value);
\r
249 public override void Write(int value) {
\r
250 InnerWriter.Write(value);
\r
253 public override void Write(long value) {
\r
254 InnerWriter.Write(value);
\r
257 public override void Write(object value) {
\r
258 InnerWriter.Write(value);
\r
261 public override void Write(string format, object arg0) {
\r
262 InnerWriter.Write(format, arg0);
\r
265 public override void Write(string format, object arg0, object arg1) {
\r
266 InnerWriter.Write(format, arg0, arg1);
\r
269 public override void Write(string format, object arg0, object arg1, object arg2) {
\r
270 InnerWriter.Write(format, arg0, arg1, arg2);
\r
273 public override void Write(string format, params object[] arg) {
\r
274 InnerWriter.Write(format, arg);
\r
277 public override void Write(string value) {
\r
278 InnerWriter.Write(value);
\r
281 public override void Write(uint value) {
\r
282 InnerWriter.Write(value);
\r
285 public override void Write(ulong value) {
\r
286 InnerWriter.Write(value);
\r
289 public override void WriteLine() {
\r
290 InnerWriter.WriteLine();
\r
293 public override void WriteLine(bool value) {
\r
294 InnerWriter.WriteLine(value);
\r
297 public override void WriteLine(char value) {
\r
298 InnerWriter.WriteLine(value);
\r
301 public override void WriteLine(char[] buffer) {
\r
302 InnerWriter.WriteLine(buffer);
\r
305 public override void WriteLine(char[] buffer, int index, int count) {
\r
306 InnerWriter.WriteLine(buffer, index, count);
\r
309 public override void WriteLine(decimal value) {
\r
310 InnerWriter.WriteLine(value);
\r
313 public override void WriteLine(double value) {
\r
314 InnerWriter.WriteLine(value);
\r
317 public override void WriteLine(float value) {
\r
318 InnerWriter.WriteLine(value);
\r
321 public override void WriteLine(int value) {
\r
322 InnerWriter.WriteLine(value);
\r
325 public override void WriteLine(long value) {
\r
326 InnerWriter.WriteLine(value);
\r
329 public override void WriteLine(object value) {
\r
330 InnerWriter.WriteLine(value);
\r
333 public override void WriteLine(string format, object arg0) {
\r
334 InnerWriter.WriteLine(format, arg0);
\r
337 public override void WriteLine(string format, object arg0, object arg1) {
\r
338 InnerWriter.WriteLine(format, arg0, arg1);
\r
341 public override void WriteLine(string format, object arg0, object arg1, object arg2) {
\r
342 InnerWriter.WriteLine(format, arg0, arg1, arg2);
\r
345 public override void WriteLine(string format, params object[] arg) {
\r
346 InnerWriter.WriteLine(format, arg);
\r
349 public override void WriteLine(string value) {
\r
350 InnerWriter.WriteLine(value);
\r
353 public override void WriteLine(uint value) {
\r
354 InnerWriter.WriteLine(value);
\r
357 public override void WriteLine(ulong value) {
\r
358 InnerWriter.WriteLine(value);
\r
361 private sealed class WriterScope : IDisposable {
\r
362 private SwitchWriter _switchWriter;
\r
363 private TextWriter _writerToRestore;
\r
365 public WriterScope(SwitchWriter switchWriter, TextWriter writerToRestore) {
\r
366 _switchWriter = switchWriter;
\r
367 _writerToRestore = writerToRestore;
\r
370 public void Dispose() {
\r
371 _switchWriter.InnerWriter = _writerToRestore;
\r