January 2004 - Posts

Sometimes you find a really cool site on the internet by checking your referrers. Nice work Chris and Charles! From their site:

Our Simple Goal
Our goal is simple: To provide a reference to the best sources on the web for the Office user, developer and IT support specialist. How do we plan to do this? We think we can do this by providing links to other useful websites, books, utilities, news, events and articles that will interest you as an Office enthusiast.

Ok, we have another goal: to be a reference that is always relevant, concise, focused and practical Office information. If you find a pointer or link on this website, you are guaranteed that it is something important and it is worth your time to consider. If you find that we are wrong, let us know. Quality and accuracy are very important to us.

Reading through their blog aggregation I found a nice trick by KC Lemson: Naming the colored flags in Outlook 2003.

Probably some old news, but today I stumbled over the Microsoft XSD Inference tool:

The Microsoft XSD Inference utility is used to create an XML Schema definition language (XSD) schema from an XML instance document. When provided with wellformed XML file, the utility generates an XSD that can be used to validate that XML file. You can also refine the XSD generated by providing the tool more wellformed XML files. The download contains the core library, simple command line utility and the source code.

There's an online version available, but you can also download it for offline use. On this GotDotNet page are some more tools and articles listed: intresting stuff...

Welcome to the Microsoft XML Tools Team site. This site is brought to you by the same team (Webdata) that brought you our complimentary Web site Microsoft MSDN XML  and the Extreme XML Column .

Our customers have told us that they would like to see Microsoft produce more tools to help them with their XML applications. This site is an effort to satisfy this need by providing various XML Tools and Utilities.

Did you ever wonder how you could replace the default generated test/help page of a web service by your own page? This could be useful in a number of situations: you could use your company lay-out, provide contact information or documentation, ... First of all: how is the default test page generated? There is a single ASPX file that takes care of this: DefaultWsdlHelpGenerator.aspx, which is located in the X:\<WindowsDir>\Microsoft.NET\Framework\v1.1.4322\CONFIG directory (for the .NET Framework V1.1). It's possible to alter this file, but be aware it will have an effect for all web services running on that machine!

Changing the test page for all the web services on the machine is probably not want we want to do, so a solution that would allow to change the test page for one web service would be nicer. To accomplish that we can use the wsdlHelpGenerator element in the <webServices> tag of the Web.config file. This element has an attribute called href which should contain the file path for the page we want to use as test page. The Web.config could look like this:
<system.web>
 <webServices>
  <wsdlHelpGenerator href="myDocs.aspx"/>
 </webServices>
 ...

</system.web>

If we now navigate to the web service (.asmx page), the contents of the myDocs.aspx page will be showed. But, we're still not yet there; this test page is used for all the web services of the current project. So if your project contains more then one web service, the myDocs.aspx should contain logic to display the corresponding information for each web service:
ServiceDescriptionCollection serviceDescriptions;

string ServiceName
{
 get { return serviceDescriptions[0].Services[0].Name; }
}

private void Page_Load(object sender, System.EventArgs e)
{
 //Get the serviceDescriptions
 serviceDescriptions = (ServiceDescriptionCollection) Context.Items["wsdlsWithPost"];
 if (serviceDescriptions == null)
 {
  serviceDescriptions = (ServiceDescriptionCollection) Context.Items["wsdls"];
 }

 switch(ServiceName)
 {
  case "Service1":
   Response.Write("Docs for Service1");
   break;
  case "Service2":
   Response.Write("Docs for Service2");
   break;
 }
}

First the serviceDescriptions collection is built, so the name of the service for which information is requested can easily retrieved by using the ServiceName function.

UPDATE: For solution when using WSE, see here!

Sometimes when you invoke a webservice the call fails with the following exception:

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.
at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at ...

In some cases the first call to the webservice works just fine, but if in the following few minutes no new call to the webservice is made, the next call would throw the exception shown above. This problem could be solved by altering the generated proxy class; in the GetWebRequest function the KeepAlive property must be set to false. This can be accomplished by following these steps:

  • Add a Web Reference using the normal way (if you haven't already added one ofcourse).
  • Make sure Show All Files menu item is enable in the Project menu.
  • In the Solution Explorer window, navigate to:
    • Web References
      • <Name of your webservice>
        • Reference.map
          • Reference.cs (or .vb)
  • Open the Reference.cs file and add following code in the webservice proxy class:
    protected override System.Net.WebRequest GetWebRequest(Uri uri)
    {
     System.Net.HttpWebRequest webRequest =
      (System.Net.HttpWebRequest) base.GetWebRequest(uri);
     webRequest.KeepAlive = false;
     return webRequest;
    }

Ted Neward (Editor-in-Chief of TheServerSide.NET) posted a link on this site to my previous post about Reporting in a SOA World. There are some intresting comments and links posted over there discussing how InfoPath can be (ab)used as a reporting engine:

  • Serve InfoPath Documents Dynamically, Drew Robbins
    “I created a little experiment to serve InfoPath documents dynamically from ASP.NET. Once opened, I wanted the form to already be populated with values from a database rather then having two views (Query and Data Entry). Then, the user could make whatever changes necessary and post back to a web service. The user could also save the document for offline editing and submit to the web service when getting back online later.“
  • Viewing InfoPath forms without InfoPath, Joel Alley (thx to Rolf Tollerud)

Update: Ingo Rammer has posted some comments too.

Besides that SOA (Service Oriented Architecture) is a cool buzz-word nowadays, it's also an architecture that can bring you some interesting advantages.O'Reilly webservices.xml.com has an article that provides following definition:

SOA is an architectural style whose goal is to achieve loose coupling among interacting software agents. A service is a unit of work done by a service provider to achieve desired end results for a service consumer. Both provider and consumer are roles played by software agents on behalf of their owners. ... How does SOA achieve loose coupling among interacting software agents? It does so by employing two architectural constraints:

  • A small set of simple and ubiquitous interfaces to all participating software agents. Only generic semantics are encoded at the interfaces. The interfaces should be universally available for all providers and consumers.
  • Descriptive messages constrained by an extensible schema delivered through the interfaces. No, or only minimal, system behavior is prescribed by messages. A schema limits the vocabulary and structure of messages. An extensible schema allows new versions of services to be introduced without breaking existing services.

I like to compare a SOA's facade (see also the Facade design pattern) as a single point of contact that hides the business object model and the technical implementation of the provided service. The only thing that I, as a consumer of the service, need to know is the location of that service. If I have to explain SOA I sometimes use the following metaphor: If I have a problem with my computer I call the helpdesk using the telephone number (= service location). Once connected they give me some choices: software related problems, hardware related problems, ... (the service describes itself). So I don't have to know the internal structure of the helpdesk and I don't have to know which department will take care of my problem (the complex structure is hidden).

There is a lot of information available on how to build and use SOA, but there is one area that keeps bothering me: reporting. In the “good old days” of pure two-tier Client/Server programming it was quite simple: the reporting engine connected directly to the database and fetches the data by executing SQL statements. Even in the three-tier and n-tier models this way of getting the data to the reporting engine stays the same.

So how would you deal with reporting in a Service Oriented Architecture? Of course you still could bypass the whole service layer (plus the layers beneath it) and connect directly to the database but you'd loose advantage of the facade so you'd have to deal with the possible complex database model. Connecting directly to the database also won't work in a distributed environment where the client and server are separated by the internet for example. (I know this statement is debatable because you could use SQLXML, but you'd have to expose your database server to the internet.). A solution could be building the report upon the results of a call to your service. A nice example of this way of working is InfoPath (assuming that the facade is exposed as a web service). You can create InfoPath forms based on web services, even complex XML structures can be transformed into good-looking forms. In my opinion this perfectly fits in a SOA.

But (unfortunately) InfoPath is not (yet?) usable as a reporting engine, it requires a client license and I don't know if it would be possible to pass a parameter to an InfoPath form without user intervention. Does anyone know if there are other solutions or products available?

My (free) ExtendedDataGrid control gets quite some attention and every developer knows that the more people use your software the more bugs will be reported. To organize bug reporting, feedback, feature requests, ... I've created a GotDotNet Workspace: http://workspaces.gotdotnet.com/extendeddatagrid. So if you have something to say about this control; please use the workspace.

New releases will be put in this workspace, so you can easily track them by using the RSS feed. Everybody who has contacted my concerning the ExtendedDataGrid: thanks for giving it a try. I'd like to ask you to post the reported bugs in the Bug Tracker. I'm sorry for the hassle.

Global Name Registry announced:

Breaking News: Global Name Registry will open up its second level for registrations, meaning names like spike.name, abc.name, pmorgan.name, will be available.

So if you're quick you can now get a hold of the [yourlastname].name domain! I've registered mine (tielens.name) at MyDomain.com for $29.90 / 2 years. They offer free URL and email forwarding, even for subdomains (I think unlimited). So you can now visit my blog by surfing to http://jan.tielens.name. I think it's quite cool because such a domain is not company related at all, you can have your personal email address like yourfirstname@yourlastname.name and let it forward to your current email address. When your email address changes (e.g. you change work, your ISP gets boughts by another company, ...) you can easily change the forwared to match your new address.

The free ExtendedDataGrid provides a framework to easily add virtually any UserControl to a DataGrid cell! It comes down to creating a custom control by inheriting from the ExtendedDataGridControl and implementing the desired functionality. Then this custom control can be added to the ExtendedDataGridControlColumn so in each cell your control will be rendered. All of this can be done by using the default Visual Studio.NET designers.



Add any user control to the DataGrid!

 

I've just finished the ColumnStyle and I've written very quickly a demo application, both can be downloaded from the ExtendedDataGrid site. In the next few days I'll try to document the grid a little bit more and write some cooler demo applications. In the meanwhile; if you have any questions or remarks, please let me know!

Yesterday I added two new ColumnStyles to the ExtendedDataGrid:

  • MultiLineTextBox Column
    This column has the same functionality as the normal DataGridTextBoxColumn, the only difference is that this column can display the text in a multiline TextBox. So when editing a cell, a TextBox with a vertical scrollbar is used.
  • ComboBox Column
    The ExtendedDataGridComboBoxColumn will display a ComboBox control when a cell is edited. The items of this ComboBox can be set at runtime, using for example an array, DataTable, collection...

On the ExtendedDataGrid site you can find a list of all features currently available. If you don't know the ExtendedDataGrid, check out my previous post. For short: it's a free Windows.Forms DataGrid with some additional functionality.

At this moment I'm working on a way to allow developers to easily extend the ExtendedDataGrid by adding a column which will be able to display any UserControl. There will be no need to create your own ColumnStyle for the UserControl, so the extending the DataGrid will be easier than ever! If you're intrested keep an eye on the latest news (RSS Feed).

More Posts