- bellevue_preview.zip
- Bellevue_Preview
- DemoWeb.sln
- Ope.Bellevue.DemoWeb
- Ope.Bellevue
- bin
- Debug
- BoneSoft.CSS.dll
- Fizzler.dll
- Fizzler.Systems.HtmlAgilityPack.dll
- HtmlAgilityPack.dll
- Ope.Bellevue.dll
- Ope.Vss.dll
- Ope.Bellevue.csproj
- Ope.Bellevue.csproj.user
- Parsing
- Properties
- Renderers
- Rendering
- Resources
- ViewEngine
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
namespace Ope.Bellevue.Rendering
{
public class DataContext: IViewDataContainer
{
ViewDataDictionary viewData;
object itemData;
int itemIndex = -1;
public DataContext(ViewDataDictionary viewData)
{
this.viewData = viewData;
}
public DataContext GetItemContext(object itemdata, int itemIndex)
{
var itemContext = new DataContext(viewData);
itemContext.itemData = itemdata;
itemContext.itemIndex = itemIndex;
return itemContext;
}
public bool GetBool(RenderingParameter param)
{
if (param == null)
{
return false;
}
object value = GetObject(param);
if (value == null)
{
return false;
}
if (value is bool)
{
return (bool)value;
}
if (value is string && value.ToString().ToLower() == "false")
{
return false;
}
return true;
}
public string GetValue(RenderingParameter expression)
{
object result = GetObject(expression);
if (result == null)
{
return "";
}
else
{
return result.ToString();
}
}
public System.Collections.IEnumerable GetEnumerable(RenderingParameter expression)
{
object result = GetObject(expression);
if (result == null)
{
return null;
}
if (!(result is string) && result is System.Collections.IEnumerable)
{
return (System.Collections.IEnumerable)result;
}
return new object[] { result };
}
public object GetObject(RenderingParameter parameter)
{
if (parameter == null)
{
return null;
}
if (parameter.Type == ParameterType.Function)
{
return getFunctionValue(parameter.Function);
}
else if (parameter.Type == ParameterType.Text)
{
return parameter.Value;
}
else
{
throw new NotSupportedException("Unknown parameter type: " + parameter.Type);
}
}
private object getFunctionValue(FunctionParameter func)
{
string functionName = func.Name.ToLower();
if (functionName == "concat")
{
StringBuilder sb = new StringBuilder();
foreach (var param in func.Parameters)
{
sb.Append(GetValue(param));
}
return sb.ToString();
}
if (functionName == "true")
{
return true;
}
if (functionName == "false")
{
return false;
}
if (functionName == "null")
{
return null;
}
// The rest of the functions use the first prameter separately, so fetching it here as object and string
object firstParamValue = func.Parameters.Count < 1 ? null : GetObject(func.Parameters[0]);
string firstParamText = (firstParamValue ?? "").ToString();
switch (functionName)
{
case "isnull":
if (firstParamValue == null)
{
return func.Parameters.Count > 1 ? GetObject(func.Parameters[1]) : null;
}
else
{
return firstParamValue;
}
case "if":
if (func.Parameters.Count < 2)
{
return null;
}
bool condition = GetBool(func.Parameters[0]);
if (condition)
{
return GetValue(func.Parameters[1]);
}
else
{
if (func.Parameters.Count == 2)
{
return null;
}
else
{
return GetValue(func.Parameters[2]);
}
}
case "index":
if (itemIndex < 0)
{
return null;
}
int indexBase;
int.TryParse(firstParamText, out indexBase);
return itemIndex + indexBase;
case "data":
if (firstParamText == "")
{
return viewData;
}
else
{
// TODO: Consider the performance of doing Eval directly vs. trying with the key first
return viewData.Eval(firstParamText);
}
case "model":
if (firstParamText == "")
{
return viewData.Model;
}
else
{
// TODO: Consider restricting this to Model only (not ViewData dictionary)
return viewData.Eval(firstParamText);
}
case "item":
if (firstParamText == "")
{
return itemData;
}
else
{
return getProperty(itemData, firstParamText);
}
}
// Collection functions (one parameter required to be IEnumerable)
string[] collectionFunctions = new string[] { "join", "first", "last", "rest", "trunc", "strip", "length" };
if (collectionFunctions.Contains(functionName))
{
var coll = firstParamValue as System.Collections.IEnumerable;
if (coll == null)
{
return null;
}
var objectColl = coll.Cast<object>();
switch (functionName)
{
case "join":
string separator = ", ";
if (func.Parameters.Count > 1)
{
separator = GetValue(func.Parameters[1]);
}
return string.Join(separator, objectColl.Select(o => (o ?? "").ToString()).ToArray());
case "first":
return objectColl.FirstOrDefault();
case "last":
return objectColl.LastOrDefault();
case "rest":
return objectColl.Skip(1);
case "trunc":
return objectColl.Take(objectColl.Count() - 1);
case "strip":
return from x in objectColl where x != null select x;
case "length":
return objectColl.Count();
}
}
// Two parameters required
if (functionName == "get")
{
if (func.Parameters.Count < 2)
{
return null;
}
return getProperty(firstParamValue, GetValue(func.Parameters[1]));
}
throw new NotSupportedException("Function " + functionName + " not supported.");
}
private object getProperty(object container, string propertyExpression)
{
// TODO: This implementation is quite limited: should probably support indexers / dictionaries
if (string.IsNullOrEmpty(propertyExpression) || container == null)
{
return null;
}
string[] propertyPath = propertyExpression.Split('.');
object currentObj = container;
for (int i = 0; i < propertyPath.Length; i++)
{
string propertyPart = propertyPath[i];
System.ComponentModel.PropertyDescriptor descriptor
= System.ComponentModel.TypeDescriptor.GetProperties(currentObj).Find(propertyPart, true);
if (descriptor == null)
{
return null;
}
else
{
currentObj = descriptor.GetValue(currentObj);
if (currentObj == null)
{
return null;
}
}
}
return currentObj;
}
#region IViewDataContainer Members
public ViewDataDictionary ViewData
{
get
{
return viewData;
}
set
{
viewData = value;
}
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Olli is a .Net developer and architect.
He specializes in Asp.net MVC and other web technologies, XML and lately Domain Specific Languages.
Olli is originally from Finland, but currently works for his own one-man-initiative OPE AG (
www.ope.ag) from Switzerland. He has over 10 years of experience as one of the founding partners and Chief Technology Officer of Quartal group of companies (
www.quartal.com).