Web Q&A

IDs as Anchors, Preventing Search, and More

Edited by Nancy Michell

Q I use <base href="https://go.msn.com/"> on my Web pages to control page performance. I want to provide a "back to top" link, implemented as follows:

Q I use <base href="https://go.msn.com/"> on my Web pages to control page performance. I want to provide a "back to top" link, implemented as follows:

On the top of the page I use:

<a name="top"></a>

On the bottom I use:

<a href="#top">back to top</a>

Of course, the easy approach doesn't work because the browser resolves this link as https://go.msn.com/\#top. So I need to build the href value for the back to top anchor within my ASP.NET code.

According to the standards, what should the format be in a case where there's a query string in the URL? Should it be this

https://www.foo.com/page.aspx#top?x=1

or this:

https://www.foo.com/page.aspx?x=1#top

A Actually, you can do this with even less code by putting id="top" in your <body> tag:

<body id="top">

A Actually, you can do this with even less code by putting id="top" in your <body> tag:

<body id="top">

There's no need for meaningless empty anchor tags. You can make your code even smaller by using the id attribute on the actual element you are trying to jump to. Instead of

<h2><a name="sectionfoo"></a>Here is headline for section foo</h2>

use this:

<h2 id="sectionfoo">Here is headline for section foo</h2>

You're just saving a few bytes, but it adds up for those larger pages. A link back to top looks like this:

https://www.foo.com/page.aspx?x=1#top

Q Is there HTML code for disabling full-text and other searches?

Q Is there HTML code for disabling full-text and other searches?

A A robots.txt file tells most robots what to do. You can put a robots.txt file in the root directory of your Web server. The file is plain text and looks like this:

User-agent: *
Disallow: /nosearch/ 
Disallow: /nosearch.htm 

A A robots.txt file tells most robots what to do. You can put a robots.txt file in the root directory of your Web server. The file is plain text and looks like this:

User-agent: *
Disallow: /nosearch/ 
Disallow: /nosearch.htm 

User-agent: * applies to all search engines. This tells search engines not to index any of the pages in this directory. For individual pages, use a meta tag in the HTML header like this:

<META name="robots" content="noindex, nofollow">

Other attributes you can add to the content, separated by commas, are: all, none, index, noindex, follow, and nofollow. Content="all" means all content is indexed and searchable. "None" means no content on the page is searchable; "follow" means all the links on that page can be crawled. And "nofollow" means none of them should be, and so on. For example,

<META name="robots" content="index, nofollow">

means that the content will be searchable, but the spider should not follow the links on that page to find more content to index.

Q I've been using Visual Basic® for a long time and I'm familiar with the Microsoft® .NET Framework, but I am by no means an expert in it. I really need help understanding some behavior a programmer on my team (who also has a background in Visual Basic) saw when using inheritance and overloading. This programmer has written what appears to be identical source logic in both Visual Basic and C#: a base class containing two functions taking single parameters (int and string), and a derived class which overloads the function and uses an Object data type.

Q I've been using Visual Basic® for a long time and I'm familiar with the Microsoft® .NET Framework, but I am by no means an expert in it. I really need help understanding some behavior a programmer on my team (who also has a background in Visual Basic) saw when using inheritance and overloading. This programmer has written what appears to be identical source logic in both Visual Basic and C#: a base class containing two functions taking single parameters (int and string), and a derived class which overloads the function and uses an Object data type.

The programmer creates an instance of the derived class and passes an int, string, and object. In Visual Basic .NET, the functions called are the int and string functions in the base class and the object function in the derived class. In C#, the object function appears to be called three times instead of the number corresponding to the data type. I don't understand this difference in behavior.

A What is happening is simple (see Figure 1). You have a method, test.DoSomething, which takes an object parameter—public void DoSomething(object value) . You then call this method three times:

tst.DoSomething(nr); 
tst.DoSomething(str); 
tst.DoSomething(2.3);

You shouldn't be surprised that when you call this method it runs and prints "DoSomething(object value)" three times. The int, the string, and the double (2.3) are upcast to object because object is the type your method takes. The test.DoSomething is then run three times with the expected output of:

DoSomething(object value) 
DoSomething(object value) 
DoSomething(object value) 

A What is happening is simple (see Figure 1). You have a method, test.DoSomething, which takes an object parameter—public void DoSomething(object value) . You then call this method three times:

tst.DoSomething(nr); 
tst.DoSomething(str); 
tst.DoSomething(2.3);

You shouldn't be surprised that when you call this method it runs and prints "DoSomething(object value)" three times. The int, the string, and the double (2.3) are upcast to object because object is the type your method takes. The test.DoSomething is then run three times with the expected output of:

DoSomething(object value) 
DoSomething(object value) 
DoSomething(object value) 

Figure 1 Sample Code in C# and Visual Basic .NET

C#

main() 
{        
    test tst = new test(); 
    int nr = 3; 
    string str = "drie"; 

    tst.DoSomething(nr); 
    tst.DoSomething(str); 
    tst.DoSomething(2.3); 
} 

public class testbase 
{ 
        public testbase(){} 
        public void DoSomething(int waarde) 
        { 
                Console.WriteLine("DoSomething(int value)"); 
        } 
        public void DoSomething(string waarde) 
        { 
                Console.WriteLine("DoSomething(string value)"); 
        } 
} 
public class test:testbase 
{ 
        public test():base(){} 

        public  void DoSomething(object waarde) 
        { 
                Console.WriteLine("DoSomething(object value)"); 
        } 
} 

/*Expected output: 
   DoSomething(int value) 
   DoSomething(string value) 
   DoSomething(object value) 

Program output: 
   DoSomething(object value) 
   DoSomething(object value) 
   DoSomething(object value)*/ 

Figure 1 Sample Code in C# and Visual Basic .NET

Visual Basic .NET

    Sub Main() 
        Dim tst As test = New test() 
        Dim nr As Integer = 3 
        Dim str As String = "drie" 

        tst.DoSomething(nr) 
        tst.DoSomething(str) 
        tst.DoSomething(2.3) 

    End Sub 

    Public Class testbase 
        Public Sub New() 
        End Sub 
        Public Overloads Sub DoSomething(ByVal waarde As Integer) 
            Console.WriteLine("DoSomething(int value)") 
        End Sub 
        Public Overloads Sub DoSomething(ByVal waarde As String) 
            Console.WriteLine("DoSomething(string value)") 
        End Sub 
    End Class 
    Public Class test 
        Inherits testbase 
        Public Sub New() 
            MyBase.New() 
        End Sub 
        Public Overloads Sub DoSomething(ByVal waarde As Object) 
            Console.WriteLine("DoSomething(object value)") 
        End Sub 
    End Class 

'Expected output: 
   'DoSomething(int value) 
   'DoSomething(string value) 
   'DoSomething(object value) 
'Program output: 
' = Expected output 

Visual Basic .NET, C#, and C++ are not the same languages; they do not behave the same way. However, it's easy to see why your programmer is surprised. The overload C# uses is less efficient because it requires the argument to be boxed. Visual Basic uses the more precisely typed overload. From the language specs, you can see that C# tries to use an overload on the derived class, if possible, while Visual Basic tries to use the best match. Why prefer a less efficient overload just because it's declared in the derived class?

Visual Basic avoids that problem by having an explicit Overloads keyword; you can't slip an overload past the Visual Basic compiler. The reason for the C# rules is to be resilient in the face of class evolution (versioning). This ensures that the addition of a method in a base class doesn't break code that binds to a derived class because of accidental overloading.

Q I would like to convert the following code snippet from C# to Visual Basic .NET:

public struct Control : Component{
   private int handle;
  
   protected int Handle{
      get{ 
         return handle; 
      }
   }
}

When I try to convert it, I get an error "structure cannot have inherits keyword." Is it possible for a structure to inherit an object in Visual Basic .NET?

Q I would like to convert the following code snippet from C# to Visual Basic .NET:

public struct Control : Component{
   private int handle;
  
   protected int Handle{
      get{ 
         return handle; 
      }
   }
}

When I try to convert it, I get an error "structure cannot have inherits keyword." Is it possible for a structure to inherit an object in Visual Basic .NET?

Following is the code that a C# to Visual Basic .NET converter generates (this code generates the "structure cannot have inherits keyword" error):

Public Structure Control
    Inherits Component
    Private handle As Integer
 
    ReadOnly Property Handle() As Integer
        Get
            Return handle
        End Get
    End Property
End Structure

A First, you bring up an interesting point for other readers—that there are many converters out there (see https://www.kamalpatel.net/ConvertCSharp2VB.aspx for one). While we don't endorse any, you may find them useful to play around with. Note, however, that converters can get confused if you leave out the open and close braces for functions and may have other issues. Make sure you go through the output code as it may contain errors. Overall, the converters do a decent job and minor tweaking will take care of most of the issues.

A First, you bring up an interesting point for other readers—that there are many converters out there (see https://www.kamalpatel.net/ConvertCSharp2VB.aspx for one). While we don't endorse any, you may find them useful to play around with. Note, however, that converters can get confused if you leave out the open and close braces for functions and may have other issues. Make sure you go through the output code as it may contain errors. Overall, the converters do a decent job and minor tweaking will take care of most of the issues.

On the question of this output code, it doesn't compile in C# either unless Component is an interface, not a class. The struct (in C#) and Structure (in Visual Basic) keywords imply value types, which do not support inheritance. Value types do support implementing interfaces, but this isn't of much use because you have to box the value type in order to use the interface. In other words, you end up with a structure on the stack and a copy on the heap. If Component is an interface instead of a class, then use Implements Component instead of Inherits Component.

Q I have a simple XML document (see Figure 2). I would like to query these nodes (in a Visual Basic 6.0-based app) using an XPath query. However, I'm having a problem querying all nodes. When I use the following query

Set oQueryElemList = oDOM.selectNodes("//TestCases/TestCase/
   Platforms[Platform='Client']")

I only get two test cases found when I'm expecting three. The TestCase with id=1 is skipped since the second <Platform> tag (which is of the value "Client") doesn't seem to be found.

Q I have a simple XML document (see Figure 2). I would like to query these nodes (in a Visual Basic 6.0-based app) using an XPath query. However, I'm having a problem querying all nodes. When I use the following query

Set oQueryElemList = oDOM.selectNodes("//TestCases/TestCase/
   Platforms[Platform='Client']")

I only get two test cases found when I'm expecting three. The TestCase with id=1 is skipped since the second <Platform> tag (which is of the value "Client") doesn't seem to be found.

Figure 2 XML Document

<?xml version="1.0" encoding="UTF-8"?>
<TestCases>
       <TestCase id="1">
              <Platforms>
                     <Platform>Server</Platform>
                     <Platform>Client</Platform>
              </Platforms>
       </TestCase>
       <TestCase id="2">
              <Platforms>
                     <Platform>Client</Platform>
              </Platforms>
       </TestCase>
       <TestCase id="3">
              <Platforms>
                     <Platform>Client</Platform>
                     <Platform>Server</Platform>
              </Platforms>
       </TestCase>
</TestCases>

How can I modify my query to tell it to read all child elements in the XML document?

A You can add the $any$ token

Set oQueryElemList = oDOM.selectNodes("//TestCases/TestCase/   
   Platforms[$any$ Platform='Client']")

or set the SelectionLanguage property to XPath:

oDOM.setProperty("SelectionLanguage", "XPath");
Set oQueryElemList = oDOM.selectNodes("//TestCases/TestCase/
   Platforms[Platform='Client']")

A You can add the $any$ token

Set oQueryElemList = oDOM.selectNodes("//TestCases/TestCase/   
   Platforms[$any$ Platform='Client']")

or set the SelectionLanguage property to XPath:

oDOM.setProperty("SelectionLanguage", "XPath");
Set oQueryElemList = oDOM.selectNodes("//TestCases/TestCase/
   Platforms[Platform='Client']")

Q I've written some VBScript code to handle synchronous events fired on a Microsoft Exchange folder. This script includes two subs: ExStoreEvents_OnSyncSave and ExStoreEvents_OnSyncDelete. For the Windows® Script Host (WSH) calling VBScript, the object name, ExStoreEvents, is prepended to the event handler.

Q I've written some VBScript code to handle synchronous events fired on a Microsoft Exchange folder. This script includes two subs: ExStoreEvents_OnSyncSave and ExStoreEvents_OnSyncDelete. For the Windows® Script Host (WSH) calling VBScript, the object name, ExStoreEvents, is prepended to the event handler.

I want to write a JScript® version of this same code since JScript has more robust error handling, providing more options and flexibility. I found an article on MSDN® (Scripting Events) which describes how the WSH hooks up to events in JScript. One method is to call WScript.CreateObject on an appropriate object, specifying a second parameter, which is the prefix to use on the event handler name. This doesn't appear to work since I only have an interface to work with, not an actual object. (The object appears to be hidden, so I can't instantiate one of them to specify a name prefix.) The other possible approach is to use an <object> tag for a .wsf file. However, this doesn't work either as the parameter to the "progid" field must also be an automation object and I'm back to the same problem I have with the first approach. How can I write a JScript-based handler to catch these two events?

function Bill_ListView::EveDblClick(index){}

The problem is the name of the "object" to use. In Visual Basic, the name used is "ExStoreEvents", but there is no such object. In this case, what I have is an interface, IExStoreEventInfo, not an actual object (the interface is an object, but not of the proper form). Furthermore, even though the object IExStoreEventInfo is the proper interface, it can't be instantiated as there is no entry for it in the registry. (I looked under HKCR with the ExOleDB prefix and found nothing reasonable for an automation instantiation.)

A You said this doesn't appear to work since you only have an interface to work with, not an actual object, but this makes no sense. First, the question of what the interfaces are is irrelevant—neither JScript nor VBScript use any interface other than IDispatch to call methods on objects. Second, what does it mean to have an interface without having an object that implements it?

A You said this doesn't appear to work since you only have an interface to work with, not an actual object, but this makes no sense. First, the question of what the interfaces are is irrelevant—neither JScript nor VBScript use any interface other than IDispatch to call methods on objects. Second, what does it mean to have an interface without having an object that implements it?

If you're using WSH, here's the deal: if your object is cocreatable then you can bind events on it in two ways: use the <object> tag and use the :: syntax, or call WScript.CreateObject and pass in "Foo_" as the prefix. Event "Bar" will then be handled by function "Foo_Bar". If the object is not cocreatable, then you can use WScript.ConnectObject, but the object must support IProvideClassInfo. The underlying explanation is that the outgoing event interface is only accessible if the sink is able to get class type information about the object. That means either supporting IProvideClassInfo or knowing the classid is required for sinking events in late-bound languages.

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

Thanks to the following Microsoft developers for their technical expertise: Michael Beatty, Daniel Boerner, John Caffrey, Sunit Carpenter, Tantek Celik, Matt Curland, Peter Golde, Sean Grimaldi, Glenn Hackney, Phil Johnson, Anton Lapounov, Dan Liebling, Eric Lippert, Michael Rys.