Files
linux-packaging-mono/external/aspnetwebstack/src/System.Web.Mvc/ViewPage.cs
Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

430 lines
12 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Text;
using System.Web.UI;
namespace System.Web.Mvc
{
[FileLevelControlBuilder(typeof(ViewPageControlBuilder))]
public class ViewPage : Page, IViewDataContainer
{
[ThreadStatic]
private static int _nextId;
private DynamicViewDataDictionary _dynamicViewData;
private string _masterLocation;
private ViewDataDictionary _viewData;
public AjaxHelper<object> Ajax { get; set; }
public HtmlHelper<object> Html { get; set; }
public string MasterLocation
{
get { return _masterLocation ?? String.Empty; }
set { _masterLocation = value; }
}
public object Model
{
get { return ViewData.Model; }
}
public TempDataDictionary TempData
{
get { return ViewContext.TempData; }
}
public UrlHelper Url { get; set; }
public dynamic ViewBag
{
get
{
if (_dynamicViewData == null)
{
_dynamicViewData = new DynamicViewDataDictionary(() => ViewData);
}
return _dynamicViewData;
}
}
public ViewContext ViewContext { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This is the mechanism by which the ViewPage gets its ViewDataDictionary object.")]
public ViewDataDictionary ViewData
{
get
{
if (_viewData == null)
{
SetViewData(new ViewDataDictionary());
}
return _viewData;
}
set { SetViewData(value); }
}
public HtmlTextWriter Writer { get; private set; }
public virtual void InitHelpers()
{
Ajax = new AjaxHelper<object>(ViewContext, this);
Html = new HtmlHelper<object>(ViewContext, this);
Url = new UrlHelper(ViewContext.RequestContext);
}
internal static string NextId()
{
return (++_nextId).ToString(CultureInfo.InvariantCulture);
}
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
if (!String.IsNullOrEmpty(MasterLocation))
{
MasterPageFile = MasterLocation;
}
}
public override void ProcessRequest(HttpContext context)
{
// Tracing requires IDs to be unique.
ID = NextId();
base.ProcessRequest(context);
}
protected override void Render(HtmlTextWriter writer)
{
Writer = writer;
try
{
base.Render(writer);
}
finally
{
Writer = null;
}
}
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The object is disposed in the finally block of the method")]
public virtual void RenderView(ViewContext viewContext)
{
ViewContext = viewContext;
InitHelpers();
bool createdSwitchWriter = false;
SwitchWriter switchWriter = viewContext.HttpContext.Response.Output as SwitchWriter;
try
{
if (switchWriter == null)
{
switchWriter = new SwitchWriter();
createdSwitchWriter = true;
}
using (switchWriter.Scope(viewContext.Writer))
{
if (createdSwitchWriter)
{
// It's safe to reset the _nextId within a Server.Execute() since it pushes a new TraceContext onto
// the stack, so there won't be an ID conflict.
int originalNextId = _nextId;
try
{
_nextId = 0;
viewContext.HttpContext.Server.Execute(HttpHandlerUtil.WrapForServerExecute(this), switchWriter, true /* preserveForm */);
}
finally
{
// Restore the original _nextId in case this isn't actually the outermost view, since resetting
// the _nextId may now cause trace ID conflicts in the outer view.
_nextId = originalNextId;
}
}
else
{
ProcessRequest(HttpContext.Current);
}
}
}
finally
{
if (createdSwitchWriter)
{
switchWriter.Dispose();
}
}
}
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "textWriter", Justification = "This method existed in MVC 1.0 and has been deprecated.")]
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This method existed in MVC 1.0 and has been deprecated.")]
[Obsolete("The TextWriter is now provided by the ViewContext object passed to the RenderView method.", true /* error */)]
public void SetTextWriter(TextWriter textWriter)
{
// this is now a no-op
}
protected virtual void SetViewData(ViewDataDictionary viewData)
{
_viewData = viewData;
}
internal class SwitchWriter : TextWriter
{
public SwitchWriter()
: base(CultureInfo.CurrentCulture)
{
}
public override Encoding Encoding
{
get { return InnerWriter.Encoding; }
}
public override IFormatProvider FormatProvider
{
get { return InnerWriter.FormatProvider; }
}
internal TextWriter InnerWriter { get; set; }
public override string NewLine
{
get { return InnerWriter.NewLine; }
set { InnerWriter.NewLine = value; }
}
public override void Close()
{
InnerWriter.Close();
}
public override void Flush()
{
InnerWriter.Flush();
}
public IDisposable Scope(TextWriter writer)
{
WriterScope scope = new WriterScope(this, InnerWriter);
try
{
if (writer != this)
{
InnerWriter = writer;
}
return scope;
}
catch
{
scope.Dispose();
throw;
}
}
public override void Write(bool value)
{
InnerWriter.Write(value);
}
public override void Write(char value)
{
InnerWriter.Write(value);
}
public override void Write(char[] buffer)
{
InnerWriter.Write(buffer);
}
public override void Write(char[] buffer, int index, int count)
{
InnerWriter.Write(buffer, index, count);
}
public override void Write(decimal value)
{
InnerWriter.Write(value);
}
public override void Write(double value)
{
InnerWriter.Write(value);
}
public override void Write(float value)
{
InnerWriter.Write(value);
}
public override void Write(int value)
{
InnerWriter.Write(value);
}
public override void Write(long value)
{
InnerWriter.Write(value);
}
public override void Write(object value)
{
InnerWriter.Write(value);
}
public override void Write(string format, object arg0)
{
InnerWriter.Write(format, arg0);
}
public override void Write(string format, object arg0, object arg1)
{
InnerWriter.Write(format, arg0, arg1);
}
public override void Write(string format, object arg0, object arg1, object arg2)
{
InnerWriter.Write(format, arg0, arg1, arg2);
}
public override void Write(string format, params object[] arg)
{
InnerWriter.Write(format, arg);
}
public override void Write(string value)
{
InnerWriter.Write(value);
}
public override void Write(uint value)
{
InnerWriter.Write(value);
}
public override void Write(ulong value)
{
InnerWriter.Write(value);
}
public override void WriteLine()
{
InnerWriter.WriteLine();
}
public override void WriteLine(bool value)
{
InnerWriter.WriteLine(value);
}
public override void WriteLine(char value)
{
InnerWriter.WriteLine(value);
}
public override void WriteLine(char[] buffer)
{
InnerWriter.WriteLine(buffer);
}
public override void WriteLine(char[] buffer, int index, int count)
{
InnerWriter.WriteLine(buffer, index, count);
}
public override void WriteLine(decimal value)
{
InnerWriter.WriteLine(value);
}
public override void WriteLine(double value)
{
InnerWriter.WriteLine(value);
}
public override void WriteLine(float value)
{
InnerWriter.WriteLine(value);
}
public override void WriteLine(int value)
{
InnerWriter.WriteLine(value);
}
public override void WriteLine(long value)
{
InnerWriter.WriteLine(value);
}
public override void WriteLine(object value)
{
InnerWriter.WriteLine(value);
}
public override void WriteLine(string format, object arg0)
{
InnerWriter.WriteLine(format, arg0);
}
public override void WriteLine(string format, object arg0, object arg1)
{
InnerWriter.WriteLine(format, arg0, arg1);
}
public override void WriteLine(string format, object arg0, object arg1, object arg2)
{
InnerWriter.WriteLine(format, arg0, arg1, arg2);
}
public override void WriteLine(string format, params object[] arg)
{
InnerWriter.WriteLine(format, arg);
}
public override void WriteLine(string value)
{
InnerWriter.WriteLine(value);
}
public override void WriteLine(uint value)
{
InnerWriter.WriteLine(value);
}
public override void WriteLine(ulong value)
{
InnerWriter.WriteLine(value);
}
private sealed class WriterScope : IDisposable
{
private SwitchWriter _switchWriter;
private TextWriter _writerToRestore;
public WriterScope(SwitchWriter switchWriter, TextWriter writerToRestore)
{
_switchWriter = switchWriter;
_writerToRestore = writerToRestore;
}
public void Dispose()
{
_switchWriter.InnerWriter = _writerToRestore;
}
}
}
}
}