1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional ASP.NET 3.5 in C# and Visual Basic Part 135 pot

10 215 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 221,53 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Your Interop library is automatically created for you from the ActiveX DLL that you told Visual Studio 2008 to use.. This Interop library is the RCW component customized for your ActiveX

Trang 1

Runtime Callable Wrapper (RCW)

.NET Code (C# or VB.NET)

ActiveX DLL or OCX (COM Component)

Your New NET Code

.NETs Built-In Interoperability Technology

Your existing ActiveX Component Code

Figure 28-6

The Runtime Callable Wrapper

The Runtime Callable Wrapper, or RCW, is the magic piece of code that enables interaction to occur

between NET and COM One RCW is created for each COM component in your project To create an

RCW for a COM component, you can use Visual Studio 2008

To add an ActiveX DLL to the References section of your project, choose Website ➪ Add Reference or

choose the Add Reference menu item that appears when you right-click the root node of your project in the Solution Explorer

The Add Reference dialog box appears with five tabs: NET, COM, Projects, Browse, and Recent, as

shown in Figure 28-7 For this example, select the COM tab and locate the component that you want to add to your NET project After you have located the component, highlight the item and click OK to add

a reference to the component to your project The newly added component will then be found inside a

newly createdBinfolder in your project

Your Interop library is automatically created for you from the ActiveX DLL that you told Visual Studio

2008 to use This Interop library is the RCW component customized for your ActiveX control, as shown previously in Figure 28-6 The name of the Interop file is simplyInterop.OriginalName.DLL

It is also possible to create the RCW files manually instead of doing it through Visual Studio 2008 In the NET Framework, you will find a method to create RCW Interop files for controls manually through a

command-line tool called the Type Library Importer You invoke the Type Library Importer by using the

tlbimp.exeexecutable

For example, to create the Interop library for the SQLDMO object used earlier, start up a Visual Studio

2008 Command Prompt from the Microsoft Visual Studio 2008 ➪ Visual Studio Tools group within your Start Menu From the comment prompt, type

tlbimp sqldmo.dll /out:sqldmoex.dll

In this example, the/out:parameter specifies the name of the RCW Interop library to be created If you omit this parameter, you get the same name that Visual Studio would generate for you

Trang 2

Figure 28-7 The Type Library Importer is useful when you are not using Visual Studio 2008 as your development

environment, if you want to have more control over the assemblies that get created for you, or if you are

automating the process of connecting to COM components

The Type Library Importer is a wrapper application around theTypeLibConvertorclass of the

Sys-tem.Runtime.InteropServicesnamespace

Using COM Objects in ASP.NET Code

To continue working through some additional examples, you next take a look at a simple example of

using a COM object written in Visual Basic 6 within an ASP.NET page

In the first step, you create an ActiveX DLL that you can use for the upcoming examples Add the Visual

Basic 6 code shown in Listing 28-1 to a class calledNameFunctionsClassand compile it as an ActiveX

DLL calledNameComponent.dll

Listing 28-1: VB6 code for ActiveX DLL, NameComponent.DLL

Option Explicit

Private m_sFirstName As String

Private m_sLastName As String

Public Property Let FirstName(Value As String)

m_sFirstName = Value

Trang 3

End Property

Public Property Get FirstName() As String

FirstName = m_sFirstName

End Property

Public Property Let LastName(Value As String)

m_sLastName = Value

End Property

Public Property Get LastName() As String

LastName = m_sLastName

End Property

Public Property Let FullName(Value As String)

m_sFirstName = Split(Value, " ")(0)

If (InStr(Value, " ") > 0) Then

m_sLastName = Split(Value, " ")(1)

Else

m_sLastName = ""

End If

End Property

Public Property Get FullName() As String

FullName = m_sFirstName + " " + m_sLastName

End Property

Public Property Get FullNameLength() As Long

FullNameLength = Len(Me.FullName)

End Property

Now that you have created an ActiveX DLL to use in your ASP.NET pages, the next step is to create a

new ASP.NET project using Visual Studio 2008 Replace the HTML code in theDefault.aspxfile with

the HTML code illustrated in Listing 28-2 This adds a number of text boxes and labels to the HTML page,

as well as the Visual Basic or C# code for the functionality

Listing 28-2: Using NameComponent.dll

VB

<%@ Page Language="VB" %>

<script runat="server">

Protected Sub AnalyzeName_Click(ByVal sender As Object, _

ByVal e As System.EventArgs)

Dim Name As New NameComponent.NameFunctionsClass()

If (FirstName.Text.Length > 0) Then

Name.FirstName = FirstName.Text

End If

If (LastName.Text.Length > 0) Then

Continued

Trang 4

Name.LastName = LastName.Text

End If

If (FullName.Text.Length > 0) Then

Name.FullName = FullName.Text

End If

FirstName.Text = Name.FirstName

LastName.Text = Name.LastName

FullName.Text = Name.FullName

FullNameLength.Text = Name.FullNameLength.ToString

End Sub

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>Using COM Components</title>

</head>

<body>

<form id="form1" runat="server">

<p>

<asp:Label ID="Label1" runat="server">First Name:</asp:Label>

&nbsp;

<asp:TextBox ID="FirstName" runat="server"></asp:TextBox>

</p>

<p>

<asp:Label ID="Label2" runat="server">Last Name:</asp:Label>

&nbsp;

<asp:TextBox ID="LastName" runat="server"></asp:TextBox>

</p>

<p>

<asp:Label ID="Label3" runat="server">Full Name:</asp:Label>

&nbsp;

<asp:TextBox ID="FullName" runat="server"></asp:TextBox>

</p>

<p>

<asp:Label ID="Label4" runat="server">Full Name Length:</asp:Label>

&nbsp;

<asp:Label ID="FullNameLength" runat="server"

Font-Bold="True">0</asp:Label>

</p>

<p>

<asp:Button ID="AnalyzeName" runat="server"

OnClick="AnalyzeName_Click" Text="Analyze Name"></asp:Button>

</p>

</form>

</body>

</html>

C#

<%@ Page Language="C#" %>

<script runat="server">

Trang 5

protected void AnalyzeName_Click(object sender, System.EventArgs e)

{

NameComponent.NameFunctionsClass Name =

new NameComponent.NameFunctionsClass();

if (FirstName.Text.Length > 0)

{

string firstName = FirstName.Text.ToString();

Name.set_FirstName(ref firstName);

}

if (LastName.Text.Length > 0)

{

string lastName = LastName.Text.ToString();

Name.set_LastName(ref lastName);

}

if (FullName.Text.Length > 0)

{

string fullName = FullName.Text.ToString();

Name.set_FullName(ref fullName);

}

FirstName.Text = Name.get_FirstName();

LastName.Text = Name.get_LastName();

FullName.Text = Name.get_FullName();

FullNameLength.Text = Name.FullNameLength.ToString();

}

</script>

Now you need to add the reference to the ActiveX DLL that you created in the previous step To do so, follow these steps:

1. Right-click your project in the Solution Explorer dialog

2. Select the Add Reference menu item

3. In the Add Reference dialog box, select the fourth tab, Browse

4. Locate theNameComponent.dllobject by browsing to its location

5. Click OK to addNameComponent.dllto the list of selected components and close the dialog box

If you are not using Visual Studio 2008 or code-behind pages, you can still add a reference to your COM

control by creating the RCW manually using the Type Library Converter and then placing anImports

statement (VB) orusingstatement (C#) in the page.

After you have selected your component using the Add Reference dialog, an RCW file is created for the component and added to your application

That’s all there is to it! Simply run the application to see the COM interoperability layer in action

Figure 28-8 shows the ASP.NET page that you created When the Analyze Name button is clicked, the

fields in the First Name, Last Name, and Full Name text boxes are sent to the RCW to be passed to

Trang 6

theNameComponent.DLLActiveX component Data is retrieved in the same manner to repopulate the text

boxes and to indicate the length of the full name

Figure 28-8

Accessing Tricky COM Members in C#

Sometimes, some members of COM objects do not expose themselves properly to C# In the

preceding examples, theStringproperties did not expose themselves, but theLong property

(FullNameLength) did

You know when there is a problem because, although you can see the property, you cannot compile the

application For instance, instead of the code shown in Listing 28-2 for C#, use the following piece of code

to set theFirstNameproperty of theNameComponent.dllActiveX component:

if (FirstName.Text.Length > 0)

Name.FirstName = FirstName.Text.ToString();

When you try to compile this code, you get the following error:

c:\inetpub\wwwroot\wrox\Default.aspx.cs(67): Property, indexer, or event ’FirstName’

is not supported by the language; try directly calling accessor methods ’NameComponent

.NameFunctionsClass.get_FirstName()’ or ’NameComponent.NameFunctionsClass

.set_FirstName(ref string)’

TheFirstNameproperty seems to be fine It shows up in IntelliSense, but you can’t use it Instead, you

must useset_FirstName(andget_FirstNameto read) These methods do not show up in IntelliSense,

but rest assured, they exist

Trang 7

Furthermore, these methods expect aref stringparameter rather than aString In the example from

Listing 28-2, two steps are used to do this properly First,Stringis assigned to a local variable, and then the variable is passed to the method usingref

Releasing COM Objects Manually

One of the great things about NET is that it has its own garbage collection — it can clean up after itself This is not always the case when using COM interoperability, however .NET has no way of knowing

when to release a COM object from memory because it does not have the built-in garbage collection

mechanism that NET relies on

Because of this limitation, you should release COM objects from memory as soon as possible using the

ReleaseComObjectclass of theSystem.Runtime.InteropServices.Marshalclass:

C#

System.Runtime.InteropServices.Marshal.ReleaseComObject(Object);

It should be noted that if you attempt to use this object again before it goes out of scope, you would raise

an exception

Error Handling

Error handling in NET uses exceptions instead of the HRESULT values used by Visual Basic 6 applica-tions Luckily, the RCW does most of the work to convert between the two

Take, for instance, the code shown in Listing 28-3 In this example, a user-defined error is raised if the

numerator or the denominator is greater than 1000 Also notice that we are not capturing a divide-by-zero error Notice what happens when the ActiveX component raises the error on its own

Begin this example by compiling the code listed in Listing 28-3 into a class namedDivideClasswithin

an ActiveX component calledDivideComponent.dll

Listing 28-3: Raising errors in VB6

Public Function DivideNumber(Numerator As Double, _

Denominator As Double) As Double

If ((Numerator > 1000) Or (Denominator > 1000)) Then

Err.Raise vbObjectError + 1, _

"DivideComponent:Divide.DivideNumber", _

"Numerator and denominator both have to " + _

"be less than or equal to 1000."

End If

DivideNumber = Numerator / Denominator

End Function

Next, create a new ASP.NET project; add a reference to theDivideComponent.dll(invoking Visual

Studio 2008 to create its own copy of the RCW) Remember, you can also do this manually by using the

tlbimpexecutable

Trang 8

Now add the code shown in Listing 28-4 to an ASP.NET page.

Listing 28-4: Error handling in NET

VB

<%@ Page Language="VB" %>

<script runat="server">

Protected Sub Calculate_Click(ByVal sender As Object, _

ByVal e As System.EventArgs)

Dim Divide As New DivideComponent.DivideClass()

Try

Answer.Text = Divide.DivideNumber(Numerator.Text, Denominator.Text)

Catch ex As Exception

Answer.Text = ex.Message.ToString()

End Try

System.Runtime.InteropServices.Marshal.ReleaseComObject(Divide)

End Sub

</script>

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title>Using COM Components</title>

</head>

<body>

<form id="form1" runat="server">

<p>

<asp:Label ID="Label1" runat="server">Numerator:</asp:Label>

&nbsp;

<asp:TextBox ID="Numerator" runat="server"></asp:TextBox>

</p>

<p>

<asp:Label ID="Label2" runat="server">Denominator:</asp:Label>

&nbsp;

<asp:TextBox ID="Denominator" runat="server"></asp:TextBox>

</p>

<p>

<asp:Label ID="Label3" runat="server">

Numerator divided by Denominator:</asp:Label>

&nbsp;

<asp:Label ID="Answer" runat="server" Font-Bold="True">0</asp:Label>

</p>

<p>

<asp:Button ID="Calculate"

runat="server"

OnClick="Calculate_Click"

Text="Calculate">

</asp:Button>

</p>

Trang 9

</body>

</html>

C#

<%@ Page Language="C#" %>

<script runat="server">

protected void Calculate_Click(object sender, System.EventArgs e)

{

DivideComponent.DivideClass myDivide = new DivideComponent.DivideClass();

try

{

double numerator = double.Parse(Numerator.Text);

double denominator = double.Parse(Denominator.Text);

Answer.Text = myDivide.DivideNumber(ref numerator,

ref denominator).ToString();

}

catch (Exception ex)

{

Answer.Text = ex.Message.ToString();

}

System.Runtime.InteropServices.Marshal.ReleaseComObject(myDivide);

}

</script>

The code in Listing 28-4 passes the user-entered values for theNumeratorandDenominatorto the

DivideComponent.dllActiveX component for it to divide Running the application with invalid data

gives the result shown in Figure 28-9

Figure 28-9

Trang 10

Depending on the language that you are using to run the ASP.NET application, you will see different

values for different sets of data For valid inputs, you will always see the correct result, of course, and

for any input that is over 1000, you see the Visual Basic 6 appointed error description ofNumerator and

denominator both have to be less than or equal to 1000

However, for invalid Strings, Visual Basic 2008 reportsCast from string "abc" to type ‘Double’ is not

valid.whereas C# reportsInput string was not in a correct format For a divide by zero, they both

reportDivide by Zerobecause the error is coming directly from the Visual Basic 6 runtime

Deploying COM Components with NET Applications

Deploying COM components with your NET applications is very easy; especially when compared to just

deploying ActiveX controls Two scenarios are possible when deploying NET applications with COM

components:

❑ Using private assemblies

Private Assemblies

Installing all or parts of the ActiveX component local to the NET application is considered installing

private assemblies In this scenario, each installation of your NET application on the same machine has,

at least, its own copy of the Interop library for the ActiveX component you are referencing, as shown in

Figure 28-10

Interop.MyCOM.dll MyApp.exe

C:\Program Files\First Application Location\

Interop.MyCOM.dll MyApp.exe

C:\Program Files\Second Application Location\

MyCOM.DLL

C:\Program Files\Third Party COM Controls\

(Managed Code) (RCW)

(Managed Code) (RCW)

(ActiveX DLL)

Figure 28-10

It is up to you whether you decide to install the ActiveX component as local to the application or in a

shared directory for all calling applications

It was once considered proper practice to separate ActiveX components into their own directory so that if

these components were referenced again by other applications, you did not have to register or install the

Ngày đăng: 05/07/2014, 19:20

TỪ KHÓA LIÊN QUAN