|
Monday, June 27, 2005 COM Interop: VFP COM objects and ASP.NET
Many VFP developers face the need of consuming VFP COM components in either
ASP.NET Web Applications or Web Services. That’s normally a good way to reuse
business logic you’ve built over time in VFP. However, when dealing with VFP
business logic accessed as a COM component, one must also deal with security.
This represents a common pitfall.
Let’s say you create a VFP COM component that exposes the business logic you
want to consume from .NET. In that case, a .NET web application tries to
instantiate this object (going through the COM Callable Wrapper, or CCW, for
short). This commonly causes a “System.AnauthorizedAccessException” exception,
because the "user" (the web application) doesn’t have access rights to the
folder where the COM component is physically located.
Normally, users accessing a web application (without any specific
authentication specified) get logged in using the generic ASPNET user, which has
very limited rights on the computer. In order for the application to work, the
ASPNET user must have read rights to the folder the COM component is located in.
Therefore, to provide access to the VFP COM component from within .NET, make
sure that the ASPNET user account is granted read access to that folder. Also,
make sure you do NOT grant write-access to the folder. In general, you want to
set the access rights for that account as low as possible to prevent hacking
attacks. Also, only assign read rights as specifically as possible. Do not (for
instance) allow read access to an entire harddrive!
There also is a way to avoid the nastiness of messing with the ASPNET user
account altogether: VFP COM components can be registered in COM+ (a task that
only requires a few clicks and no programming changes). In COM+, one can specify
a specific user account that is used to run the component. This way, one can
create a special user account and use it for the purpose of interop only. As
long as that account has access to the component, no other changes in the
security system are required, and the ASPNET user account remains locked down,
and therefore limits the attack surface hackers have to work with. The downside
of this approach is the overhead that gets introduced, both in terms of
administration and performance. Nevertheless, this is the recommended
approach.
Posted @ 3:52 PM by Lassala, Claudio (lassala@foxbrasil.com.br)
Sunday, June 19, 2005 Static Code Analysis
Creating code of high quality is difficult. For this reason, software
projects need a very good process that concerns itself with code quality.
Developers are testing, testers are testing, code reviews take place, automated
tests are performed on the UI, database, and object levels, and - in
environments like .NET - a new technique known as "Static Analysis" is used. So
what is this "Static Analysis" exactly?
Static Analysis basically refers to automated code reviews. Consider this
simple example for instance:
o=CREATEOBJECT("wwIPStuff")
o.cMailServer="mail.yourmailserver.net" o.cSenderEmail="rstrahl@west-wind.com"
o.cSenderName="Rick Strahl" o.cRecipient="somebody@sweat.com,another@bust.com" o.cSubject="wwIPStuff Test Message" o.cMessage="Who said this
had to be difficult?" o.SendMail()
This sends an email from VFP using West Wind's IPStuff (www.west-wind.com). It is a relatively
simple object to use, and is very powerful at the same time. However, people
tend to have some problems with this, because unless the object is used
correctly, it does not work. People often forget to send the email server
setting, or set it incorrectly.
Of course, this is something that can be handled with code reviews, where the
person in charge of the code review can verify, that "mail.yourmailserver.net"
is in fact the correct server to use. Static Analysis does the same thing, but
instead of having someone in charge of that code review, there is software that
does this. The question is: How can this be done reliably?
Static Analysis really only works well with strongly typed languages. In the
example above, it is extremely difficult to write an algorithm that loads
thousands of files of source code and reliably analyze what "o.cMailServer" is
and what it should it be set to. However, if "o" is stronly typed, it is very
easy to look at it through strongly typed technologies such as ".NET Reflection"
or ".NET Introspection", where it is easy to ensure that "o" really refers to
"wwIPStuff", and create a simple set of rules that define how wwIPStuff is to be
used, and what the rules are for the "cMailServer" property. (Note that in
addition to strong typing, this also requires another technology that supports
the parsing aspect...)
In Visual Studio, up to version 2003, Static Analysis is done through a tool
known as FxCop (www.gotdotnet.com/team/fxcop).
FxCop ships with thousands of rules right out of the box, and it can be enhanced
with different rules of your own (in fact, our own Claudio Lassala is presenting
a session about this very topic at this week's DevTeach conference - www.devteach.com). Starting with Visual
Studio 2005, Static Analysis will be integrated right into the Visual Studio
environment.
The advantages of Static Analysis are clear: One can perform very advanced
code reviews that do not overlook problems and at the same time include massive
amounts of code. In fact, with Static Analysis, one can code-review 100% of all
source code (in fact, rules can be defined that only allow code to be checked
into source control if all static analysis rules were passed). Of course, there
are always special cases that need to be reviewed manually, but with Static
Analysis, that becomes a much more approachable problem.
The increase in quality achieved through static analysis are amazing! Best
practices and rules can be easily enforced and communicated. Much more so than
training ever could. Also, the simple fact that every line of source code
written will be analyzed causes most developers to write much cleaner code to
begin with.
Posted @ 2:41 PM by Egger, Markus (megger@eps-software.com)
Tuesday, June 14, 2005 Live from DevCon 2005, Las Vegas
After the opening session presented by Microsoft's Ken Levy and Randy Brown
last night, DevCon is now in full swing with it's first full day of sessions
today.
The keynote last night was interesting, especially since Microsoft just
posted the new VFP Roadmap, and attendees were eager to learn more about how to
interpret the announcements. In particular, people have come to Las Vegas to
learn more about the "Sedna" project, which is scheduled for release in 2007.
What exactly is Sedna? Will it be called VFP10? What does the future hold?
After the keynote and the first day of the conference, some of these
questions have been answered to a certain extent, but it is also clear that even
Microsoft has yet to make a lot of decisions in the next 2 years before the
project is brought to completion. However, at this point the interpretation that
seems to emerge (and that Microsoft seems to be guiding attendees to) is that
Sedna can be seen either as an Add-On to VFP9, or as VFP9 - Service Pack 2. The
core engine of the product will not be modified in Sedna (except for bug-fixing
perhaps) and the focus is clearly on .NET and Windows Longhorn adoption for VFP
developers.
This certainly does not mean that VFP is not a viable product anymore. It
simply means that there are other technologies that VFP developers should also
be thinking about in the future. VFP will remain a Win32 product, and will not
be migrated to the Managed Platform or 64-bit. While for some scenarios, Win32
may still be a viable solution, other projects may require a more up-to-date
implementation and VFP developer should plan accordingly in the long term (or
possibly even in the near future... depending on the project).
Most of the keynote demos focused on early ideas for Sedna, with
presentations including anything from relatively simple interop scenarios, to an
early demo of Avalon UIs using .NET WinForms components, which in turn used
FoxPro data.
Sadly, attendance at this year's DevCon is a little down from last year's.
(Official numbers have not been announced, but several attendees seem to have
been busy trying to count attendees themselves, and guesses range from 160 to
200 attendees). Unfortunately, many of the old Fox Gang members are not
attending DevCon anymore. However, those who are still active and many of them
are now blogging. For more information on the conference, check out David Stevenson's Talking Fox Blog,
or Alex Feldstein's
Blog.
The conference content is good as always. Many of the regular conference
sessions deal with features new to VFP9, or with .NET adoption for VFP
developers. The conference overall is a pretty good deal for attendees, since
all attendees are free to attend other conferences that are held here at the
same time, such as a SharePoint conference, and Access conference, a .NET
conference, and an SQL Server conference.
If you have missed this conference however, there still is time to get into
the next event of similar nature: DevTeach (www.DevTeach.com) in Montreal is just around
the corner!
Posted @ 1:37 AM by Egger, Markus (megger@eps-software.com)
Friday, June 10, 2005 Going to DevCon...
Advisor's Visual FoxPro DevCon 2005 is just around the corner!
This weekend, several people associated with VFPConversion.com will be heading
to Las Vegas to present: Claudio Lassala, Rick Strahl, Kevin McNeish, Rod
Paddock, and myself (Markus) will all be presenting. Feel free so seek us out at the
conference and chat about technology (or other topics).
After recent Microsoft announcements, the keynote is highly anticipated.
Expect some posts right from the conference over the next few days.
For details, visit http://advisorevents.com/cmt0506p.nsf/w/main-cmx
If you missed DevCon, you can still sign up for the next conference with
FoxPro content: DevTeach in Montreal (www.DevTeach.com).
Posted @ 9:48 AM by Egger, Markus (megger@eps-software.com)
Thursday, June 09, 2005 Declarative UI Development: Is it new for VFP Developers?
With WinFX, Microsoft introduces a completely new UI technology called
"Avalon", and with it, a completely new way of defining these UIs (among other
things) called "XAML" (pronounced "zamel"). (Note: I will be teaching a session
about Avalon at the upcoming DevTeach conference in Montreal - www.DevTeach.com). XAML is a way to define
UIs "declaratively". What does that mean? It means that rather than using
traditional programming techniques, one simply "declares" what the UI looks
like. An example explains what it means:
In Visual FoxPro, we would create a form with controls on it like so:
oForm = CreateObject("Form") oForm.AddObject("btn1","CommandButton") oForm.btn1.Top =
10 oForm.btn1.Left = 10 oForm.btn1.Caption = "Hello World" oForm.AddObject("txt1","TextBox") oForm.txt1.Top =
30 oForm.txt1.Left = 10
And so forth. In Avalon on the other hand, one can declare the same thing
like so:
<Window> <Button ID="btn1"
Top="10" Left="10">Hello World</Button> <TextBox ID="txt1" Top="30" Left="10"/> </Window>
This is a slightly simplified version of the real Avalon syntax, but you get
the idea. (Of course Avalon still also supports programmatic declaration of the
UI similar to how its done in VFP of WinForms today).
If you are interested in more information about the declarative programming
concept, check out my recent CoDe Magazine eColumn: http://www.code-magazine.com/Article.aspx?quickid=050053.
All this declarative programming is a hot new thing for WinForms developer,
and in many ways rightfully so, since it provides a number of advantages (see my
article for some details). However, when I talk to VFP developers, they often
seem to be sceptical about the whole concept. I am not really sure why. I
understand that the syntax is different from what we are used to, but is the
concept really new? Give this a try:
USE (HOME(2)+"Solution\forms\Launch.scx") cXml = "" CursorToXml("Launch","cXml") ? cXml
As you will see, this conceptually is very similar to what Avalon does. Sure,
the syntax is a bit different, but the concept is the same. Creating a form in
an SCX or VCX is really very close in concept to declarative programming. Much
closer than it is to traditional programmatic development. The main different is
that VFP stores the declaration of the UI in DBF files, while Avalon uses XML.
But that's mainly a storage mechanism and has little influence on the
concept.
Some may say "but I am never exposed to the DBF structure of a form when I
create it", and that's true! But guess what: So far, Microsoft has not shown any
visual editors for XAML, but there is no doubt that there will be. In fact,
third parties have already presented such editors (see www.erain.com for an example).
Does that mean that there is little difference between Avalon and VFP forms?
No! Avalon is a much more powerful UI technology than any of the current windows
UI packages can provide. It is a 3D-based, fully graphics accelerated UI geared
towards highly professional and highly polished user interfaces. But I find it
interesting to see that a fundamental concept introduced in FoxPro 15 (or more)
years ago, still provides great value today!
Posted @ 10:04 AM by Egger, Markus (megger@eps-software.com)
Wednesday, June 08, 2005 Passing Arrays to a .NET COM object from Visual FoxPro
A number of people have asked me about passing arrays
to .NET functions from Visual FoxPro applications. The problem here is that
Visual FoxPro arrays are not formatted the right way to just be called to a .NET
COM object by default. VFP arrays are 1 based while in general COM objects
expect arrays to be 0 based so you need to fix up arrays to make this happen.
.NET arrays are always 0 based unless explicitly declared
otherwise.
Assume you have a method in a .NET COM object that looks
like this:
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("DotNetCom.DotNetComPublisher")]
public
class DotNetComPublisher
public
string PassArray(object[] Objects )
{
string Output = "";
foreach(object Customer in Objects)
{
// *** Must access array by using
Reflection
Output += ComUtils.GetProperty(Customer,"Name") + " " +
ComUtils.GetProperty(Customer,"Name") + "\r\n";
}
return
Output;
} }
And you want to pass an object like
this:
loAddr
= CREATEOBJECT("EMPTY")
ADDPROPERTY(loAddr,"Name","Rick
Strahl")
ADDPROPERTY(loAddr,"Company","West Wind")
ADDPROPERTY(loAddr,"Date",DATETIME())
loAddr2
= CREATEOBJECT("EMPTY")
ADDPROPERTY(loAddr2,"Name","Rick
Strahl")
ADDPROPERTY(loAddr2,"Company","West Wind")
ADDPROPERTY(loAddr2,"Date",DATETIME())
DIMENSION
loAddrArray[2]
loAddrArray[1] = loAddr
loAddrArray[2] = loAddr2
To .NET. Your first try likely looks like
this:
LOCAL
loNet
as
DotNetCom.DotNetComPublisher
loNet
= CREATEOBJECT('DotNetCom.DotNetComPublisher')
? loNet.PassArray(@loAddrArray)
which will fail with Invalid Parameter
type.
The key to make this work is to use the COMARRAY()
function in VFP to mark the array as 0 based and passed by
reference:
LOCAL
loNet
as
DotNetCom.DotNetComPublisher
loNet
= CREATEOBJECT('DotNetCom.DotNetComPublisher')
COMARRAY(loNet,10)
? loNet.PassArray(@loAddrArray)
And this works correctly passing the objects to .NET.
To return arrays works as well. Take the following
.NET method:
public
Customer[] ReturnArray(int Count)
{
Customer[] Customers = new
Customer[Count];
for (int x= 0;x < Count;
x++)
{
Customers[x] = new
Customer();
Customers[x].Company = "West Wind " +
DateTime.Now.ToString();
Customers[x].oAddress.StreetAddress =
DateTime.Now.ToString();
}
return
Customers;
}
Which you can retrieve like this in
FoxPro:
LOCAL
loNet
as
DotNetCom.DotNetComPublisher
loNet
= CREATEOBJECT('DotNetCom.DotNetComPublisher')
loArray =loNet.ReturnArray(3)
lnCount
= ALEN(loArray,1)
FOR
x=1
TO
lnCount
loCust =
loArray[x]
?
loCust.Company
?
loCust.oAddress.StreetAddress
ENDFOR
RETURN
Note that you are not getting the Array object that
.NET is returning. There’s no Length property for example, but rather VFP
marshals this .NET array to a standard array. Actually .NET returns this array
to COM as a COM compatible SafeArray and VFP picks that up and exposes the array
as a VFP array object. You won't need to use COMARRAY() on the returned
array.
A final option that I like to use in many situations is to
not pass arrays as parameter or return types directly, but rather pass objects
that contain arrays. The advantage is that you get more control over the data
and you have a chance to potentially call COMARRAY() with other marshalling
options.
Posted @ 2:02 PM by Strahl, Rick (rstrahl@west-wind.com)
Wednesday, June 08, 2005 Subclassing with Designer Support
Visual Studio has very fancy visual designers (such as the form designer).
They are different from the designers in FoxPro in that they work directly of
the source code file. For instance, when you add a button to the form and set
the button's caption to "Hello World", the form designer creates the following
source code snippet (or similar... this is a condensed version):
// // button1 //
this.button1 = new System.Windows.Forms.Button(); this.button1.Location = new System.Drawing.Point(312, 128); this.button1.Name = "button1"; this.button1.TabIndex = 2; this.button1.Text = "Hello World!";
As you can see, the button gets created, and then all the required properties
are set. The million-dollar-question is: Which properties are "required"? The
simple answer would be: "All the properties that have changed". And this is the
correct answer, except: How do we know which properties have changed? To know
that, we also have to know what the propertie's default value is. In FoxPro, the
designer can look in the VCX and find out. In .NET, things are not quite this
simple.
The people writing the .NET designers have come up with the following
solution. Each property can have an attribute attached that defines the default
value. If we were to add a custom property, this could look like this
example:
public class Xxx {
private string myCaption =
"Hello";
[DefaultValue("Hello")] public string Caption {
get {
return this.myCaption; }
set {
this.myCaption = value; }
} }
The attribute (red) allows the designer to figure out the default value for
the Caption property. Therefore, whenever the caption is "Hello", no
source code line will be created, since the default value is OK, but if the
caption was set to something else, the designer would create the appropriate
source code line.
The situation gets a bit tricky when we start subclassing controls. For
instance, we might want to subclass the default label control and set
AutoSize to true. Conceptually, this can be done very easily
like so:
public class MyLabel :
System.Windows.Forms.Label { public MyLabel() {
this.AutoSize = true;
} }
So far so simple. However, the AutoSize property has a DefaultValue
attribute of false. Therefore, whenever the auto size of our new label
is set to true (which would be the newly programmed standard value for the
property), the designer thinks that according to the DefaultValue attribute, it
is NOT the default, and thus creates a line of code the specifically sets the
property to true again. This is redundant, but unless we change our
class again, not a big problem. On the other hand, if we were to drop this label
on a form and set its AutoSize property to false, the designer looks at
the DefaultValue atttribute and says "cool... that's the default value anyway...
no code needed" and does NOT create the line. Therefore the property can not be
set to false anymore, which pretty much makes it useless. To fix the
problem, we must not just change the propertie's value, but we must also
override the property itself, so we can set the new attribute:
/// <summary> ///
Auto size /// </summary> [DefaultValue(true)]
public override bool AutoSize {
get { return
base.AutoSize; } set {
base.AutoSize = value; } }
As you can see, the override itself only calls the base functionality without
any other changes. We simply had to override to attach a new DefaultValue()
property, which allows the designer to work right. Unfortunately, with this
little trick, we may have lost some other functionality. The property
description may not show up correctly anymore for instance, and we may have to
duplicate the original Description() attribute as well.
This is probably one of the most annoying things in .NET OOP. I have been
lobbying to get this changed for a while. Right now, we will have to deal with
the situation. Luckily, the C# and VB.NET editors make it relatively easy to
code all of this...
Posted @ 8:44 AM by Egger, Markus (megger@eps-software.com)
Tuesday, June 07, 2005 What exactly is an 'Inner Class'?
OK, some people had questions about the last blog entry. I mentioned that
"inner classes" are stored in the same file as regular classes. So what exactly
is an "inner class". So here's the deal:
In Visual FoxPro, there is basically one type of class. No differences, no
strings attached. In .NET, there are many different types of classes. For
instance, there is the standard "class", which is very similar to a class in
VFP. Then, there is a "struct", which is rather similar to a class, but
completely different in terms of internal handling (especially memory
management). Then there are completely different types of classes, such as
Delegates and Enums (those will probably be a topic of a future post).
Inner classes are classes that are defined in other classes. One would do
this for classes that are only needed inside of another class. Consider this
example:
public class Xxx { private Yyy internalDataStore =
new Yyy();
publicvoid
DoSomething() { this.internalDataStore.Something(); } }
class
Yyy { publicvoid
Something() { // Something
} }
In this example, class Xxx uses class Yyy for internal purposes only. So why
define class Yyy in a way that is visible to everyone and may confuse people?
That's exactly where inner classes are important. The following example defines
class Yyy within class Xxx and is thus only available to class Xxx.
public class Xxx { private Yyy internalDataStore =
new Yyy();
publicvoid
DoSomething() { this.internalDataStore.Something(); }
class Yyy
{ publicvoid
Something() {
//
Something } } }
Posted @ 9:14 PM by Egger, Markus (megger@eps-software.com)
Monday, June 06, 2005 About Assemblies, Classes, VCXes, and how they all relate...
One of the things in .NET that seems to throw Fox developers for a loop, is
how to organize their .NET classes in source files.
FoxPro developers are generally used to putting multiple classes in a single
file, such as a .PRG or a .VCX file. As a result, many VFP developers end up
putting several .NET classes in a single .VB or .CS file, thus treating it very
much like a class library. In FoxPro, this makes sense, because a class library
is a file that contains multiple classes, and in the Fox-world, that is
generally a VCX file (or VCX plus VCT combination). In .NET however, the closest
concept there is to a "class library" is an assembly. Assemblies are
the compiled versions of a collection of classes and therefore very similar to
class libraries (all classes in a project get compiled into a .DLL or .EXE
assembly), although one can also see assemblies as applications (especially when
they are compiled into EXEs).
In .NET, there are mostly downsides to putting a multiple classes into single
source files: Source control gets tougher, editors can not handle multiple
classes in a single assembly, .NET developers are generally not used to having
multiple classes in a single file and therefore have a hard time navigating
projects,...
As a rule-of-thumb, at EPS, we put each class in its own source file. There
are very few exceptions to this rule. "Inner classes" for instance, are always
in the same file. Sometimes, Enums or Delegates are in the same file as the
class using them. But as a general rule, keep things separate, and your .NET
life will be a lot smoother.
Posted @ 10:39 AM by Egger, Markus (megger@eps-software.com)
Monday, June 06, 2005 VFP-to-.NET Conversion Training - Montreal
DevTeach 2005 (www.DevTeach.com) is
just around the corner, and with it, a 2-day VFPConversion.com pre-con seminar,
presented by industry expert Kevin McNeish.
Topics include: C# and VB.NET primer, Object-Orientation in .NET, Data Access
in .NET, Creating Windows Forms Applications, Creating Web Forms Applications,
Best practices for porting Fox applications to .NET, and .NET to FoxPro Interop.
All content is presented from a VFP perspective.
For further details and to sign up, visit http://www.eps-cs.com/VFPConversion/Training/Index.aspx.
Posted @ 10:28 AM by Egger, Markus (megger@eps-software.com)
Thursday, June 02, 2005 Microsoft announces Future-of-VFP Roadmap
Microsoft published a "Microsoft Visual FoxPro Roadmap" to help developers
figure out the appropriate path forward. Details can be found at: http://msdn.microsoft.com/vfoxpro/roadmap/
The roadmap includes the first public announcement of "Sedna", the project
the Microsoft VFP Team is currently working on. ("Sedna" is an object in our
solar system beyond Pluto, the 9th planet...). Sedna will help VFP developers to
make the move to .NET much more easily. Sedna is an add-on product to Visual
FoxPro 9 and will ship sometime in the first half of 2007 (after the release of
Windows "Longhorn"). Microsoft has not announced any plans for a new version of
Visual FoxPro. Microsoft has also announced that Visual FoxPro will remain a
Win32 product. It will of course continue to work in WinFX and 64bit scenarios,
but only in compatibility mode.
For VFPConversion.com, this represents a new chapter in our existence. While
initially, VFPConversion.com was even criticized by some as "stabbing Microsoft
in the back", it has now become much clearer that VFPConversion.com is very much
in line with Microsoft's plans for the future of Visual FoxPro.
For additional information, visit Ken Levy's blog at http://blogs.msdn.com/klevy/ (Ken
is Microsoft's VS Data Product manager, and also the "public voice of Visual
FoxPro).
Posted @ 7:05 AM by Egger, Markus (megger@eps-software.com)
Wednesday, June 01, 2005 Welcome to the VFPConversion Blog
Welcome to the brand-new VFPConversion.com blog! This blog is slightly
different from regular blogs in that it is written not by a single person, but
by an entire group of people who can provide valuable information about
VFPConversion topics. Expect this blog to provide detailed technical information
about Visual FoxPro and .NET and very little fluff that often plagues personal
blogs.
We hope you will find this new feature useful, and are looking forward to
your feedback!
Sincerely, Markus Egger
President and Chief Software Architect, EPS Software Corp. - www.eps-cs.com Publisher, CoDe Magazine -
www.code-magazine.com www.eps-software.com - www.MarkusEgger.com
Posted @ 7:10 AM by Egger, Markus (megger@eps-software.com)
|