Web Q&A
InfoPath Back End, WSH Script Signing, and More
Edited by Nancy Michell


Q I've read a little about InfoPath lately, but I'm confused about what I need on the back end. Do I need to have a database, or does it make sense to store everything in XML files? From what I've read it seems like you can do that, but how efficient is it and is it recommended? Otherwise, would I use Microsoft® Access? Do I need Microsoft SQL Server™?


A InfoPath can handle any of the options you mention. Looking at the question from a best practices perspective, however, there is not always a single correct solution. You should evaluate the solutions for both online and offline situations.

Online solutions are typically connected to the network all the time. Ideally, these are best served using XML-based Web Service as the submission point. From within a Web Service you can push the data directly into a SQL database or a BizTalk® process. Even though you can use SQL Server or Access, you'll end up with a very tightly coupled solution when you send data directly to a database without a Web Service in between. Try to avoid this whenever possible, as Web Services offer better flexibility and control.

Offline solutions may never be connected to the network or may be connected only occasionally, typically in scenarios where people are using mobile devices and roaming around. For these situations, you should use either a local Access database, the Microsoft Data Engine (MSDE), or even local files. The data is really in a transitory state until it is pushed to its final resting place through an online solution. For example, replication or Microsoft Message Queue (MSMQ) can be used as a way of transmitting the data to the back end.

You should really think about this question in light of a services oriented architecture (SOA). SOA defines components as services, and InfoPath is simply a consumer of these services from the front end. People are often confused about where InfoPath stands in comparison with ASP.NET. They think they don't need an InfoPath solution because they're already doing everything as a Web Form. That is fine, but there are limitations. A better solution is to treat all services as a provider and then use InfoPath, ASP.NET, or Windows® Forms as the consumer. Once you abstract the back end, you need to look at how to get the data into a location that can be used. For example, you could push collection information into a SQL database for reporting or analysis.

For more information on InfoPath, see Aaron Skonnard's article in this issue of MSDN® Magazine.


Q I would like to use the signature verification policy available with Windows Script Host (WSH) 5.6 (see Signature Verification Policy). On MSDN Online, I found information on using signature verification policy in a Windows 2000 environment (in Windows 2000, the signature verification policy is set through the Local Security Policy editor), but I'm running Windows NT® 4.0. Can I use the signature verification policy of WSH 5.6 in a Windows NT 4.0 environment?


A The short answer is that you can install WSH 5.6, which features code signing, on Windows NT 4.0. The signature verification policy works wherever you can install WSH 5.6. Windows NT 4.0 is still supported, and there are setup packages available for it. Use the one labeled for Windows NT, Windows 98, and Windows Me.

Now, let's get down to specifics. What exactly do you want to do? If you want to use Software Restriction Policies (SRP), then you will have to use an operating system that supports it.

If you don't want to use SRP, there are some registry keys you can set. Under either HKLM or HKCU, take a look at the \Software\Microsoft\Windows Script Host key. Four values are relevant here: Enabled, TrustPolicy, UseWINSAFER, and IgnoreUserSettings. Here are their effects:

You can buy a certificate from VeriSign or install your Public Key Infrastructure (PKI), produce your own certificate, add your Certificate Authority (CA) to the list of trusted CAs on the machines, and so on. Next, sign the scripts (as described in Windows Script Host) using the certificate. Finally, you'll be able to turn on the Enabled, TrustPolicy, UseWINSAFER, and IgnoreUserSettings registry keys on the machines.


Q I need to know the best way to iterate over a large XML document. Let's say, for example, that I have a huge XML document that's basically organized like the following:

<Root>
   <ForestNode>
      <Node>
         <...>
            <...>
               ...
   <ForestNode>
      ...
Let's also assume that I have some node that is regularly repeated at some relatively high level. Think of a forest as a collection of a specific type of node. In my sample, there is a forest of Contact nodes (see Figure 1). Each forest node may be extremely complex, and I may not need to get all the information contained in every node. For example, say I have an XML representation of all the domains in my company. This representation may drill all the way down to the details of computers and users on the domain, and so on. But what if I'm only interested in getting a list of domain names in the company, or even just domain names that fall within certain criteria (domains in North America, for instance)? How can I retrieve only the information I need without walking through every node of the XML?


A The answer to this problem is a simplified mechanism that works with one main loop that goes over the forest nodes. The following while loop iterates the nodes, extracting just the information you need and processing it.

XPathNodeIterator ni = xdoc.CreateNavigator().Select(forestNode);
while (ni.MoveNext())
{
      XPathNavigator nav = ni.Current;
      
      string XPathStmt = "Name";
      myContact.Name = GetXPathValue(nav, XPathStmt);
      XPathStmt = "Age";
      myContact.Age = GetXPathValue(nav, XPathStmt);
 
      ProcessMyContact(myContact);        
}

This code is extracting just the name and age from the contacts. Figure 2 shows the entire process. Obviously, this is a very simple example. You could generalize this so that you can provide a list of XPath expressions and the location to put the data so you don't need to hardcode the data assignment.


Q I am writing an ASP page that deals with four different types of objects that have common features. It is a very simple design and the classes make it easy for me to make polymorphic calls. I have a case in which I would like to reuse some functionality and one option is to make it using inheritance. Of course, I can always make it a separate function. What is the correct way to implement object inheritance in JScript®?

If I have Base and Derived classes and their constructors

function Base()
{
// do something
}
 
function Derived()
{
// do something else
}
how can I call the constructor of Base from the constructor of Derived (and use the this operator)?


A The correct way is to rewrite your program in a language that supports class inheritance. Classic JScript does not support class inheritance, only prototype inheritance. However, JScript .NET supports both.

Why do you want to use class hierarchies at all? Class hierarchies were invented to provide abstraction and encapsulation to developers working in large teams on complex software. JScript was designed to provide a quick, easy way to write simple scripts on Web pages. The fact that you're asking at all makes me think that you're using the wrong tool for the job.

If you don't want "is a" relationships but do want code sharing, that's when you use prototype inheritance. However, there is no easy way to do a recursive descent on constructor functions, which is what you asked. Languages like C# do recursive descent on constructors because class inheritance strongly expresses an "is a" relationship. A Giraffe is a Mammal, so you'd expect the Giraffe ctor to call the Mammal ctor (which calls the Animal ctor, and so on) to ensure that the polymorphism works.

Prototype inheritance languages do not express "is a" relationships nearly so neatly. Instead, they keep a prototypical object and share implementation details through one. However, if all you want to do is share some methods, that's easy:

function Feed() {}
function Animal() {}
Animal.prototype.Feed = Feed;
 
var Bob = new Animal(); // create a new Animal, set its prototype to 
                        // Animal.prototype
Bob.Feed(); // Bob has no Feed method, but Bob's prototype does,
            // so we call it.
 
Now you can make this a little deeper by making Bob's prototype itself have a prototype (see Figure 3).

The Animal constructor is not called once per instance of Snake. Rather, it is called once for all instances of Snake, and the result is the "prototypical Snake."


Got a question? Send questions and comments to  webqa@microsoft.com.


Thanks to the following Microsoft developers for their technical expertise: Svet Bonev, Marco Crippa, John Lambert, Paul Leach, Eric Lippert, Mike Lonergan, Thom Robbins, Ben Smith, Michael Whalen.



© 2007 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.