Remarks by Anders Hejlsberg, Distinguished Engineer, Microsoft Corporation
Visual Studio .NET Launch — San Francisco
February 13, 2002
ANDERS HEJLSBERG: Thank you very much. Im going to start my talk today with a little bit of a historical perspective to sort of take you from the early days of computing to where we are now. Im sure if you look back at the history of computing and distributed applications youll see that every decade or so there is a shift in the center of gravity. Go back to the 70s with mainframes, you know, we did all of our computing on a server in the back room and connected with proprietary protocols and dumb terminals.
And then in the 80s the center of gravity shifted toward computing on the client. In fact, file servers would just sort of serve up files. There wouldnt be a lot of computing happening on the server; it would all happen on the client.
Now in the 90s with the Internet the center of gravity basically shifted back to a server model. The Net is very much like really an old IBM 3270 terminal, except you can connect to multiple different sites instead of just one server in the back room and, of course, HTML is a much richer protocol.
Now, people have talked about how maybe now the time has come for another shift towards the client with peer-to-peer computing, but we actually think that this time in this decade were going to finally see a balance. We’re going to have both computing on the server and the client. Were going to be able to still do a lot of stuff on the server like we do today, but also take advantage of some of the innovations that are sure to happen in handwriting recognition and speech recognition on the client.
In other words, we think were going to be able to have the best of both worlds. And the reason we think so is that we finally have a protocol set, an infrastructure that allows us to have intelligence on both ends of the wire, and thats XML and Web services.
One of the things about XML Web services, of course, is that a shift of that dramatic nature, you know, if you look at the vision for .NET its about information anywhere on any device at any time. But really no matter who you ask about their vision for distributed computing in the future, its all about distributed applications, connected applications. And we believe that XML and Web services are going to be the infrastructure for these distributed applications. But, of course, a shift like that also takes a new toolset.
And looking at where we are today, here are sort of a little bit of the history of the tools that have led us today with each of the previous decades really sort of had their own toolsets with text mode applications, GUI applications and then leading up to the Internet and the next set of tools in that evolution is what were here to talk about today is the .NET Framework Visual Studio .NET.
Now, when we shipped Visual Studio 6.0 about three and a half, four years ago now, we knew that we had built a great tool that was going to enable you, our customers, to build great solutions, but we also knew that in some of the areas of the tool we could do better.
For example, we really realized that the model for building distributed and connected applications simply was too complicated. If you look at the technologies that people have used up until now to build distributed apps or connected apps, its been technologies like DCOM or Corba, IIOP, RMI, you know, you name your favorite protocol. But I think all of those protocols are sort of characterized by the fact that the distributed applications are hard to build, theyre hard to deploy and theyre hard to maintain. We knew we could do better.
We also knew that we had too many different programming models and too many different programming languages that didnt really interoperate. You know, we had Visual Basic and C++ and ASP and so forth. We knew that our object system, COM, in many ways was not rich enough to do what people want to do in their programming today. COM doesnt support key object oriented concepts such as inheritance and polymorphism and at the same time we knew that COM was too complicated. COM is a very low-level binary standard. There is a lot of housekeeping that you have to do yourself with COM, worrying about results and add refs and releases and GUIDs and so forth.
At the same time, we were seeing, sort of, the Internet grow leaps and bounds and we knew through our work with XML and the W3C consortium where XML has been standardized, we knew that this was going to be the fabric upon which this new class of applications was going to be built.
But looking at all of these factors together, we also realized that we werent really going to be able to get there in an evolutionary way of just sort of modifying COM and DNA a little bit; we knew that we had to build a new platform.
And that new platform is the .NET Framework. Its a platform that natively supports XML Web services, that unifies our many programming models, that dramatically simplifies development, provides a robust and durable, secure execution environment, supports multiple programming languages and finally allows you to interoperate with the code that you have already written and put resources into.
Now, before I show you how we built the framework and drill into some of these bullet points here a little bit, let me first give you a block diagram overview of what the framework is.
It starts with at the bottom the operating system and on top of that we have what we call the common language runtime. This is a component that in day-to-day use of the framework you dont actually see this component. It provides all of the sort of core system services such as class loading, compilation, exception handling, garbage collection, security, et cetera, et cetera. So its sort of this black box that allows you to execute code in the .NET world.
On top of the common language runtime we have a whole set of class libraries, starting with the base class library that provides a bunch of common functionalities such as file IO, string handling, access to TCPIP, for example.
Built on top of that then we have ADO .NET, which is the next generation XML Web service-enabled version of ADO, and also our XML stack that starts all the way down at a low level XML parser, works its way up through a W3C DOM compliant XML document model and also supports X-PATH and a bunch of the other XML standards.
At the top of the class library stack we sort of have two buckets then. We have the server-side bucket and the client-side bucket. In the server side bucket we find ASP .NET, our application server, Web Forms, which is a programming model for writing forms in ASP .NET, support for Web services and the Mobile Internet Toolkit that allows you to build a UI for mobile devices.
And on the client side we have Windows Forms, which is in a sense you can think of it as an evolution of Visual Basic forms and MFC sort of put together. You get the best of both worlds in Windows Forms.
Now further on top of that we have this thing that we call the common language specification, and what that really is, it is a standard for the minimum set of functionality that languages must support in order to be implemented on the .NET common language runtime.
And supporting that common language specification we are ourselves shipping four languages: Visual Basic, C++, C# and J#. But industry partners are building, you know, at this point we have in excess of 20 languages supported on the runtime.
And then finally, of course, supporting the entire stack is the development tool Visual Studio .NET.
So lets take a little closer look at how we built this and what were sort of some of the key drivers in creating the framework and Visual Studio.
I talked about how up until now we have had too many different programming models, and the way to think about this problem is really again to take a historical perspective and look back at how we used to write Windows applications. If you go back, say, 10 or even 15 years, writing a Windows application, there was really only one way of doing that. You would fire up your C compiler. You would probably include Windows .H. You would look in your book and youd write Win cross and Windows message handlers and it was all quite complicated and not particularly productive.
And so over time weve seen a number of different programming models come to light. For example, Visual Basic pioneered the notion of rapid application development with composition of forms, where, you know, youd drag controls from a tool pallet onto a form and youd delegate to event handlers and write code behind in that way.
But C++ took a different route with MSC and ATL. Here we sort of used different paradigms such as sub classing. And while this might give you more power and expressiveness, its certainly not as easy to use as Visual Basic.
And then most recently with the Internet weve seen a whole new programming model spring up around stateless code in HTML pages that execute on the server, the ASP programming model.
And you could certainly imagine that we would just keep going and have a new programming model for writing Web services and a new programming model for writing mobile UIs, but there is an unfortunate fact about this sort of evolution here. One is that your choice of programming model inadvertently also becomes your choice of programming languages.
For example, if you think about MSC, if you were a VB programmer and there are features of MSC or ATL that you would like to use, its just not possible. Likewise, VB forms can only be used from Visual Basic. And if you want to write code behind an HTML page, well it would have to be script.
Another problem is that each of these different programming models has solutions to common problems that differ amongst them. So, for example, in each of these different programming models there is a way of doing file IO but its different between all of them.
Now, what the .NET Framework does is it unifies all of these programming models to give you consistent API availability, regardless of what your programming language is and regardless of what your programming model is.
Now, I talked about how another goal for the framework was to dramatically simplify development. And there are so many ways in which the .NET Framework does that that I cant even enumerate all of them, but Ive sort of put some of the high level bullets on this slide here.
First of all, I think the thing that the .NET Framework does is it moves up the level of abstraction. If you look at COM today, its a very low-level binary standard. I dont know if any one of you have ever done programming with C++ and COM, its horrible. You know, you have to deal with H results and GUIDs and add refs and releases and just every place you go there is ample opportunity for bugs to sneak in. And, as I said, COM really isnt rich enough today either. It doesnt support the core object oriented concept.
The framework really does away with all of that plumbing. It simply automates it completely and frees you to think about the algorithms instead of thinking about the housekeeping.
Another example here is how the framework provides a unified type system. In the framework everything can be treated as an object. Even an INT can be treated as an object, or a float. There are no variants; rather everything is object, so there is no dichotomy between objects and variants as you might have sort of come across in Visual Basic. There is one string tied for the entire platform and all character data is uni-code.
Finally, the platform provides support for component oriented programming or software component. Things like properties and methods and events are all first-class constructs in the .NET Framework. So its not like if you use C++ to create an Active X control, for example, theres all sorts of macro stuff you have to do to define its properties and its events and so forth, but its all native built into our languages in the .NET Framework.
Another final point would be the way our APIs are organized. It used to be with the Win 32 API that really its an enormous flat API. There really isnt any organization there. About the best we could do is take the 30,000 entry points and sort them alphabetically, but if you look at the framework everything is organized into logical name spaces. So if youre looking for something having to do with IO you would look in System.IO and there you would find a class called file, and it just sort of takes you to the place that you want to go.
One way of looking at the simplified development is also to sort of look at what you would write before and what you write today. Here is sort of a little — one of my favorites — a little example of what it takes to create a window using the Windows API. You first have to call create.window.ex and pass it no less than 12 parameters and then you have to show an update window in order to show it on the screen.
Compare that to what you do with the framework. You create a form. You set its caption and you show it.
Now, a lot of you I know are VB programmers and youre going,
“Weve had this for years. Whats new here?”
I think though that there are several things that are new, if you compare it to VB today. First of all, with VB today in order for you to get these easy APIs someone had to first write a wrapper around the API turning them into COM APIs. Thats sort of why VB has lagged behind. Often when new system APIs come out, they come out sort of in the C style of programming and then the VB team first has to wrap them and turn them into sort of easy to use APIs.
A second problem, of course, has been that once these APIs do get wrapped, youre not really speaking the same language as the other guy that talks about the low-level API and the documentation doesnt really apply and some things didnt get wrapped and therefore youre missing this and that and the other favorite feature of yours.
But I think perhaps most important is that this is the way we will author APIs at Microsoft going forward. There is not going to be any of this low-level gobbledygook anymore. We are moving the abstraction level up and writing APIs that are easy to use where you can pay as you go, so to speak, and not have to understand the entire API before you can write the simplest application.
I think another key thing that the .NET Framework provides is a robust and durable execution environment. In the .NET Framework all objects are garbage collected. Memory management is automatic.
Now, theres actually a difference here between how memory management works in COM and how it works in the .NET Framework. In COM there is also automatic memory management, but its done with a methodology called reference counting where you count the number of references outstanding for each object. And it works pretty well, if it wasnt for one intractable problem that no one has actually managed to solve so far. And thats the circular reference problem. If you have two objects that each holds references to each other, it looks to the memory manager as if these objects are still alive, yet no one else references them and so you create a little island of memory that never gets garbage collected.
The .NET Framework uses a different technology for memory management called mark and sweep, and Im not going to go into details about how it works but basically it circumvents entirely the problem of reference counting.
Another key thing to providing a robust execution environment is exception handling. Youre familiar in VB with
“on error go to”
and it certainly gives you some modicum of structured error handling. But still exception handling goes way further. When an exception is raised in the .NET Framework, every exception carries along a descriptive error message. You can obtain a stack dump from the exception and learn precisely what went wrong and where.
And perhaps most importantly error handling is mandatory in the .NET Framework. If you look at how the Windows API has worked traditionally and how languages actually have worked traditionally up until now with C, C++ and so forth, error handling has always been an optional thing. An API may have a function that returns an error code or a result code that says whether the API worked or not, but unless you actually write code to check the error result, you know, nothing will happen even when it goes wrong. Indeed, your application will so to speak muddle on and then three or four API calls later something blows up because of a null point or whatever and you have no idea how you ended up there.
Not so with exception handling. With exceptions if an exception occurs and if your application does not handle the exception, then the application will be shut down. It will be shut down in an orderly fashion, mind you, and you have ample opportunities to sort of unroll your state and so forth, but we will not muddle on by default, and that will definitely remove lots of bugs.
Type safety is another thing that brings about robustness. In the .NET Framework it is simply impossible to have unsafe typecast. You cant cast a pointer of one type to a pointer of another type; the execution engine will simply refuse to do it. Its impossible to have uninitialized variables. You cant index an array out of its bounds and so forth.
A key thing too is our Zero-Impact Install feature. This is, in fact, one of my favorites. With the .NET Framework when you write an application there is absolutely no requirement that anything be registered in order for that application to run. You can create a subdirectory, drop the application in there, run it and when youre done with it you can delete the subdirectory and it leaves no trace whatsoever on your machine.
Thats not to say that applications cant actually share information. We do support another model where you install into the global assembly cache, as we call it, and then applications can share libraries.
Another key, I think, innovation in the .NET Framework is side-by-side execution, which allows you to run and to have installed on your machine multiple versions of the same application. So you can have application version 1.0, version 1.1 and version 2.0 and you can run them side by side. You can even run objects from these applications within the same process.
Now, what this means is that no longer will you have sort of the DLL-hell problem that occurs when you install a newer version of some DLL and one of your applications breaks because of it.
Instead, by default with the .NET Framework your applications simply continue to run against the versions of libraries that they request. So like I said, you can have version 1.0, 1.1 and 2.0 of some database support library and various applications can continue to use various versions and therefore by default you are ensured that applications will not break when you install newer applications on a machine.
So the .NET Framework is a multi-language platform. From the very beginning of us designing this platform we knew that we wanted to support multiple programming languages on this platform. Its important for us not to make people learn one single language but rather for them to be able to leverage their skills with the programming languages that they already know and the code that theyve already written.
Another key thing here is that in the .NET Framework all the languages are first-class players. I alluded sort of a little bit earlier to the fact that APIs are not available to VB today unless they are first wrapped as COM objects. That is absolutely not the case in the .NET Framework. Any API that gets published on the .NET Framework is immediately available to VB or to any of the other programming languages that are implemented on the platform.
Indeed, our integration goes much further than anything that really has ever been seen before. For example, you can write a class in one language, inherit from it in another language, and instantiate it from a third language. The integration is that deep.
And, of course, it also means that the tools are highly leveraged. You actually really only need one integrated development environment and one debugger to use all of these multiple languages.
Now, we are providing five languages: VB, C++, C#, J# and Java Script or J-Script. But in industry and academia there are a number of languages that have been developed or are being developed currently, including languages such as COBOL, Fortran and APL.
Now, I mentioned earlier that the .NET Framework allows you to interoperate with your existing code. Because all of our languages are built on this common substrate called the .NET Framework the level of interoperability that you have between languages that are hosted on the framework is just so much higher than anything weve seen before.
There is really no difference in performance or in capabilities between writing in Visual Basic or in C# or J-Script or in any of the other languages that get implemented on this platform.
But its not enough to just interoperate between the languages in this new world. Of course theres a lot of code out there that was not written for the .NET Framework and we want to make sure that that code can still be fully leveraged, so that the .NET Framework provides interoperability with DLLs, with code that sits in DLLs through a mechanism known as P invoke or with COM and OLE automation object. Indeed any class you write in the .NET Framework can automatically be viewed as a COM object outside of the framework, and likewise any COM object can be automatically imported into the .NET Framework and be viewed as a class in there.
And finally through XML and SOAP we provide probably the best and most flexible way of doing heterogeneous systems integration.
So there is lots and lots of interoperability built into this simply because we think that Moores Law — at least in my mind Moores Law has already passed us. What are we going to do with gigahertz CPUs and 512 megabytes of memory? Back in the old days with 64k or 640k of memory, well, you could sort of start from scratch every time and it would take you maybe six months to write a program that took up all of the capacity of the machine. So you could get away with it. But today you cant. I mean, customers expect more and more and more and there is just endless capacity available and we have to find ways to leverage the software thats already been written.
Okay, so now let me switch gears a little bit and talk about Web services, about this Web service revolution that we think is currently in process and that Visual Studio .NET and the .NET Framework are going to be major enablers of.
Before we go into demos and so forth, I wanted to just spend a few slides here on explaining my view of what a Web service is. And really sort of in a nutshell the simplest way of thinking of it, for me at least, is that where HTML is about user to machine interaction, so is XML and SOAP about machine to machine interaction, but over precisely the same infrastructure.
Now, I talked earlier about how distributed computing and connected applications traditionally have been built with technologies like DCOM, CORBA, RMI and so forth. So what is it about Web services that make them a better technology for writing these distributed apps?
I think there are three key drivers here. First of all, XML Web services truly leverage the Web. They literally run on precisely the same infrastructure stack as HTML applications do today, all the way from the network all the way up through the HTTP protocol. Everything is the same. The only thing that changes with Web services is that instead of trafficking HTML, youre trafficking XML as the HTTP payload.
But, of course, this gives us tremendous leverage of whats already out there, and indeed if you have a Web application already implemented, adding Web services to that Web application may be as simple as adding a few lines of code or an extra page in the Web Site.
The second thing I think is that Web services allow for truly heterogeneous systems integration. Any kind of distributed application architecture has to support heterogeneous environments. You cant require that the same OS be present on both ends of the wire. You cant even require that the same middleware be present on both ends of the wire. With Web services while one end of the wire might be the .NET Framework, the other end of the wire could perfectly well be an Apache Server running a PERL script to parse out the XML.
The final thing I think is that XML Web services allow you to build truly scalable distributed apps. Again, if you look at the traditional distributed apps technologies they are all sort of called object remoting technologies, DCOM, CORBA and so forth, and really the way they make the world look is they try to make the entire world look like objects. It just so happens that some of the objects live on your machine and some of the objects run on other machines. And while that architecture works fine for inter-process communication on one machine or perhaps communication on a local area network, it really runs into problems when you start looking at geo-scale applications where your client is in San Francisco and youre talking to a server out in New York, because with these older technologies they basically try to hide the fact that your application is distributed and you cant really tell when theres latency on the wire. When you make this call its going to take a long time to complete, so you tend to hold state alive for long periods of time, which really hurts reliability because you cant do fail-over. You tend to engage in very chatty communications where you make a method call on this object and then he calls you back and then he goes,
“Oh, thank you.” “Oh, youre welcome,”
and so forth. And thats all very fine when youre on a single machine but the speed of light becomes a problem when youre talking out to the East Coast and you really want to understand what goes on the wire.
Now, contrast that with XML Web services where its almost like well the proof already exists that these applications can scale beyond anything that weve seen before because we already do scale them today with HTML. And like I said earlier, all were changing here is that were trafficking XML instead of HTML, but all the infrastructure stays the same. We know how to scale. We know that it can scale.
So what is the foundation for Web services? Well, of course, it starts with the ubiquitous communication provided by the Internet, and then on top of that the universal data format that is provided by XML. XML can be used to traffic any piece of data.
Now, on top of that we have a series of protocols that are all varieties of XML. We have XSD for describing types. We have SOAP for describing interactions or invocations of Web services. We have WSDL, the Web Service Description Language for describing Web services, and we have the discovery protocol.
On top of that then there is, if you will, the “Yellow Pages” of Web services, the registry of services called UDDI.
Now, key to all of this is that these are simple and open standards that have broad industry support. These are specifically not Microsoft standards; rather, these are standards that have all been built with industry partners in standardization consortia such as the W3C.
So how does a Web service work? Well, lets say that Im a Web service consumer and I want to talk to a Web service. Well, first I have to discover the Web service. I have to find it out there in the universe of Web services. And I can do that in a couple of ways. I can either go to the UDDI registry and look for Web services within a particular business segment of Web services that support a particular schema and the data is sorted in a variety of different ways, but common to all of it is that I get back a link to a Web Service Description Language document that tells me about the Web service that Ive found.
I could also just go directly to the Web Site of the organization that Im going to talk to and lets say I already know what their Web Site is and obtain a disco document or a discovery document that basically is a catalogue of all of the Web services that are available at this URL.
In either case I end up ultimately with a WSDL file or a Web Service Description Language file for the Web service, or rather I end up with a link to it and I can then go obtain this WSDL file. And from that I now can know how to engage in communication with the Web service, and so the final step here is actually go to talk to the service using the SOAP protocol with XML payload.
Now, the top three steps on the slide here are all design time steps, if you will. None of them happen in a running application. Only the last step happens in the running application. But all of the top three steps have complete support in Visual Studio. I can from within Visual Studio go to the UDDI registry. I can obtain a discovery file or a WSDL file and have Visual Studio automatically create me proxies for the Web service so that I simply can call a method that takes a bunch of parameters and then all of the infrastructure that goes below is automatically handled.
So thats sort of a little bit about what Web services are. Now, what is it that .NET brings to the table here? Well, if you look at how you develop applications, there are certain application concepts that are always common in your apps. Your apps tend to deal with data. There tends to be schema for this data. Your apps perform services, i.e. the functions of the application, and there is policy about how the application is invoked.
Now, if you look on the Web there are standards, either existing or emerging standards for these concepts on the Web today. Data can be described with XML. Schemas can be described with XSD. Services can be described with WSDL and invocations can be done using the SOAP protocol.
But when you write code, you dont really think about XML and XSD and so forth. You think more about — for your data you think of objects. For your schema you think of the classes of those objects. For your services, well those are the methods of your application, the functions of your application, so to speak, and invocation as well as calling those methods.
Well, the value that the .NET Framework brings is a bi-directional mapping between these concepts that you know as a programmer and use day to day and the standards that exist on the Web.
So the .NET Framework can, for example, take any object and turn it into XML automatically and likewise it can take a piece of XML and turn it back into an object. Likewise, it can take a class and create an XSD schema for the class or go in the opposite direction. The same is true for methods. The same is true for calls.
So basically the .NET Framework allows you to think of programming in the terms that you are comfortable with and then the framework handles the mapping to the infrastructure on the Web.
To make it a little more specific here, let me just show you what a little Web service might look like. Lets say I have written an order processor class that has a submit order method and the submit order method takes a purchase order object. In order to turn this into a Web service, I actually dont have to modify any part of the code. I just have to add an attribute to the code, a Web method attribute that tells the system please expose this method on the Web.
Now, I might actually want to do additional things like control the format of the XML that goes across the wire, so I could add additional attributes to my purchase order that specify that when this object becomes XML please put it into this XML namespace and for each of these fields in my object I can specify whether I want them mapped to XML attributes or to XML elements.
But key to it is that I can write a little piece of code like this and I can do it in another language. For example, here I implemented the Web services in C# and I can write a little bit of client code that uses it in VB. When I make up a new purchase order I say ship it to me and send the bill to Bill and do it today and submit the order.
And what happens when I do that is that the .NET Framework turns that invocation into SOAP formatted XML, traffics the SOAP envelope and the embedded object across the wire to the Web server. The Web server, so to speak, reconstitutes the object, does its work, sends back a result that gets turned into XML, comes back and gets turned into objects for me on the client. All of that happens completely automatically.
And, in fact, lets go take a look at this in a little demo here.
So youve seen on slides here some of the incredible capabilities of this platform. What Id like to do now is spend the next 15 minutes sort of doing a lap around .NET. Im going to build a Web service, first of al. Then Im going to test the Web service using my browser. Then Im going to add some data access logic to the Web service. And finally Im going to build a rich client application front end for the Web service. And finally Im going to deploy that rich client application.
So lets start out. And just to show you that there is absolutely no magic or strings attached here, Im going to use my favorite editor here, Visual Notepad, and just make it as simple as I possibly can. So well fire up Notepad and well just write the Web service from scratch right here.
So well start out and well say Im going to write a Web service. Id like the language to be C# since Im a little partial, and Id like the class that Im implementing to be called
Now, what I wrote here is a little header that tells ASP .NET that this file contains a Web service. And the rest of the file now is simply like a normal C# file. So in here I can say using system.Web.services and then I can write my class of public.class.my.service. And lets say I want to create a method in here called add that takes two integers and returns the result of adding them together. That actually is all my code right there for my Web service.
Now, the only last thing I need to do is I need to tell the system to please expose this method here as a Web service. And to do that, as I showed you earlier, I simply put a Web method directive on the method.
So let me save this and well call it demo.asmx And now lets fire up our browser and then let me try and hit this Web service. So Ill go to localhost/demo/demo.asmx and lets just take a step back and look at what happened here.
First of all, with ASP .NET every time I hit a Web page, ASP first looks to see whether this is the first time that Ive hit the Web page, and if it is it compiles it into IL. So what happened here, first of all, was that the class I just wrote got compiled automatically by ASP .NET. The second thing is that ASP .NET notices that my request is coming from a browser as opposed to from a Web service client, and so it creates a test page for the Web service automatically. And on this test page here you see it looked at my code and it figured out that, ah, theres an add method in here in the Web service and I can actually go ahead and call the add method by clicking on the link and then the test page wants me to pass the two parameters, X and Y, so well type in lets say 32 and 10 and well invoke the method, and at that point the method runs. It computes the results, 42, and that gets automatically trafficked back as XML.
So thats sort of in a nutshell a very simple Web service.
Now, if we go back to the test page again youll note that not only did ASP .NET automatically extrude this test page, it also did a little bit of analysis on my Web service to see if it adheres to all of these standards that are out there for Web services. And it actually discovered that I have not put the Web service into an XML namespace, which Im supposed to do if Im a good boy. So it suggests down here how I might go ahead and fix that in my code, but Im just going to go say well thats great; let me just copy and paste that little fix here. So well grab that and well go back to our Web service and well paste in that little attribute to put the Web service into a namespace.
Now, the reality is that doing arithmetic operations over the Web is highly inefficient — (laughter) — and in most cases people are probably going to do some form of data access in their Web services. And indeed when I look at how people build data logic into their applications, there tend to be sort of two schools of thought. One is that you model your data as objects. You have a customer object, an order object and so forth. You obtain the data from the database and then you create instances of your object and you populate the data in there and then you operate on those.
Another model is that you simply keep the data in its tabular form. You know, today that would be in a record set. With ADO .NET its called a dataset. But you basically just sort of treat it as buckets of data.
Im going to show you how we support both of those methodologies equally well. And let me start out by looking at the object way of building data access. And indeed lets say that in my Web service here I want to create a little contact database that I want to talk to as a Web service, and I want to model it as objects.
So first what Im going to do is Im going to paste in, since I dont want you to look at me typing all of this, a little class called contacts that contains a name, address and phone number. And then Im going to create a Web service that can return a list of contacts and Ill just paste that in here.
Now, of course, in the real world youre not going to just instantiate these objects on the fly here. Theyre going to come out of a database. I just wanted to show you how Web services can return and operate on structured data. And here you see my get contacts method returns an array of contact objects.
So lets try and save this and then lets go back to our test page and well simply refresh the test page. And you see two things happen here. First of all, ASP .NET discovers that my Web service file has been modified, so it recompiles. It produces a new test page and in this new test page the error diagnostic at the bottom is gone because Ive fixed the missing namespace, and I now have a link to the additional method that I wrote, the get contacts method. And lets try and click on that link and indeed since it takes no parameters I can simply invoke it by just clicking the invoke button.
And here you see the results nicely formatted in XML. Notice here how I did absolutely zero work to take this array of contact objects and turn it into XML, yet here it is, an array of contacts with each contact object having a name, address and phone number field, all of it done completely automatically.
Now lets just for the sake of argument say that someone had told me about the particular XML schema that they wanted for this contact database and lets say that they had wanted the data of each contact to not be trafficked using XML elements but rather using XML attributes.
Now, I can actually go back and use some directives in here that control the shape of the generated XML. To do that, Ill first say using system.xml.serialization and then well go down and we will add a few attributes to the fields of my object, and indeed we will say here when you turn this field into XML instead of making it an element make it an attribute called name. And lets do that to the other guys as well, so well copy and then well just paste a little bit here and we will say the address field turn that into an adder attribute and then finally take the phone field and turn that into the ID attribute on the object.
So well save this. Well go back and we will just refresh the results page of my Web service, which will reinvoke the Web service now with the new formatting in place. And here you see the shape of the XML magically changes to use attributes instead of elements.
So as you can see the tool gives you tremendous control over the wire format.
Now, the other way of trafficking data or the other way that applications manipulate data is that they just create and return full record sets that basically reflect the result of, say, a SQL query, and we can certainly do that also in our Web service. In fact, let me go back and let me add a bit more logic here. Ill add a few more using clauses first, so well import the data namespaces and then well grab a little method that we have and paste that in, and this is a little method called
It takes a query string. It then creates a connection. It creates an adaptor for that connection and then it creates a new dataset and fills it with the result of executing that query.
So well go ahead and save this and go back to our Web service. Well refresh the test page. You see it again it recompiles. We get the
method. We could invoke it and, of course, it takes a query string so well have to type in something. Well say select * from customers and well press enter.
Now, what you see here is the result of that SQL query returned as XML. Indeed, if we go down here first, here you see each of the entries in the table and theres a customer ID and name, blah, blah, blah, blah. But at the beginning of the XML there is also a description of the schema of the data. So the data not only contains the actual records; it also contains a description of what the record means so that a client application can understand how to display this data.
And indeed lets go try and build a client application that calls this Web service, so well shut down all these windows here and well fire up Visual Studio. And lets create ourselves a new project. Well create a Visual Basic Windows forms application and well call it client. And heres our Windows client forms designer and in here what well try and do in this little client app is well call the Web service and display the result of the Web service in a data grid. So were going to grab a data grid, put it on our form. Were going to grab a button and put that on our form down in the corner here, try and clean it up and make it look a little nicer. There we go.
Now, in order to call the Web service in here we first have to add a reference to it. And as I mentioned earlier, Visual Studio completely automates this step of importing the Web service description file and providing a proxy for the Web service. So we can simply right-click and say
“add Web reference.”
In here well just hit our Web service, localhost/demo/demo.asmx and here again we see again it tells us here the services that are available and we can just say add reference and import them.
Now we can go and write a little bit of code behind our button and in here well say
“dim S as new local host.”
Since I didnt change the namespace Im referring to my Web service as the local host namespace. And here you see statement completion on Web services. Here you see the My Service object that lives in the local host namespace and thats indeed the service I just wrote. So Ill just dim that up as an object.
And now I can refer to the Web service and what Ill do is Ill say
“data grid one.data source”
, so get the data source of my data grid to be the result of executing the get data method of my Web service. And again here you see statement completion on the Web service, it knows that theres a get contact and a get data method in there, and indeed when I pick get data it knows that Im supposed to give it a query string here, so Ill type in select * from customers, and I will pick the first of the tables that come back. A dataset, unlike a record set, can actually return multiple tables and well just pick the first one coming back.
So two lines of code in order to call the Web service. Lets try and run this app and heres the running app. And when we click the button we will now invoke the Web service. The result will come back as XML that gets put into a dataset and then we put a grid on the dataset.
Now, of course, your job isnt done when youve written a rich client application until youve deployed that rich client. And we actually permit you to deploy them very easily with the .NET Framework. Indeed, you can deploy your rich client apps just with a link on a Web page, and Im going to show you how to do that.
So Im going to first go to my project here. Im going to go to my properties and Im going to change my build output path to be the root of the Web Site that weve been working with. So when I build now, Visual Studio will drop the exe into the root of the Web server that I was building.
So well build and then were going to go back to Visual Notepad again and were going to write a little HTML page that links to the rich client application. So well start out with HTML and well make it H1 so you can all read it, and then well say
and then well create an H ref to client.exe, which sits in the Web servers root directory, so click here to run smart client application. Well close this off, okay, and well save this and we will just call it start.HTML.
0212 SF Anders Hejlsberg 3 of 3
So now lets fire up the browser and then lets hit this page, so well go to localhost/demo/start.HTML.
And here you see the little Web page that I just wrote that links to my client application. So when I click here — now its all happening on one machine, but when I click here, I actually downloading the application to my local machine and running it out of the Internet download cache.
So heres the app running and I can click the button and it can talk back to the Web service.
Now you go,
“Well, geez, what about security?”
(Laughter.) Well, this app is actually running in a sandbox at this point that protects it from calling any Web services other than Web service at the same URL that it came from. It cant create files on disk, et cetera, et cetera, a whole bunch of barriers are in place. And to show you that thats the case, Im going to close it, go back to Visual Studio and Im going to try and add an additional button to my application. And were going to write an event handler that tries to do something bad. Were not going to be too bad, so well just try to say create a file in the root directory of this machine. So well simply say system.IO.file.create and well try to create log.txt in the root directory.
Well build. That deploys now a new exe into the root directory of our Web server. Well go back to our start Web page. Well link again, which will download a new copy of the executable. You can see we got a new copy because we have two buttons now. (Laughter.) I can still call the Web service. But if I try to create a file in the root directory I get a security violation. And you see here it says the application attempted to blah, blah, blah, blah, blah thats not permitted by security policy.
Now, the interesting thing is I can actually continue to run because its all done through exceptions. Its just every time the app tries to do something nasty it gets stopped.
So in 15 minutes that was a quick overview of sort of all of the functionality that .NET provides be it for server, client and so forth.
Indeed, the core tenet of .NET is the triumvirate of client and server and services. And just like the .NET Framework provides the core infrastructure for developing applications that target these areas, so do Visual Studio .NET provide the complete development experience.
In the client space, for example, Visual Studio .NET allows you to create a multitude of different client applications, be it Windows forms as you just saw me do, be it Web forms or be it using the mobile Internet toolkit to create front-ends for mobile devices.
In the server space we provide rapid application development for the server. Just as youve been used to being able to create client applications by grabbing controls from a tool pallet and dropping them onto form, so can you now do that on the server and you can grab things like event logs or message queues onto a business object designer and build your business logic in a visual fashion.
We have incredible rich data access in Visual Studio. We have integrated data designers, query builders, et cetera, et cetera, and complete support for the .NET Enterprise Servers.
And, of course, as you saw with Web services Visual Studio .NET provides for the entire lifecycle of Web services through discovery, consumption, creation, registration and deployment.
Now, to give you a closer look at Visual Studio .NET, Id like to bring up Rob Copeland who is the product unit manager for Visual Basic .NET.
ROB COPELAND: Good morning. Well, youve seen a lot of really great things this morning. Youve seen some applications that were pre-built using Visual Studio .NET and the .NET Framework and Anders just took you through a great overview of the framework and how to build applications with the rich functionality thats there.
Im going to show you for a few minutes this morning how Visual Studio .NET makes creating those applications even easier.
Im going to start in the development environment and create a new project. So I click the new project button and this allows me to choose what type of project I want to create.
Now, Im going to say that I want to create a Web service that returns information about books. So I click ASP .NET Web service and I think Im going to call this my book info service and then I click okay.
Visual Studio now is going to go contact the Web server, create an application root for me, put the files up there that I need in order to create this Web service and then bring me back to a design view.
Now, this design view is a new feature Visual Studio .NET that gives me an easier way to use components and classes inside of my components that Im currently developing. Its very similar in a lot of ways to a form where I can drag and drop components, set their properties, handle their events without having to write all of that plumbing code. I can concentrate on my business logic and the code that I want my Web service to accomplish.
Now, Anders showed you how easy it is to create data and return that data as XML from a Web service. Im going to show a similar thing, but Im going to use some of the richer tools inside of the Visual Studio development environment.
Im going to bring up a new feature in Visual Studio .NET called the Server Explorer. The Server Explorer is a great way to get access to resources on servers that I want to program against. In this case Ive got two things here. Ive got data connections so I can look at SQL Servers and other types of databases, and Ive got a list of servers. Right now I just have the one, which is the machine that Im on, but I can add others to this list.
The thing I want to do is connect to a SQL Server and get some data back and then return it when somebody calls my Web service.
So if I expand this node I see a list of database diagrams and cables and stored procedures. If I expand tables heres a book table. This is the one that I want to use for my Web service. I can drag it and drop it onto this design surface. Visual Studio .NET then automatically creates the components that I need to get the data from the SQL Server.
In this case its created two components: a connection, which allows me to connect to the SQL Server and execute commands there, and whats called a data adaptor. And the data adaptor is this thing that actually gets the data back from the SQL Server, turns it into the form that I want and then puts it into a data set. And Anders talked about a data set just a few moments ago.
Now, as I said, this is similar to a form in many ways, except this is really just a class that Im working on here. But its similar to a form because I can click on these components, come over to the property window and set their properties. So, for example, maybe I dont want my Web service to be called service one. Its a simple matter of coming over to the property window and changing its name. Ill call it book service.
By default the data adaptor that was created for me will return all the records from the database. I really dont want all the records. I want someone to be able to tell me what books they want information on.
So going back over to the property window I can click the
“configure data adaptor”
link here and this brings up a wizard thats going to walk me through this. It asks me which data adaptor Id like to use. Theres only one on here so Im going to choose the default. And now it asks me how I want to update the data and get data from my SQL Server. By default I can use SQL statements, but Im going to choose to create stored procedures so that theyre living on the SQL Server and I get better performance and scalability. And Visual Studio .NET will automatically create those stored procedures for me.
When I click
can see what the default select that the wizard wants to use is and again its going to return all of the records, and I really dont want that. So I can click query builder, open this up and the ISBN is the thing Im going to have customers ask me for and then Ill return data on a given ISBN. So Im going to go to the criteria field here and type
and thats going to say ask me for an ISBN or let me ask for a certain ISBN number and then only return that book.
Now the wizard wants me to name the stored procedure and its going to automatically generate these for me, so Ill call the select one book select, insert Ill call book insert and so on. And then I click
Visual Studio .NET connects to the SQL Server and generates the stored procedures for me automatically.
So now Ive got an easy way to connect and get a single book back from my SQL Server.
Now, another great thing that I can do using the property window here is by default the form of the data thats coming back from SQL Server is the names of the columns in the database. And a lot of times my DBA names things in ways that I dont really want to use in my objects model. So I can go over to this table mapping property and bring up a dialog that allows me to name the tables the way Im going to use them for my program so that I can have an object model thats much more to my liking.
So here I see that they named the title in all caps, and my object models never have all caps, so Im just going to change it to a regular proper casing. And down here for the price they stuck this MNY in front of it to denote money I guess, but for me I just want it called price. So Ill click
Now Ive got this thing configured the way I want it so that I can interact with my SQL Server very, very easily.
I havent written any lines of code yet. Visual Studio .NET is taking care of all of these property settings and all of the work necessary to make these mappings happen for me.
Now, one last thing that I want to do is go back to my Server Explorer and Anders in his last slide talked about RAD for the server a little bit. And thats a set of features that Visual Studio .NET uses to allow you to more easily program against the server. The Server Explorer is part of that set of features but weve also created a set of components that makes common server task very easy.
In this case I want to use a performance counter to count how many people are hitting my Web service, so I can see if its got the capacity that I need, if I need to add more machines or change something about it.
So Im going to go and expand my server and I can see that Ive got a list here of event logs and message queues and performance counters that are currently on this machine.
If I expand the performance counter, boy, theres a huge list. The .NET Framework added a bunch of things. If I scroll down theres a bunch of SQL Server performance counters. But none of these are really what I want for my app.
So Visual Studio .NET makes it easy for me to create a new category of performance counters. I can right click and say
“create new category.”
Im going to call this the books category and then create a specific counter in that category, and in this case Im going to call it query count to count how many queries Im getting against my Web service. So Im going to hit
Visual Studio goes out and creates that performance counter on this machine for me and it can do the same thing on another machine on the network as long as Ive got privileges on that machine.
Now I can see that its created this category and heres the query count counter. In order to use it for my application I simply drag it off and drop it onto the surface and again Ive got a component now that I can easily use the property window, for example, to change read only from true to false so I can actually write it, and I can do a number of other things here. But the real benefit here is that you dont have to write the code to instantiate these components and set their default states. You do that visually and then you can concentrate on the code that you want to write for your Web service.
Well, now that Ive gotten all of these components set up, Im going to double click on the surface, which is going to take me to the code behind, much the same way that I go to the code behind a form, and in here Im going to essentially do what you just saw Anders do. Im going to create a public function, so Ill say public.function.get.info.for and the information Im going to return was a book and I want people to send me the ISBN number and they can send that as a string, and this function is going to return something that I forgot to put on here.
Let me go back; one last thing that I want to do. As Anders talked about and I talked about a little bit, datasets are the components that actually contain data when I execute queries against databases. And the datasets are disconnected from the database and sent across as XML. And in this case I need to tell this data adaptor to generate a dataset for me so that I can use it.
So Im just going to right click and say
Im going to tell it that I want to call it book info. And now heres a list of the tables that I could use inside my dataset.
The nice thing about the dataset is it can contain more than one table and it also can store the relationships between tables. In this case Ive only got one. Im going to tell it to go ahead and add this to the designer so I can use it easily from within this Web service.
There we go. Now Ive got my dataset called book info one.
Im going to switch back to my code and now I can finish this and say I want to return book info, which is that dataset.
So now Ive got a public function and all I need to do is a couple things here to invoke my SQL data adaptor, call the SQL Server, get back the data and return it. The first thing that I need to do is tell the SQL data adaptor what the ISBN number is. If you remember, I told it that I wanted a parameterized query. So here I go in and I tell it to take the select command, theres a parameter property here that lets me say which parameter do I want to specify. I want to specify the ISBN and I want to set its value to the ISBN that someone is going to pass in. So that sets up the stored procedure so that Im ready to call it.
So the next thing I need to do, I need to do SQL data adaptor and its got a fill method. This tells it to fill a dataset and the dataset on my Web service was called book info one.
I want it to also bump up my performance counter, and thats already on here and instantiated for me. All I have to do is say
“performance counter one.increment by one”
and now Im done. I just want to return my dataset, which is book info one. And now Ive got a fully functioning Web service and I used a lot of the functionality in Visual Studio to add quite a bit of value with very little code.
If I press F5 Visual Studio will automatically launch the browser and take it to my Web service and show me the same page that Anders was showing you that allows me to test out my Web service.
But it doesnt show anything, because I forgot to put Web method, which is the attribute that tells Visual Studio that this public function needs to be exposed as a Web method.
Now when I press F5 and it hits the Web service its got my get info for. I can go ahead; its going to ask me for an ISBN number. Luckily, I just happened to have one in my clipboard, so I dont have to remember to type that in. I click
It calls the Web service, which connects to the SQL Server. And as Anders showed you, I get the same type of thing back. I get a set of XML back. So its very easy to make use of server resources, SQL Server resources, performance counters and a whole myriad of things that are listed in the Server Explorer.
Now that Ive got my Web service — Anders showed you how to create a rich Windows client using Visual Studio .NET — Im going to create a rich Web client using Visual Studio .NET to use this Web service.
Im going to go over here and add an existing project that Ive already created and its at HTTP://localhost/bookapplication. And if I open this up Ive got a simple Web page. Its not very pretty. I havent had a chance to get a designer to look at it or anything yet, but its got a text box thats going to allow me to type in an ISBN number and its got a couple of labels here to put the author and the title of the book.
Now, the first thing that I need to do, and Anders showed us this just a moment ago, is tell Visual Studio .NET that I want to use a Web service. I go to the Web references node over here in the Solution Explorer and I choose
“add a Web reference”
and its already in my dropdown list here so I pick it.
Now, from here I can also check out the Web service and see how it works, just like I did when I was in the browser, but at this moment Im just going to say
“add a Web reference.”
Visual Studio automatically creates all the plumbing that I need to call that Web service and I call it just as if it were an object, so I have a very familiar programming model.
Im going to double click the button on the form and now behind here Im going to create a variable called WS and its localhost.bookservice. I need to create a variable to contain the return value, the data, so Im going to say dim data as. Now, again localhost. — and book info was my dataset.
Now, to call the Web service I simply can say data=WS.getinfofor. Now, Im going to take the value out of that text box that was on my Web page, textbox1.txt and call the Web service with it. Thats going to return and fill this dataset with data.
And then to put the data into the labels Ive got my author label. Im going to set the text value to data.
Now, as I said earlier, datasets can contain more than one table, so in this case I need to say that its data.books, because thats the table. Im going to say sub zero because its only going to have one row in it and sub zero is the first one. And now I can use statement completion to find the fields from the SQL Server data that I want to use, in this case author last name and then Ill do the same thing with the title field, data.book.subzero.title.
Now one last thing I need to do is tell Visual Studio that this is the project I want to run when I press F5. But one of the added benefits that Visual Studio has is very rich debugging. So lets just take a look at that real quick. Lets say that my Web service and my Web application isnt working properly and I need to find out whats going on. I can set a breakpoint in this code behind my Web page. I can go back over to my Web service and set a breakpoint in my Web service. And I can even go back into Server Explorer, go to the stored procedures. These are the ones that were generated for me. Open up the select stored procedure and set a breakpoint there.
And now when I press F5 Visual Studio is going to automatically launch the browser and take me to my Web application or that Web page that I just created. Here I can go ahead and paste in my valid ISBN number and hit get. Now, when I click
the code that I wrote behind the button is going to execute but I had a breakpoint there. So this code could be on another machine. Im still going to step into it for my Visual Studio development environment. I can use all of the rich debugging tools in Visual Studio.
I can press F8 and step.
Now, this next call is actually calling the Web service, which could be on yet another machine, but I can step onto the Web service, which is going to give it a call. All of a sudden I hit this breakpoint. I can hover over my values and see that its passing the ISBN in.
I can step here.
Now, this next call, which is the fill on the data adaptor, calls the stored procedure on the SQL Server. So when I step onto that I actually step into the SQL Server and onto the stored procedure and again I still get rich debugging. I can see what the values are and use the rich interfaces of Visual Studio to have a great debugging experience.
And I can continue F8 and just keep stepping through. Im going to press F5, which is going to bring the browser back up and finish it and fill in these fields from the SQL Server.
So I get a great set of features to allow me to easily create these applications and then debug them.
And one last thing that I want to show you that Im really excited about is a new feature in Visual Studio Enterprise Architect Edition, and thats Microsoft Application Center Test. So Ive shown you how easy it is to create these applications and debug them, but I also want to show you how its easy to test performance capacity on these things.
Ive got my performance counter running down here, and Im going to go ahead and add that performance counter that I created earlier. Actually, I need to refresh it so Im going to start it up again, get rid of these default things here and theres the books category and the query count and youll notice that when I put that in there Ive got a count of two, because Ive called this thing twice so far and my performance counter is actually working.
But what if I want to see what happens when lots and lots of people are calling these things? Im going to go in and start Application Centers Test UI and what this allows me to do is create tests to hit my Web service for me automatically so I can see what kind of performance Im going to get.
Im going to right click on tests and say create a new test. And I can create an empty test or choose to record a test. And what I would like to do is record a test. Its going to be in VB script, which is fine for me, and Ill say start recording.
Application Center Test starts up the browser for me. Now its recording what Im doing. So Im going to go in here, choose my Web application that I just was running, paste in my ISBN number again, choose get. Its going to go out and hit the Web service, get the data back, put it on the page.
If I go into my performance counter and look its bumped up to three because my Web service recorded that. But if I go back to my Application Center Test I choose stop recording, choose next to give it a test name — Ill call it book test and choose finish. Now Ive got book test over here on my list. I can look at the script that it generated if I want to. I can right click on it and there is a whole set of properties here where I can set how many browser connections do I want, how many users do I want to simulate, how long do I want the test to run. Im just going to lose those at default and click run. It starts up this little app and shows me whats happening.
If I go to my performance counter, gosh, Ive got a huge spike all of a sudden, because now we can see Im up to 400, 500. So it hits the Web service over and over and over again and I can come back to the Application Center Test and get a little graphical printout of how many requests per second, any errors and that sort of thing.
So this makes it very easy for me to test my Web service and see what kind of capacity it has.
All right, well, Im glad to be able to show you this morning how Visual Studio .NET makes creating .NET applications very easy, easy to debug and then easy to test. Thank you very much.
ANDERS HEJLSBERG: Thanks, Rob.
So today in Bills keynote you saw several customers that have already built and deployed applications on the .NET Framework Visual Studio .NET. Hopefully Rob and I have shown you how easy it is to get going with your applications, how easy it is to use Web services, and there is a lot of information that you can draw on out there already, over 150 books and magazines, training, more than 20 languages implemented on the .NET Framework, more than 65 Visual Studio integration partners, a whole slough of components vendors and more than 25 ASP .NET application hosting companies that can host your ASP .NET applications and Web services.
So start writing .NET applications today. Everything is there for you to do so. And on behalf of Bill and myself and the entire Visual Studio development team, I really want to thank you for being here at this exciting launch and I hope you have as much fun using this product as weve had building it.