Reputation: 9411
I am developing an asp.net component that requires many parameters. It will be called from classic ASP. I can of course pass in 10-20 parameters, but I'd love to be a bit tidier.
I'm fairly confident I could pass in an array, but ideally I'd like to be able to pass in an object.
Is this possible?
I decided to do a little test. The Classic ASP:
Dim objDictionary
Set objDictionary = CreateObject("Scripting.Dictionary")
objDictionary.Add "startDate", startDate
objDictionary.Add "endDate", endDate
MyComponent.checkObj(objDictionary)
In my ASP.net component I have:
public string checkObj(object config)
{
return "StartDate is " + config.startDate;
}
Edit:
I have progressed the issue so I'm changing this: I created an abstract class and now it's checking against that and building perfectly. At run time I am now getting and error - Microsoft VBScript runtime error: Invalid procedure call or argument: 'checkObj' .
Is it possible to pass a collection into a com assembly?
Perhaps the problem is that the com component is receiving an object of type Scripting.Dictionary, and not the abstract class I created, but such a thing doesn't exist in .net?
Upvotes: 0
Views: 2202
Reputation: 350
I wanted to do something similar and so created a wrapper class for .NET DataRow. You could use a HasTable/Dictionairy/Other Custom Implementation as your backing store if you want.
I expose my "properties" using an Indexer Property on my wrapper object, so working with a property in asp-classic would look like this:
Dim lngCustomerId
lngCustomerID = CLng(objectWrapper("CustomerId"))
I expose my wrapper using a COM Registered .NET assembly. My wrapper inherits from DynamicObject and exposes the following by a COM visible interface:
[ComVisible(true)]
[Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IDynamicModel
{
dynamic this[string propertyName] { get; set; }
bool TryGetMember(GetMemberBinder binder, out object result);
bool TrySetMember(SetMemberBinder binder, object value);
}
I would think that TryGetMember and TrySetMember will not be necessary for your needs.
My wrapper class implementation looks like this:
[ComVisible(true)]
[Guid("YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY")]
[ProgId("COMLIB.DynamicModel")]
[ClassInterface(ClassInterfaceType.None)]
public sealed class DynamicModel : DynamicObject, IDynamicModel
{
#region indexer
public dynamic this[string propertyName]
{
get
{
dynamic propertyValue;
if (TryGetMember(propertyName, out propertyValue) != true)
{
propertyValue = null;
}
return propertyValue;
}
set
{
if (TrySetMember(propertyName, value) != true)
{
throw new ArgumentException("Cannot set property value");
}
}
}
#endregion indexer
#region Fields
private DataRow dataRow;
#endregion Fields
#region Properties
public dynamic GetAsDynamic { get { return this; } }
#endregion Properties
#region CTOR Methods
public DynamicModel()
: base()
{
DataTable dataTable = new DataTable();
this.dataRow = dataTable.NewRow();
}
public DynamicModel(DataRow dataRow)
: base()
{
this.dataRow = dataRow;
}
#endregion CTOR Methods
#region Dynamic Object Member Overrides
public override bool TryGetMember(GetMemberBinder binder, out object columnValue)
{
bool result = false;
columnValue = null;
result = TryGetMember(binder.Name, out columnValue);
return result;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
bool result = false;
result = TrySetMember(binder.Name, value);
return result;
}
#endregion Dynamic Object Member Overrides
#region Operations
public bool TryGetMember(string columnName, out dynamic columnValue)
{
bool result = false;
columnValue = null;
if (dataRow != null && dataRow.Table.Columns.Contains(columnName))
{
columnValue = dataRow[columnName];
result = true;
}
return result;
}
public bool TrySetMember(string columnName, dynamic columnValue)
{
bool result = false;
if (dataRow != null && dataRow.Table.Columns.Contains(columnName) == true)
{
dataRow[columnName] = columnValue;
result = true;
}
else
{
Type type = columnValue.GetType();
DataColumn dataColumn = new DataColumn(columnName, type);
result = TrySetDataColumn(dataColumn, type, columnValue);
}
return result;
}
private bool TrySetDataColumn(DataColumn dataColumn, Type type, object value)
{
bool result = false;
dataRow.Table.Columns.Add(dataColumn);
result = TrySetMember(dataColumn.ColumnName, value);
return result;
}
#endregion Operations
}
I hope this helps.
Upvotes: 0
Reputation: 2785
you could try using a .net object in your asp page like System.Collections.ArrayList or System.Collections.Hashtable instead of that dictionary...
<%@ LANGUAGE="VBSCRIPT" %>
<%
dim netObj
set netObj = server.createobject("System.Collections.Hashtable")
' or:
'set netObj = server.createobject("System.Collections.ArrayList")
%>
that should make things easier in your .net component
Upvotes: 1