aspnetcore/src/Microsoft.AspNet.Mvc/View/ViewData.cs

101 lines
2.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Dynamic;
namespace Microsoft.AspNet.Mvc
{
public class ViewData : DynamicObject
{
private readonly Dictionary<object, dynamic> _data;
private object _model;
public ViewData()
{
_data = new Dictionary<object, dynamic>();
}
public ViewData(ViewData source)
{
_data = source._data;
SetModel(source.Model);
}
public object Model
{
get { return _model; }
set { SetModel(value); }
}
public dynamic this[string index]
{
get
{
dynamic result;
if (_data.TryGetValue(index, out result))
{
result = _data[index];
}
else
{
result = null;
}
return result;
}
set
{
_data[index] = (dynamic)value;
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = _data[binder.Name];
// We return true here because ViewDataDictionary returns null if the key is not
// in the dictionary, so we simply pass on the returned value.
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
// This cast should always succeed assuming TValue is dynamic.
dynamic v = value;
_data[binder.Name] = v;
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
if (indexes == null || indexes.Length != 1)
{
throw new ArgumentException("Invalid number of indexes");
}
object index = indexes[0];
result = this[(string)index];
return true;
}
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
if (indexes == null || indexes.Length != 1)
{
throw new ArgumentException("Invalid number of indexes");
}
object index = indexes[0];
// This cast should always succeed assuming TValue is dynamic.
this[(string)index] = value;
return true;
}
// This method will execute before the derived type's instance constructor executes. Derived types must
// be aware of this and should plan accordingly. For example, the logic in SetModel() should be simple
// enough so as not to depend on the "this" pointer referencing a fully constructed object.
protected virtual void SetModel(object value)
{
_model = value;
}
}
}