CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Peter's Gekko

public Blog MyNotepad : Imho { }

January 2006 - Posts

  • Setting up a simple internet server (pt1)

    My company (which is just me) has a web site which really needs a big refresh. At the moment it is a static bunch of html on a Unix box. I want a lot more and taking a look at the wish-list there is only one way to get that all done without spending huge amounts of money: start hosting myself. I will blog a little about this project. No big stories on IT pro related stuff. Most of that is pretty intimidating and speaks in a different language as info directed at developers. I'll blog just some essential noteworthy details which I wish I had known in advance and hope you'll find useful as well.

    My server will be part of the internal network; will serve web and mail requests to the outer world and will serve internet access to the internal network. What do I need to start:

    1. A network plug connected to the internet with a static IP address
    2. Server hardware with a server OS,  a network card to connect to the internet and a network card to connect to the internal network
    3. Orchestrate IP traffic via this server

    The internet connection

    Quite a few DSL providers, but not all, have affordable subscriptions with a static address. I'm not unhappy at all with my current @home cable but they do not give any guarantee at all on the IP address, so they are out. XS4all, the Dutch provider with a great history (they were the first one to provide internet to the public over here) and a continuous stream of good reviews, offers an ADSL connection with a fixed address and good speed for an affordable price. They even encourage you to run your own server. Wherever you are living, shop around and you'll find great differences.

    The server hardware

    You need a piece of hardware which will be switched on night and day and should be built for that. It's not a problem to find affordable server hardware but watch what you buy. I've visited many an office which was terrorized by a blazing vacuum cleaner labeled Dell, HP or whatever. As I want to keep my office queit I needed something else. Which brought me to a company named ikbenstil (stands for I am silent) which is specialized in silent pc's and I bought their economy model. Its price is a little over that of a Dell but on the long run it will save money. Most machines make so much noise because of the huge fans needed to make sure all the heat gets out of the machine. My machine takes a different approach. It is very economic on its power consumption (amongst others by using an AMD Athlon processor) so there is less heat to get rid off. With energy prices going up and up that is a good investment. The ikbenstil company is somewhat geeky, not to good in communications and does make mistakes like forgetting the external power cable. But the machine is very well built and and I'm very very happy with it. Absolutely recommended.

    Orchestrating outbound IP traffic

    The server OS is Windows 2003 (what else ?). The first part of the installment should make the server the hub of all IP traffic coming in and going out. Up till now this was all handled by an access point where an onboard DHCP server gives all machines enough info to keep them connected. In the new scenario the server box is going to take this role. It has two network cards: one to hook up the ADSL. More on that in a later post. The other card is connected to the internal network. Using a dynamic IP addresses for this is no longer possible. When you choose an address it is a good idea to use one in a defined private range, like 192.168.x.x as that is secure. By definition no internet router will direct any (undesired) traffic to it. The server is administered via remote desktop. If you give the desktop client machine a static IP address as well you can set that as the only address from which a remote desktop is allowed. The nice thing is that Windows 2003 will choose this "all by itself". It is "secure by default" you have to open access bit by bit. For all other machines in the network it still does make a lot of sense to use DHCP. It gives me one central place to configure all of them.

    The first list of server's roles:

    • Domain controller (Active directory) AD is the API all other components use
    • DNS server. Direct outbound traffic
    • DHCP server. Orchestrate IP traffic

    Setting up the DHCP server is just a little more than next, next, finish. It should provide clients with:

    • An IP address
    • The address of the name server (what is the IP number of a site, mailbox or computer ?)
    • The address of the default gateway (where to send data for an IP address which is not on the local network ?)

    By default the DHCP server does not include the latter two. You have to do that by hand in the Scope options

    The IP address of the DNS is going to be that of the internal server network card. All requests to resolve names will be handled and controlled by my own DNS. The IP address of the gateway (or router) will be the ADSL connection. In this first step the server will only orchestrate the traffic, not handle it yet. So the gateway address will be that of the existing access point. The nice thing is that the moment I plug in the ADSL I have one point to change this setting.

    Configuring a DNS server looks like a quite intimidating task. In the end only setting the forwarders is important. In case the DNS cannot solve a request it will forward it to another (external) names server.

    In the forwarders list you build  a list of name servers to use. Take the Ip numbers of the name servers which are reached fastest over the actual connection (Provided they are reliable). Thanks to DHCP all machines on the internal network will now redirect their name queries to my own server. There I have one point of configuration for all name resolving. Right from the start, even without having the ADSL connected yet, all machines will have an advantage; a name server does a lot in caching and optimizing a request and the internal server is far easier to reach than any external.

    Now my server is in control of all IP traffic. When the ADSL connection is up and running I'll blog a little on the external network part.

  • Horizontal vs vertical blogging

    In application development the terms horizontal and vertical development are sometimes used to distinguish two approaches. Vertical applications target a specific group of users; like health care or insurances in which they support the entire cycle of information management. Horizontal applications target one specific aspect of information management, like word processing, and try to provide this for almost any user you can imagine.

    Perhaps this is somewhat farfetched but I think I see something somewhat comparable in blogging as well. See it as going horizontal or vertical through time.

    A horizontal blogger slices through loads and loads of blogs and presents a list of interesting finds. Try interesting finds on Google, hit #3 and #4 will direct you to the (old dnj) blog of Jason Healey. The majority of his blog posts are a list of links; Codebetter is happy to be a supplier for such a meta-aggregator.

    A vertical blogger is building post upon post; a lot of CB'ers do that. Take Raymond's series on database basics or David who usually finishes his posts with a list of related posts. This way blogging turns into (thanks to comments) a form of interactive publishing.

    Just a thought...

  • The scope of the web.config file, with some notes on authentication and authorization

    In my last post I described a way to set up a web service. One of the requirements of the service was that it could share some of it's settings with a web site. In a first attempt I made the service part of the site, so it would use the same web.config file, creating a single point of configuration for things like the db connection strings contained. For a lot of other reasons this was a bad idea. The service became a separate project, that is a separate application on the web server, with it's own web.config.

    The good thing is that ASP.NET does share information in a web.config by default. When starting the application, that is on the first request of the session, IIS reads in the web.config of the application and all other web.config's up in the tree of applications on the server. It combines them into one list of settings. So when the service is in a subfolder of the site, all the site settings are available to the service.

    In this case IndatoService can read all settings of Indato. When combining these settings asp.net does something you can compare to overriding. In the web.config of the site authentication is set to forms authentication, directing the user to the login.aspx page.

    <authentication mode="Forms">
       <forms name = ".IndatoAuthenticationCookie"
             loginUrl = "login.aspx"
             protection="All"
             timeout="15">
       </forms>
    </authentication>

    For a web service forms authentication will not work. The web.config of the service will also set an authentication method more fit to a service; this setting overrides the setting in the site's web.config.

     <!-- AUTHENTICATION
            This section sets the authentication policies of the application. Possible modes are "Windows", "Forms", "Passport" and "None"
            "None" No authentication is performed.
            "Windows" IIS performs authentication (Basic, Digest, or Integrated Windows) according to
    its settings for the application. Anonymous access must be disabled in IIS.
            "Forms" You provide a custom form (Web page) for users to enter their credentials, and then
    you authenticate them in your application. A user credential token is stored in a cookie.
            "Passport" Authentication is performed via a centralized authentication service provided
    by Microsoft that offers a single logon and core profile services for member sites.
    -->
    <authentication mode="Windows" />

    Note that the comments in the web.config generated by the Visual Studio web service template include the suggestion to use forms authentication while it makes no sense for a web service. The web.config generated by WSCF does not include any authentication settings; the WSCF service will "inherit" the authentication used by the application up in the tree.

    So settings in a web.config can span more than just the application it's part off. But you can also limit the settings to a narrower scope. All settings in the web.config are between the <system.web> tags. To have different settings for a part of an application you repeat this <system.web> part enclosed in tags for the specific location. Take authorization. In this example the Tabellen folder is closed for everybody by adding a section, which will something like this:

     <location path="Tabellen">
       <system.web>
          <authorization>
             <deny users="*" />
          </authorization>
       </system.web>
    </location>

    You cannot do this with all web.config settings. It is not allowed to change the kind of authentication within an an application. This:

    <location path="Tabellen">
       <system.web>
          <authentication mode="Windows">
          </authentication>
       </system.web>
    </location>

    will produce a somewhat cryptic error message. It will pop up when you try to browse to a page in the Tabellen folder.

    The message may be cryptic but it points exactly to the line in config.sys which caused the trouble.

    In case you are afraid another application will install in a subfolder of yours and hack your configuration settings you can use the allowOverride attribute. The attribute can be applied on a lot of tags.

     <location path="Tabellen" allowOverride = "false">
       <system.web>
          <authorization>
             <deny users="*" />
          </authorization>
       </system.web>
    </location>

    There is so much more you can do with the web.config file. For a good overview I can recommend ASP.NET setup and configuration by James Avery (MS press); a handy little book explaining settings with good code samples. The link invites you to read the book online but does not lead to anything useful.

  • My first WSCF web service project. Contract first, code later.

    Recently I was in the need of a web service. At first sight I only needed a back door on a website to retrieve some bulk data. VS (2003) tempts you to make the web service part of the web project itself. This can be done but it will result in a service which is very very dependent on the site. For some parts this was good as the service uses a lot of the same configuration settings as the site. New versions of the site are rolled out on a regular basis (I'm not going to use the A-word) and as the IT department is not completely used to .NET yet, setup just has to be as simple as possible. Including the service in the same setup would be nice. The wost part of the dependency lies in security. You cannot use different authentication methods within one web project. As the site (like many others) uses forms authentication the web service will (try to) use forms authentication as well. Which is out of the question. As a workaround you can disable authorization for the specific web service urls. Which is out of the question as well. And that also does require quite some web.config fiddling and complicates the setup; exactly the thing I was trying to prevent. There are far simpler ways for web applications to share configuration, more on that in a later post.

    So however simple my initial web service was going to be; it is a separate project. Which gave me the occasion to work in real life with Christian Weyers Web Service Contract First tool, known as WSCF.

    There are two ways to approach a web service. The best known one is the Visual Studio template. Which starts with the code. My service would look something like this.

        public class IndatoWebService : System.Web.Services.WebService

        {

            public IndatoWebService()

            {

                //CODEGEN: This call is required by the ASP.NET Web Services Designer

                InitializeComponent();

            }

     

            [WebMethod]

            Indato.Data.Lookups.RoosterExport Activiteiten(int school, int opleiding, int jaar, int periode)

            {

                // implementation code

            }

     

            [WebMethod]

            Indato.Data.Lookups.StudentSets StudentSets(int school, int opleiding, int jaar, int periode)

            {

                // more implmentation code

            }

     

            [WebMethod]

            Indato.Data.Lookups.Personeel Personeel(int school, int opleiding, int jaar, int periode)

            {

                // and even more implementation code

            }

     

        }

    The service is built around this class which has methods with a WebMethod attribute. They all take a couple of selection parameters and return a typed dataset. It comes close to the programming model in the consumer of the service. A typical consumer will have a proxy (which is generated when you add a web reference in a VS project) containing members for these WebMethod's. The consumer's code will call the methods of the proxy. How the proxy communicates with the service is encapsulated. In Christian Weyer's flamboyant talk (go and see it whenever you get the chance or else read this) he makes it very clear that Remote Procedure Calls are just one aspect of web services.

    What's actually happening between a service and its consumer should be seen as an exchange of messages. Just like your web browser issues a request for a certain page on a certain site and is returned a bunch of HTML a web service consumer sends a request message to the service and is returned a response message. The latter can even be missing, the consumer just sends a message to the service, No Reply Necessary. Compare it to people exchanging emails.

    To focus looking at web services this way Christian created WSCF. On the site is a very elaborate walkthough how to work with it; in the remainder of this post I hope to tickle your curiosity.

    You start with describing the messages your service will exchange. These message will be in XML, the XML schema editor in VS makes a good tool to do the job. Here's another look at the same service:

    The list of parameters to the method are bundled in the Selection element. A service operation (webmethod) has only one parameter, it is a message containing the former parameter list. The messages returned by the services are modeled in the other xxxResponse messages. WSCF installs a right mouse button click for every XSD in your project. It reads create WSDL interface description and will fire up a wizard to generate a Web Service Description Language (WSDL) document which describes your service. The wizard can infer operations (web methods) out of the schema and you have full control on specifying the operations.

    For each operation you specify the message coming in:

    and the message returned:

    As all operations use the same selection criteria I can reuse the Selection message for several operations.

    Now I have a WSDL WS–I BP (Basic Profile) 1.1 conformant description of my service which describes it in a standard understood by a great number of tools in a large variety of environments. Including WSCF. Right clicking the wsdl in the project reveals Generate Web Service Code which pops up the next wizard. The wizard, which again has a number of fascinating options, can generate the code for the server stub to implement the service itself as well for the client proxy to consume the service.

    The walkthough starts with three projects. An empty one to house the contract in the form of the messages schema, an empty web project for the service implementation and a client implementation. Having generated the WSDL you have to copy it, with schema, to the client and the service project before generating the code. When generating the server stuff quite a lot happens. A couple of classes are added to the project including one inheriting from the System.Web.Services.Webservice class. Which looks like an highly decorated version of the thing the VS template came up with

        [System.Web.Services.WebServiceBindingAttribute(Name="IndatoWebService", Namespace="http://hanze.nl/Indato/Rooster")]

        [System.Web.Services.WebServiceAttribute(Namespace="http://hanze.nl/Indato/Rooster")]

        public class IndatoWebServicePort : System.Web.Services.WebService, IIndatoWebServicePort

        {

     

            public IndatoWebServicePort()

            {

            }

     

            /// <remarks/>

            [System.Web.Services.WebMethodAttribute()]

            [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://hanze.nl/Indato/Rooster:activiteitenZonderL1L2ResponseIn", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]

            [return: System.Xml.Serialization.XmlElementAttribute("ActiviteitenZonderL1L2Response", Namespace="http://hanze.nl/Indato/Rooster/RoosterMessages.xsd")]

     

     

            public virtual ActiviteitenZonderL1L2Response ActiviteitenZonderL1L2([System.Xml.Serialization.XmlElementAttribute(Namespace="http://hanze.nl/Indato/Rooster/RoosterMessages.xsd", ElementName="Selection")] Selection selection)

     

     

            {

                throw new System.NotImplementedException();

            }

     

            // Other members are quite likewise

     

            // Other members

     

     

        }

    Now I have reached the same point as the VS template and I can start writing the service implementation. What I have gained is that I have started with an outside view of the service in a language of XML formatted messages and not with an inside view of just some lines of generated C# (VB) code.

    Working on the service (but before publishing it to the world outside the dev department !)  you will always find out some things have to change. WSCF  supports round tripping. You can edit the message schema and edit the WSDL. The latter is in the right-click menu and will fire up the wizard.

    WSCF looks like a tool which fits perfectly in architecture centered development. And the moment you start building web services you are in that world. My service started as a backdoor to a website but as soon as the end users had seen it (yes we have very regular meetings discussing the application and I'm still not going to mention the A-word :)) we started discussing interaction with other applications. The user does understand the (graphical) schema which makes perfectly clear what the service can and cannot do. This is good for the applications as it's usability will increase and it is good for me as it can bring more nice things to do.

    So far using WSCF for building the web service is quite a success. But I did not use it for building the consuming client. My main problem was that every roundtrip of the contracts requires deploying (plain copy) the generated wsdl and the accompanying schema's to the client code. Instead I created just a server project which included the contract schema's. One clean and independent project. As all info needed by a consumer of the service is in the wsdl all the consuming client application needs is a reference to the wsdl. Which is exactly what add web reference in VS does. Having updated the service all I need to do in the client project is Update Web Reference. However, the proxy generated by WCSF does offer some nice extra's. It returns the data (when the option in the wizard is set) as a collection, the VS web reference just sees an plain array. I also have to set the service endpoint (the URL with it's location) by hand. The latter is something I'll have to do anyhow, as it will be read from a config file. And I can live with the arrays as a trade off for a cleaner development process. This is a point where WSCF could be improved.

    I have only scratched the surface of the many, many options of WSCF. Go the site and read on, even if you don't plan to actually use WSCF. You will find loads and loads of interesting stuff. In the old days we used to say Think First, Program Later. As a variation: Contract First, Program Later.

  • Add a web service to an existing web project (?)

    Here's the problem : We have quite a website which works with quite a database. The end user can only reach the web-server, the web server itself is the only one who can connect to the database. All works well but there is an extra feature which has to pump and check bulk data into the database from a COM server. The COM server itself has the tendency to pop up occasional dialogs so it just has to run on a manned workstation. (Imagine a web server popping up a dialog. It will have to wait until someone will visit the server room and take a look at that particular screen. Could take weeks) A good way for the client side app to communicate with the database is a web service. The server-side code of the web service implementation can reach the database. The client side sends and receives XML datasets to and from the web service.

    There are several ways to implement an asmx web service with Visual Studio

    • Listen carefully to the story Christian Weyer has to tell and use his Contract First tool
    • Create a new project and pick new web service
    • Add a web service to the existing web site project. Right click the project and just pick it:

     

    The latter works like a snap. After all a web service is not that much different from a web page. Both a a matter of request and response. In the case of a web page a bunch of HTML is returned, in the case of a web service a bunch of XML is returned. When you browse through the classes in the .NET framework which are used you will see great overlap. Both a web service project and a web site project are based on the System.Web.HttpApplication class (in global.asax)

    Implementing a service this way has some big pro's

    • It's deployed with the site itself. No extra steps needed. Simple setup.
    • It uses the same web.config. No extra configuration required.

    It could have some con's as well...

    <update after reading and trying Dave's advise>

    Dave's first point, rolling out on one and the same machine, is exactly what I want, just a backdoor for the site.

    But the authentication is indeed the big con. When the site is using forms authentication the service will be using windows authentication as well. It is somewhat hilarious to see your site login screen pop up in VS. So it's not a good idea.

    • Service is not autonomous. It's dependent from the site.
    • When the site uses forms authetication it's gonna be at least a hell of a web.config

    My next post will be on Christians Contract First tool.

     

  • Virus checker in action (you talk to much)

    Recently my PC got infected. Trying to prevent it happening again I installed McAfee, the anti-virus software provided by my provider Xs4all. I had bad experiences with AV-software in the past. To name a few

    • Norton AV blocking Office automation projects,
    • Norton internet security blocking my site because the main page is a (harmless) script
    • Several products blocking all activity on my PC because they were downloading/scanning

    I guess you all know what I'm talking about.

    Today brought  a new surprise, this is what McAfee had to say in the middle of an email chat:

    Chatter, chatter..

    Posted Jan 12 2006, 10:27 AM by pvanooijen with no comments
    Filed under:
  • SmartNavigation has Internet Explorer displaying the wrong html source

    SmartNavigation is a feature which can cause quite a lot of trouble. It is a property of an asp.net webpage intended to improve the "user experience" over postbacks by

    • Maintaining the scroll position in the browser
    • Maintaining the history over pages. Clicking back navigates to the previous page viewed instead of the previous roundtrip of the same page

    The feature only works in Internet Explorer and has some bizarre side effects. Navigating to another page from code just does not work right. View source and Save As in IE are a complete WTF. I did write a small entry on that before, had forgotten about it until it hit me again last week.

    Here's a web page to demonstrate the problem. It has two panels and a radiobuttonlist to pick which of them will be visible

    protected void Page_Load(object sender, EventArgs e)
    {
       Panel1.Visible = RadioButtonList1.SelectedIndex == 0;
       Panel2.Visible = RadioButtonList1.SelectedIndex == 1;
    }

    Panel1 contains a bulletlist, panel2 a calendar. It should be easy to see both in the browser and in the underlying HTML which panel is rendered. The result in IE :

    When displaying the source IE will return the HTML of the first roundtrip. This is very clear for the panel; the browser displays panel TWO, the source displays the HTML of panel ONE. You can also spot the differences in the smaller details. The page has a label to display the roundtrip count. In the source the text of this label is always 1.

    In VS 2005 the SmartNavigation property is considered obsolete. It still works and does display the same errant behavior. The Page.SetFocus method and Page.MaintainScrollPositionOnPostBack property are proposed as alternative. These do not maintain the history of pages visited. To get that fixed independent of SmartNavigation-settings and browser-brand you'll have to use a custom button. May I suggest this one ?

  • Connecting to a remote SQL express instance

    Connecting from VS 2005 to a SQL express instance on another machine took me some puzzling. The sqlexpress weblog has a recipe how to get that done.  Which did not work as written down (most likely because it's addressing previous CTP's not the release build) but provided enough info to get it to work on my machine. Let me share this.

    SqlExpress is installed as a part of VS. To get some tools I installed SQL server 2005 pro, a present from the launch party, on top of that. By default this server instance does not accept any connections from another machine. You switch that on using the SQL Server configuration manager. After a default install only the shared memory protocol is switched on. Activate the TCP/IP protocol:

    Now the sql server instance will accept a remote connection. As you can see in the dialog it will listen on all IP addresses on port 1070. You need this information to connect from VS.

    The server name is more complex than I was used to. It consists out of three parts: The machine name (Peckoltia), the named instance of SQL server (SQLexpress) and the port number (1070).

    Posted Jan 05 2006, 10:28 AM by pvanooijen with 11 comment(s)
    Filed under:
  • Adventures with MS-anti spyware. (Please schedule by default.)

    The new year had a troublesome start. Something which I believed could not happen has happened. I've been hacked. Over the last days my machine was displaying some very worrying signals. It kept me waiting for far too long, the task manager was disabled and I could not install anything new. Up till yesterday I thought using a private IP address (in the 192.168.x.x range, being handled by my router/dhcp server) and Windows firewall/anti spyware was enough. But it's not quite enough.

    Firing up anti spyware and some googling soon made clear what had happened. Windows firewall does protect your machine against incoming mal but anything is allowed to go out. Like data generated by spyware. MS anti-spyware automatically does a very good job in protecting your machine against unintended scripts or installations (it regularly pops up a message telling what it does, asking permission when in doubt) but sometimes something can slip through. Even with your signatures up to date. To keep your machine clean MS anti-spyware can perform a scan. Starting that by hand soon revealed and destroyed the culprit.

    MS anti spyware should schedule scans and I had that switched on. What went wrong was the scheduled time. By default this is set to sometime late at night. When I (and my machine) are sound asleep. The bad thing is that the scheduler never makes up for a scan lost. As I found out my last scan was a couple of weeks old. I should have checked; you can't trust anything these days. Blush.. Software may be perfect but it has to run to do its job.

    Killing the spyware itself was no problem. Cleaning up the mess was worse. As I wasn't in charge of my own machine any longer some drastic measures were required. What I did was reinstall Windows as an upgrade to the present installation. Doing that I bumped into a quirk in Windows setup. The drivers of some of my devices (to be precise a standard nVidia display adapter) are not signed and therefore pop up an approval dialog. When you don't reply fast enough setup will crash (completely, blue screen and all) and start over. An extra hurdle is that these dialogs pop up in an early phase of the installation, before the USB ports (to which the keyboard is connected) are activated. I had to dig up an old kbd with a classical PS/2 connector to successfully reinstall.

    And now everything is working again as it should. All my settings are back, none of the spy-ware's are. And I'm a little less naive.

More Posts

Our Sponsors

Free Tech Publications

This Blog

Syndication

News