Contents tagged with XML

  • Video – Getting Started with LINQ in .NET 3.5

    A few weeks back my company offered a free online webinar on LINQ technologies to help developers more easily make the transition to LINQ.  While there was a great turn out at the webinar, I received several emails from people who couldn’t attend asking if I could provide a video recording of the webinar.  It turns out that the audio for the recording wasn’t up to my standards so I put together a video that provides an introductory look at different LINQ technologies including:

    Read more...

  • Creating a Silverlight 2 Client Access Policy Socket Server

    Silverlight 2 provides built-in support for sockets which allows servers to push data to Silverlight clients.  By using this feature clients can avoid polling the server on a timed basis to ensure that clients are kept up-to-date.  If you're new to the socket features built-into Silverlight 2 you'll want to read my previous posts to get additional details about how data can be pushed from a server to a client:

    Silverlight 2 Beta 2 (and beyond) checks for a client access policy before accessing sockets located on host domain or cross-domain servers.  An example of a client access policy for sockets is shown next:

    <?xml version="1.0" encoding ="utf-8"?>
    <access-policy>
      <cross-domain-access>
        <policy>
          <allow-from>
            <domain uri="*" />
          </allow-from>
          <grant-to>
            <socket-resource port="4530" protocol="tcp" />
          </grant-to>
        </policy>
      </cross-domain-access>
    </access-policy>

    This XML code allows Silverlight to access a TCP socket on port 4530.  A range of ports can be specified in the port attribute if needed (ex: 4530-4532).  Before Silverlight tries to call a server with a socket, it makes a call to the target server on port 943 to check the client access policy and see if the server allows socket connections.  This helps minimize various types of hacker attacks.  If a client access policy is available on the server and the policy allows access to the port the client is trying to call, processing of the socket code continues and Silverlight tries to connect.  If not, the client will be unable to connect due to access being denied by Silverlight.

    An example of creating a client access policy socket server that Silverlight can connect to on port 943 is shown next:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    using System.Threading;
    using System.Reflection;
    using System.Configuration;
    
    namespace PolicySocketServices
    {
        class PolicySocketServer
        {
            TcpListener _Listener = null;
            TcpClient _Client = null;
            static ManualResetEvent _TcpClientConnected = new ManualResetEvent(false);
            const string _PolicyRequestString = "<policy-file-request/>";
            int _ReceivedLength = 0;
            byte[] _Policy = null;
            byte[] _ReceiveBuffer = null;
    
            private void InitializeData()
            {
                string policyFile = ConfigurationManager.AppSettings["PolicyFilePath"];
                using (FileStream fs = new FileStream(policyFile, FileMode.Open))
                {
                    _Policy = new byte[fs.Length];
                    fs.Read(_Policy, 0, _Policy.Length);
                }
                _ReceiveBuffer = new byte[_PolicyRequestString.Length];
            }
    
            public void StartSocketServer()
            {
                InitializeData();
    
                try
                {
                    //Using TcpListener which is a wrapper around a Socket
                    //Allowed port is 943 for Silverlight sockets policy data
                    _Listener = new TcpListener(IPAddress.Any, 943);
                    _Listener.Start();
                    Console.WriteLine("Policy server listening...");
                    while (true)
                    {
                        _TcpClientConnected.Reset();
                        Console.WriteLine("Waiting for client connection...");
                        _Listener.BeginAcceptTcpClient(new AsyncCallback(OnBeginAccept), null);
                        _TcpClientConnected.WaitOne(); //Block until client connects
                    }
                }
                catch (Exception exp)
                {
                    LogError(exp);
                }
            }
    
            private void OnBeginAccept(IAsyncResult ar)
            {
                _Client = _Listener.EndAcceptTcpClient(ar);
                _Client.Client.BeginReceive(_ReceiveBuffer, 0, _PolicyRequestString.Length, SocketFlags.None,
                    new AsyncCallback(OnReceiveComplete), null);
            }
    
            private void OnReceiveComplete(IAsyncResult ar)
            {
                try
                {
                    _ReceivedLength += _Client.Client.EndReceive(ar);
                    //See if there's more data that we need to grab
                    if (_ReceivedLength < _PolicyRequestString.Length)
                    {
                        //Need to grab more data so receive remaining data
                        _Client.Client.BeginReceive(_ReceiveBuffer, _ReceivedLength, 
                            _PolicyRequestString.Length - _ReceivedLength,
                            SocketFlags.None, new AsyncCallback(OnReceiveComplete), null);
                        return;
                    }
    
                    //Check that <policy-file-request/> was sent from client
                    string request = System.Text.Encoding.UTF8.GetString(_ReceiveBuffer, 0, _ReceivedLength);
                    if (StringComparer.InvariantCultureIgnoreCase.Compare(request, _PolicyRequestString) != 0)
                    {
                        //Data received isn't valid so close
                        _Client.Client.Close();
                        return;
                    }
                    //Valid request received....send policy data
                    _Client.Client.BeginSend(_Policy, 0, _Policy.Length, SocketFlags.None, 
                        new AsyncCallback(OnSendComplete), null);
                }
                catch (Exception exp)
                {
                    _Client.Client.Close();
                    LogError(exp);
                }
                _ReceivedLength = 0;
                _TcpClientConnected.Set(); //Allow waiting thread to proceed
            }
    
            private void OnSendComplete(IAsyncResult ar)
            {
                try
                {
                    _Client.Client.EndSendFile(ar);
                }
                catch (Exception exp)
                {
                    LogError(exp);
                }
                finally            
                {
                    //Close client socket
                    _Client.Client.Close();
                } 
            }
    
            private void LogError(Exception exp)
            {
                string appFullPath = Assembly.GetCallingAssembly().Location;
                string logPath = appFullPath.Substring(0, appFullPath.LastIndexOf("\\")) + ".log";
                StreamWriter writer = new StreamWriter(logPath, true);
                try
                {
                    writer.WriteLine(logPath,
                        String.Format("Error in PolicySocketServer: "
                        + "{0} \r\n StackTrace: {1}", exp.Message, exp.StackTrace));
                }
                catch { }
                finally
                {
                    writer.Close();
                }
            }
        }
    }

    Looking through the code you'll see that it uses the TcpListener class to listen for incoming client connections.  Once a client connects the code checks the request for the following value:

    <policy-file-request/>

    Silverlight automatically sends this text to the policy file socket once it connects.  If the request contains the proper value the code writes the contents of the client access policy back to the client stream (see the OnReceiveComplete() method).  Once the policy file is received, Silverlight parses it, checks that it allows access to the desired port, and then accepts or rejects the socket call that the application is trying to make. 

    An example of the Silverlight GameStream socket application I created to demonstrate the fundamentals of using sockets is shown next.  The code for the application can be downloaded here

    If you're brand new to Silverlight 2 and are interested in getting started with it check out the following video tutorials:

    Silverlight 2.0 Video Tutorials

    Part 1: Creating "Hello World" with Silverlight 2 and VS 2008 Tutorial Video Tutorial
    Part 2: Using Layout Management Tutorial Video Tutorial
    Part 3: Using Networking to Retrieve Data and Populate a DataGrid Tutorial Video Tutorial
    Part 4: Using Style Elements to Better Encapsulate Look and Feel Tutorial Video Tutorial
    Part 5: Using the ListBox and DataBinding to Display List Data Tutorial Video Tutorial
    Part 6: Using User Controls to Implement Master/Details Scenarios Tutorial Video Tutorial
    Part 7: Using Templates to Customize Control Look and Feel Tutorial Video Tutorial
    Part 8: Creating a Digg Desktop Version of our Application using WPF Tutorial Video Tutorial
     

     

    Read more...

  • Silverlight 2 Networking Options

    image I've been spending my nights working on a new book covering Silverlight 2 and have been focusing on the new networking features that are available in the System.Net and related namespaces.  Silverlight's great at animating objects, performing transformations and collecting data with all of the new controls that are available, but at some point you'll need to retrieve data or send data to a service.  There's great support built-in for calling WCF services, ASMX services as well as other services.  Support for  calling REST APIs is also very good and easy to implement using classes such as WebClient and HttpWebRequest/HttpWebResponse.  Asynchronous requests can be issued and handled quite easily once you figure out the pattern (which is quite consistent throughout the different networking classes).

    Read more...

  • LINQ to XSD

    One of the cool features in VB 9.0 is the ability to work directly with XML in code without having to wrap quotes around everything.  If you're a C# developer, that's a feature that we don't have although you can do similar things with LINQ to XML (quotes required though).

    Read more...

  • Upcoming .NET Courses in 2008



    I've had several people here in the Phoenix area and others I've met at ASP.NET Connections conferences ask when I'll be teaching specific .NET classes in 2008 and my standard reply has been "I'm not sure at this point".  We have things scheduled out past June now so here's the information for those who are interested.  Most of the classes listed are 5 days aside from the First Look at Visual Studio 2008 (1 day) and ASP.NET AJAX Programming (3 days).

    The schedule is of course subject to change, but it's what I have at this point.  If you have any questions about any of the courses feel free to contact me through my blog.

    Read more...

  • Exchanging Binary Data with MTOM and Web Services

    In the distributed computing class I'm teaching this week we're covering a few topics related to the Web Service Enhancements V3 (WSE3).  One of the nice features of WSE3 (and WCF for that matter) is that it can be used to exchange binary data quite easily and in an efficient manner by using MTOM.  I put together a demo project that shows how MTOM can be used to exchange binary data between a client and a Web Service.

    The demo code dynamically generates bar and line chart images using .NET and GDI+.  A client can pass XML data representing the data to chart to the Web Service and the service will handle dynamically generating the chart image and return it to the client using MTOM.  The code for the demo can be downloaded here.

    Read more...

comments powered by Disqus