|
//------------------------------------------------------------------------------
// <copyright file="CollectionBuilder.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
* Classes related to complex property support.
*
* Copyright (c) 1999 Microsoft Corporation
*/
namespace System.Web.UI {
using System;
using System.Collections;
using System.Reflection;
using System.Web.Util;
[AttributeUsage(AttributeTargets.Property)]
internal sealed class IgnoreUnknownContentAttribute : Attribute {
internal IgnoreUnknownContentAttribute() {}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
internal sealed class CollectionBuilder : ControlBuilder {
private Type _itemType;
private bool _ignoreUnknownContent;
internal CollectionBuilder(bool ignoreUnknownContent) { _ignoreUnknownContent = ignoreUnknownContent; }
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override void Init(TemplateParser parser, ControlBuilder parentBuilder,
Type type, string tagName, string ID, IDictionary attribs) {
base.Init(parser, parentBuilder, type /*type*/, tagName, ID, attribs);
//
PropertyInfo propInfo = TargetFrameworkUtil.GetProperty(parentBuilder.ControlType,
tagName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.IgnoreCase);
SetControlType(propInfo.PropertyType);
Debug.Assert(ControlType != null, "ControlType != null");
BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;
// Look for an "item" property on the collection that takes in an integer index
// (similar to IList::Item)
propInfo = TargetFrameworkUtil.GetProperty(ControlType, "Item", bindingFlags, types: new Type[] { typeof(int) });
if (propInfo == null) {
// fall-back on finding a non-specific Item property
// a type with overloaded indexed properties will result in an exception however
propInfo = TargetFrameworkUtil.GetProperty(ControlType, "Item", bindingFlags);
}
// If we got one, use it to determine the type of the items
if (propInfo != null)
_itemType = propInfo.PropertyType;
}
// This code is only executed when used from the desiger
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override object BuildObject() {
return this;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override Type GetChildControlType(string tagName, IDictionary attribs) {
Type childType = Parser.MapStringToType(tagName, attribs);
// If possible, check if the item is of the required type
if (_itemType != null) {
if (!_itemType.IsAssignableFrom(childType)) {
if (_ignoreUnknownContent)
return null;
string controlTypeName = String.Empty;
if (ControlType != null) {
controlTypeName = ControlType.FullName;
}
else {
controlTypeName = TagName;
}
throw new HttpException(SR.GetString(SR.Invalid_collection_item_type, new String[] { controlTypeName,
_itemType.FullName,
tagName,
childType.FullName}));
}
}
return childType;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override void AppendLiteralString(string s) {
if (_ignoreUnknownContent)
return;
// Don't allow non-whitespace literal content
if (!Util.IsWhiteSpaceString(s)) {
throw new HttpException(SR.GetString(SR.Literal_content_not_allowed, ControlType.FullName, s.Trim()));
}
}
}
}
|