1 namespace System.Web.Mvc {
3 using System.Diagnostics.CodeAnalysis;
4 using System.Globalization;
10 [FileLevelControlBuilder(typeof(ViewPageControlBuilder))]
11 public class ViewPage : Page, IViewDataContainer {
13 private DynamicViewDataDictionary _dynamicViewData;
14 private string _masterLocation;
16 private static int _nextId;
17 private ViewDataDictionary _viewData;
19 public AjaxHelper<object> Ajax {
24 public HtmlHelper<object> Html {
29 public string MasterLocation {
31 return _masterLocation ?? String.Empty;
34 _masterLocation = value;
40 return ViewData.Model;
44 public TempDataDictionary TempData {
46 return ViewContext.TempData;
50 public UrlHelper Url {
55 public dynamic ViewBag {
57 if (_dynamicViewData == null) {
58 _dynamicViewData = new DynamicViewDataDictionary(() => ViewData);
60 return _dynamicViewData;
64 public ViewContext ViewContext {
69 [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This is the mechanism by which the ViewPage gets its ViewDataDictionary object.")]
70 public ViewDataDictionary ViewData {
72 if (_viewData == null) {
73 SetViewData(new ViewDataDictionary());
82 public HtmlTextWriter Writer {
87 public virtual void InitHelpers() {
88 Ajax = new AjaxHelper<object>(ViewContext, this);
89 Html = new HtmlHelper<object>(ViewContext, this);
90 Url = new UrlHelper(ViewContext.RequestContext);
93 internal static string NextId() {
94 return (++_nextId).ToString(CultureInfo.InvariantCulture);
97 protected override void OnPreInit(EventArgs e) {
100 if (!String.IsNullOrEmpty(MasterLocation)) {
101 MasterPageFile = MasterLocation;
105 public override void ProcessRequest(HttpContext context) {
106 // Tracing requires IDs to be unique.
109 base.ProcessRequest(context);
112 protected override void Render(HtmlTextWriter writer) {
122 [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The object is disposed in the finally block of the method")]
123 public virtual void RenderView(ViewContext viewContext) {
124 ViewContext = viewContext;
127 bool createdSwitchWriter = false;
128 SwitchWriter switchWriter = viewContext.HttpContext.Response.Output as SwitchWriter;
131 if (switchWriter == null) {
132 switchWriter = new SwitchWriter();
133 createdSwitchWriter = true;
136 using (switchWriter.Scope(viewContext.Writer)) {
137 if (createdSwitchWriter) {
138 // It's safe to reset the _nextId within a Server.Execute() since it pushes a new TraceContext onto
139 // the stack, so there won't be an ID conflict.
140 int originalNextId = _nextId;
143 viewContext.HttpContext.Server.Execute(HttpHandlerUtil.WrapForServerExecute(this), switchWriter, true /* preserveForm */);
146 // Restore the original _nextId in case this isn't actually the outermost view, since resetting
147 // the _nextId may now cause trace ID conflicts in the outer view.
148 _nextId = originalNextId;
152 ProcessRequest(HttpContext.Current);
157 if (createdSwitchWriter) {
158 switchWriter.Dispose();
163 [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "textWriter", Justification = "This method existed in MVC 1.0 and has been deprecated.")]
164 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This method existed in MVC 1.0 and has been deprecated.")]
165 [Obsolete("The TextWriter is now provided by the ViewContext object passed to the RenderView method.", true /* error */)]
166 public void SetTextWriter(TextWriter textWriter) {
167 // this is now a no-op
170 protected virtual void SetViewData(ViewDataDictionary viewData) {
171 _viewData = viewData;
174 internal class SwitchWriter : TextWriter {
175 public SwitchWriter()
176 : base(CultureInfo.CurrentCulture) {
179 public override Encoding Encoding {
181 return InnerWriter.Encoding;
185 public override IFormatProvider FormatProvider {
187 return InnerWriter.FormatProvider;
191 internal TextWriter InnerWriter {
196 public override string NewLine {
198 return InnerWriter.NewLine;
201 InnerWriter.NewLine = value;
205 public override void Close() {
209 public override void Flush() {
213 public IDisposable Scope(TextWriter writer) {
214 WriterScope scope = new WriterScope(this, InnerWriter);
217 if (writer != this) {
218 InnerWriter = writer;
229 public override void Write(bool value) {
230 InnerWriter.Write(value);
233 public override void Write(char value) {
234 InnerWriter.Write(value);
237 public override void Write(char[] buffer) {
238 InnerWriter.Write(buffer);
241 public override void Write(char[] buffer, int index, int count) {
242 InnerWriter.Write(buffer, index, count);
245 public override void Write(decimal value) {
246 InnerWriter.Write(value);
249 public override void Write(double value) {
250 InnerWriter.Write(value);
253 public override void Write(float value) {
254 InnerWriter.Write(value);
257 public override void Write(int value) {
258 InnerWriter.Write(value);
261 public override void Write(long value) {
262 InnerWriter.Write(value);
265 public override void Write(object value) {
266 InnerWriter.Write(value);
269 public override void Write(string format, object arg0) {
270 InnerWriter.Write(format, arg0);
273 public override void Write(string format, object arg0, object arg1) {
274 InnerWriter.Write(format, arg0, arg1);
277 public override void Write(string format, object arg0, object arg1, object arg2) {
278 InnerWriter.Write(format, arg0, arg1, arg2);
281 public override void Write(string format, params object[] arg) {
282 InnerWriter.Write(format, arg);
285 public override void Write(string value) {
286 InnerWriter.Write(value);
289 public override void Write(uint value) {
290 InnerWriter.Write(value);
293 public override void Write(ulong value) {
294 InnerWriter.Write(value);
297 public override void WriteLine() {
298 InnerWriter.WriteLine();
301 public override void WriteLine(bool value) {
302 InnerWriter.WriteLine(value);
305 public override void WriteLine(char value) {
306 InnerWriter.WriteLine(value);
309 public override void WriteLine(char[] buffer) {
310 InnerWriter.WriteLine(buffer);
313 public override void WriteLine(char[] buffer, int index, int count) {
314 InnerWriter.WriteLine(buffer, index, count);
317 public override void WriteLine(decimal value) {
318 InnerWriter.WriteLine(value);
321 public override void WriteLine(double value) {
322 InnerWriter.WriteLine(value);
325 public override void WriteLine(float value) {
326 InnerWriter.WriteLine(value);
329 public override void WriteLine(int value) {
330 InnerWriter.WriteLine(value);
333 public override void WriteLine(long value) {
334 InnerWriter.WriteLine(value);
337 public override void WriteLine(object value) {
338 InnerWriter.WriteLine(value);
341 public override void WriteLine(string format, object arg0) {
342 InnerWriter.WriteLine(format, arg0);
345 public override void WriteLine(string format, object arg0, object arg1) {
346 InnerWriter.WriteLine(format, arg0, arg1);
349 public override void WriteLine(string format, object arg0, object arg1, object arg2) {
350 InnerWriter.WriteLine(format, arg0, arg1, arg2);
353 public override void WriteLine(string format, params object[] arg) {
354 InnerWriter.WriteLine(format, arg);
357 public override void WriteLine(string value) {
358 InnerWriter.WriteLine(value);
361 public override void WriteLine(uint value) {
362 InnerWriter.WriteLine(value);
365 public override void WriteLine(ulong value) {
366 InnerWriter.WriteLine(value);
369 private sealed class WriterScope : IDisposable {
370 private SwitchWriter _switchWriter;
371 private TextWriter _writerToRestore;
373 public WriterScope(SwitchWriter switchWriter, TextWriter writerToRestore) {
374 _switchWriter = switchWriter;
375 _writerToRestore = writerToRestore;
378 public void Dispose() {
379 _switchWriter.InnerWriter = _writerToRestore;