Damon's profiledamon wilder carrPhotosBlogLists Tools Help

damon wilder carr

domain dot net team labs

domain.dot.net team

Loading...Loading...
2/18/2009

still the definitive word - If programmers have make a plane

 

Quote

Talking about YouTube - If programmers have make a plane
  

2/11/2009

WCF REST Starter Kit CodePlex Preview 1 Release Notes


Software is very focused now in terms of the key enabling MSFT inflection points. Silverlight and WCF are the core (all the rest like deep C# 3.0 mastery is simply assumed and boring). The world hires on API but needs to hire on abstraction mastery in real use.

Making amazing views work calling into REST/SOA endpoints leaves much to do. More specifically NHibernate is typically being used by the service but so is just about everything else within reason (and some stuff not within reason).

Damon Wilder Carr


Copyright © 2008 Microsoft Corporation. All rights reserved.

This document lists several important notes related to the WCF REST Starter Kit CodePlex Preview 1 Release. Other releases such as the PDC 2008 Media Release may also find some of these notes useful.

Please read them before using:

  1. System, Environment and Security considerations:
    1. The starter kit works best with Visual Studio 2008 SP1 or later on 32 bit or 64 bit Windows Vista or Windows Server 2008. The templates are available in Visual C# only in the current release. Using Internet Explorer 7.0 or later allows you to view feeds. Using Internet Explorer 6.0 is not recommended, as it does not have some required features such as feed support. If you are using IIS to publish your Web site or Web application, it is recommended to use IIS 7.0.
    2. These templates and samples are not intended to be used directly in a production environment. Once you create the service you need using one of these templates, you must configure and modify it appropriately to meet your business requirements before deploying it in production. For example, these templates use an in-memory representation of the data, whereas some real world applications may require a persistent store for their data. Please consult the corresponding documentation on MSDN to understand various configuration and other choices available.
    3. The templates currently do not have any security built into them, barring some samples that show how to use certain security features. You are recommended to use the security guidance available on MSDN (there are other security suggestions available as in the WCF Security guide Beta 2 on codeplex which you can use to look for the right security design and implementation for your needs).
    4. The item templates provided in this kit are meant to be added to an ASP.NET Web site. We do not recommend the use of these item templates in other project types as of this release. Also, these services cannot be called asynchronously from ASP.NET AJAX clients. To call a general WCF service from AJAX, use the ASP .NET Friendly WCF Service item template available in Visual Studio (not a part of this starter kit).
  2. Installation
    1. Please install the CodePlex Preview Release from http://www.codeplex.com/aspnet . Click on the subarea titled "WCF REST" and select the releases tab. Click on "All Releases" on the right, and select the WCF REST Starter Kit CodePlex Preview 1 Release.
    2. Please note that the license that applies to the WCF REST Starter Kit releases on CodePlex is available here. No other license terms apply to your use of the WCF REST Starter Kit CodePlex Preview 1, including the "Microsoft Source License for ASP.NET Pre-Release Components" license terms that will pop up when you first click on the download links.
    3. You may download the installer by clicking on the link titled "WCF REST Starter Kit CodePlex Preview 1 Installer" will download a zip folder that contains the installer along with Install instructions.
    4. You may download the zip of the source code by clicking on the link titled "WCF REST Starter Kit CodePlex Preview 1 Source Code".
    5. You may download the release notes (this document) by clicking on the link titled WCF REST Starter Kit CodePlex Preview 1 Release Notes.
    6. If you wish to install using the installer, please do the following:
      1. Extract the installer zip file that you downloaded.
      2. Run Setup.exe as an administrator. You may do this by right clicking on Setup.exe and selecting "Run as Administrator". If you do not see this option on the right click menu, it probably means that you are clicking on the compressed file. Extract the zip and try again.
      3. You may see a warning that the installer is not signed, which you can safely ignore and continue.
      4. Remember to complete the installation of the templates from the launched Visual Studio Installer to finish up the installation.
    7. When you install the templates using the provided .vsi file, you may see a pop-up warning that the content is not signed, which you can ignore by clicking 'Yes'.
  3. Configuration
    1. Zero Configuration option: You can create a REST style service using WCF 3.5 with zero configuration. Add the Factory="System.ServiceModel.Activation.WebServiceHostFactory" attribute to the ServiceHost element in the service (.svc) file and this takes care of setting up all the configuration required to make your service a REST service. The project templates and item templates provided in this starter kit are automatically configured with this attribute, so you do not have to do this manually.
    2. If you change the namespace or service type, then remember to update the .svc file with the changes manually.
    3. If you choose to use an item template that is provided here, and you want to use ASP.NET compatibility features such as using the ASP.NET pipeline for forms authentication/caching and other such features, please remember to add an entry to the Web.config file to enable ASP.NET Compatibility. You would add an entry like the one shown in the following example.

    <configuration>

            <system.serviceModel>

                <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

            </system.serviceModel>

    </configuration>

    1. By default, IIS requires us to specify the full service name, including the .svc file. However, in the REST style, developers often want to avoid the use of file extensions. This can be achieved in IIS 7.0 using the URI rewriting module provided in IIS 7.0. The details of how this works and how to configure IIS 7.0 for URI rewriting are available here.
    2. In some cases, especially item templates, you would need to reconfigure the reference from the website to the Microsoft.ServiceModel.Web assembly, which can be obtained by building the project in the folder of that name in your install location (or the location where you extracted the source code). Most samples and templates require this assembly to exercise some of the new features in the WCF REST Starter Kit.
  4. Visual Studio
    1. Selecting the service file in Solution Explorer takes you right to the service in the browser that is launched to test the service. Selecting the project node opens the folder that contains all the service files and you can then click the service.svc file to get to the service. If you ever find yourself in the folder that contains the .svc file, then you can click the .svc file to call the service. In cases where the service itself does not have an implementation (such as in the HTTP Plain XML service templates), you would manually modify the URL to use the service (for example, in the HTTP Plain XML Service template case, you would append the URL to add a query string that contains the action you want to call).
    2. Project templates in Visual Studio 2008 on Windows Vista are installed at <my user directory>\Documents\Visual Studio 2008\Templates\Project Templates\Visual C#\Web. Item templates are installed under <my user directory>\Documents\Visual Studio 2008\Templates\Item Templates\Visual Web Developer\CSharp.
    3. On Windows Vista, you may be required to run Visual Studio 2008 as administrator to debug Web applications and to use some other features. One way to do this is to right-click the Visual Studio 2008 menu item in the Start menu and select 'Run as administrator'.
    4. When you add an item template to an ASP.NET Web site, it puts the service code behind file (such as Service.svc.cs) in the App_Code directory and the Service.svc file in the Web site folder.
    5. If you double-click the .svc file in Solution Explorer inside Visual Studio, the code behind file (.svc.cs file) may be opened. To view the markup (.svc) file, right-click the .svc file and select 'View Markup'.
  5. Samples and Documentation
    1. There is an exhaustive list of samples available with the WCF REST Starter Kit CodePlex Preview 1, which describe the different features available in this release.
    2. Every sample has an associated readme file (in the same folder) to explain the sample in brief.
    3. You may also use the solution provided in the folder "Samples\ WCF REST Starter Kit Samples" – which is a single solution that includes all the sample projects in one solution. Please note that when you run any one of the samples in that list, several instances of the ASP .NET Development Server will be launched (one per sample). If you want to work on only one sample, then you can directly open the sample project from that sample's folder.
    4. There are also an elaborate set of Screencasts, whitepaper and Hands-On-Labs available on the WCF Development Center.
    5. You can provide feedback from the issue tracker tab on CodePlex. You may also discuss this release with other developers and product team members on the WCF REST forum.
  6. Testing the service (with Fiddler)
    1. Check out the video tutorials at the top of the Fiddler2 site to learn how to use the various features of fiddler.
    2. Make sure that you know how to use Fiddler with the ASP.NET development server as described in the Appendix below – Using the Fiddler test client.
    3. When you call HTTP methods on the service, you may get some unexpected behavior such as a 307 response code (temporary redirect). To fix this issue, try appending a forward slash ('/') at the end of the URL.
    4. When you call GET on a URL from Fiddler, you may get unexpected errors (such as 400 Bad Request). Make sure that the request body is completely empty (by deleting all whitespace until the red highlight on the request body is gone) before calling GET.

     

Appendix A - Using the Fiddler Test Client

 

Fiddler is a test Web client that allows you to test Web services by constructing different HTTP requests (GET, POST, and other requests.) and sending it to a URL. Fiddler can be downloaded here.

 

Fiddler and the ASP .NET Development Server

Note: the newer releases of Fiddler do not require the below configuration, so you may try this approach first – try using http://ipv4.fiddler:(port)/mysite/service.svc directly.If it doesn't work, then use the following configuration steps (the configuration should work in both cases, the above approach is just less configuration).

Due to a limitation in the ASP.NET development server and its interaction with external requests to localhost, you must customize Fiddler to work with the ASP.NET development server used in Visual Studio 2008. Open Fiddler, and from the menu, select Rules and then Customize Rules. In the file that opens, find the method called OnBeforeRequest and modify the content under it by pasting the following code.

 

if (oSession.HostnameIs("MYAPP")) {

oSession.host = "127.0.0.1: 53634";  

oSession.bypassGateway = true;
}

 

Note that the number following 127.0.0.1 in the preceding code example, marked in bold large font must match the port number following localhost that the current ASP.NET development server instance is listening on. If you create a different instance of ASP.NET development server while debugging, you must modify the port number here to match the new port number.

Save and close the file. Now you use http://myapp/MyService.svc to access your service instead of localhost. If you are working with multiple services launched in different ASP.NET development server instances at the same time, create one such entry for each port number, project or Web site combination, with a different name as shown in the following example code.

if (oSession.HostnameIs("MYFOOAPP")) {

oSession.host = "127.0.0.1: 53634";  

oSession.bypassGateway = true;
}

 

if (oSession.HostnameIs("MYBARAPP")) {

oSession.host = "127.0.0.1: 53123";  

oSession.bypassGateway = true;
}

 

 

Calling HTTP GET using Fiddler

You would usually not pass in a request body with the GET method.

To call HTTP GET on your service using Fiddler, follow the steps shown in Figure 34 (the useful fields are highlighted).

  1. Open the request builder tab in the right pane.
  2. Select GET in the drop down.
  3. Type in the URL you want to call.
  4. You can set the Content-Type to specify the content type that you expect in return. You can, for example, use text/xml or application/json for XML or JSON.
  5. Press the Execute button.
  6. There is now a new entry in the Web Sessions pane on the left and the result field contains the HTTP response code. (Here it is 200, for success).

 

Figure 49 Calling HTTP GET using Fiddler

  1. To further inspect the message, double-click the specific request you want to inspect in the Web Sessions pane on the left. This brings up the view shown in Figure 35. The 'Session Inspector' tab is selected. Select the request view (top right pane) and the response view (bottom right pane) that you want. This figure shows the Raw views selected in both cases, which shows the raw request and response.

 

Figure 50 Inspecting the http GET request and response

Calling POST with Fiddler

You would usually pass in a request body to POST that contains the data that you want to post.

Calling POST is different from calling GET, because you must pass in a request body. You would do the following things differently (as compared to calling GET) while calling POST before pressing Execute in the response builder:

  1. Select the POST verb in the request builder view.
  2. Set the content type header entry in the request header (top right pane under the request builder tab). The example uses text/xml.
  3. Set the request body to the body of the request you want to send (bottom right pane under the request builder tab). The body shows an example of an XML message.

Figure 36 shows the request builder view and Figure 37 shows the view inspecting the response.

Figure 51 Calling HTTP POST using Fiddler

Figure 52 Inspecting the HTTP POST request and response

Calling http PUT using Fiddler

You would usually pass in a request body to a PUT call. The steps to call HTTP PUT are similar to calling POST, except that you select the PUT method instead.

Calling http DELETE using Fiddler

You would usually not pass in a request body with DELETE. The steps to call HTTP DELETE are similar to calling GET, except that you select the DELETE method instead.

 



12/27/2008

Talking about YouTube - Deep Zoom 3D over PowerPoint in SharePoint

 

Quote

Talking about YouTube - Deep Zoom 3D over PowerPoint in SharePoint
  
 


12/23/2008

Advanced Bidirectional Silverlight 2.0 to ASP.NET Integration – Part 1

kick it on DotNetKicks.com

Digg This

Silverlight_Logo_2

This is the first post covering techniques for both sending data into your Silverlight environment from ASP.NET as well as getting data out of Silverlight without resorting to a lot of new elements in your architecture. The goal is to use what you already have with the least fuss.

You may think you need to resort to ‘pushing’ all data from Silverlight into say a service using WCF but that is not the case in many scenarios.

For example, you may have activity which the user creates inside Silverlight 2.0 that results in visual elements you want to send out to ASP.NET for persistence in your ORM environment (where Silverlight has no involvement).

From ASP.NET to Silverlight 2.0

First, let’s quickly review the easiest way to pass information into your Silverlight control.

InitParamaters

Here is the on-line help:

If parameters are included, they are typically in comma-delimited pairs and are available as a dictionary object in a Silverlight 2 startup event. These parameters are not used in a Silverlight 1.0-based application.

If an action on an .aspx page causes a postback to occur, the Silverlight plug-in will start again with its content specified in the Source property. The current value of the InitParameters property is sent to the Silverlight plug-in. This enables you to change the InitParameters property before a postback occurs.

The Silverlight 2 application specified in the Source property can access the initialization parameters specified in the InitParameters property in the StartupEventArgs parameter of the Silverlight Application Startup event.

We will walk through an entire example of this, including some content that will make sense in how we can move data back out of Silverlight 2.0 to ASP.NET.

Code for this Scenario

We will be using a web UserControl (.ascx) as our control in this example, because as you will see, we need more than just the Silverlight control to make this work.

ASCX Host

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SilverlightInt.ascx.cs"
  Inherits="SilverlightInt" %>
<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls"
    TagPrefix="asp" %>
<asp:Silverlight ID="SilverlightView" runat="server" Source="~/ClientBin/AspNetIntegration.xap"
    MinimumVersion="2.0.31005.0" />
<asp:TextBox ID="SilverOutput" runat="server"   Style="display: none"></asp:TextBox>

ASCX Code Behind

    public partial class SilverlightInt : UserControl
    {
        [Browsable(true)]
        public String InitialText { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            SetSilverlightInitParamaters();
        }

        void SetSilverlightInitParamaters()
        {
            // Note: We need the client ID for later...
            var InitParams = new Dictionary<String, String>
                             {
                                 {
                                     "outputcontrol",
                                    SilverOutput.ClientID
                                     },
                                 {
                                     "InitialText",
                               InitialText ?? "Hello World"
                                     }
                             };

            SilverlightView.InitParameters =                   InitParams.ToSilverlightInit();
        }
    }

You might notice the extension method ToSilverlightInit(). Here is the code:

 public static class SilverlightIntegrationExtensions
    {
        /// <summary>
        /// Parse the dictionary into Silverlight format
        /// for InitParams
        /// </summary>
        /// <param name="target">The target.</param>
        /// <returns></returns>
        public static String ToSilverlightInit(                 this IDictionary<String, String> target)
        {
            if (target == null)
                throw new ArgumentNullException("target");

            var stringBuffer = new StringBuilder();

            foreach(var kvp in target)
            {
                if (stringBuffer.Length > 0)
                    stringBuffer.Append(",");

                // Eliminate case sensitivity
              stringBuffer.Append(kvp.Key.ToLower() +                    "=" + kvp.Value);

            }

            return stringBuffer.ToString();

        }

    }

This is hosted in a normal ASPX page as follows (surrounding detail omitted):

  <form id="form1" runat="server" style="height: 100%;">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div>
        <asp:Image Width="300px" ImageUrl="Silverlight_Logo_2.png"
           runat="server" />
        <br />
        <asp:Literal ID="sentText" runat="server" /><br />
        <hr />
        <integrate:SilverlightInt ID="SilverlightInt1"
           runat="server"     InitialText="This is a Test" />
    </div>
    </form>

Here is what it looks like:

image

Silverlight Code for Initialization

 public partial class App : Application
    {
        public App()
        {
            Startup += Application_Startup;
            UnhandledException += Application_UnhandledException;
            InitializeComponent();
        }

        void Application_Startup(object sender, StartupEventArgs e)
        {
            var PassedInArguments = e.InitParams;
            RootVisual = new SilverlightView(PassedInArguments);
        }

The interesting parts are that we are accessing the InitParams off the Startup’s ‘e’ object. This is a Dictionary<String,String> which is what prompted the ASP.NET design.

Also, we do not use a paramaterless constructor on the initial RootVisual. Instead this is the code:

Silverlight View

<UserControl x:Class="AspNetIntegration.SilverlightView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid HorizontalAlignment="Left" VerticalAlignment="Top"
       x:Name="LayoutRoot" Background="Gray">
        <Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition Height="30" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
        </Grid.ColumnDefinitions>

        <TextBlock HorizontalAlignment="Center"            VerticalAlignment="Center"
             Grid.Row="0" Text="Inside Silverlight" />
        <TextBox LostFocus="SendResultBackToAspNet" Grid.Row="1"
          BorderThickness="2" BorderBrush="Black"                 x:Name="initialText"  />

    </Grid>

</UserControl>

Code Behind

public partial class SilverlightView : UserControl
    {
        readonly IDictionary<string, string> _initParamaters;
        string _initialText =                "Nothing was Passed In - initialtext was empty";

        public SilverlightView(              IDictionary<string, string> passedInArguments)
        {
            _initParamaters = passedInArguments;
            InitializeComponent();
            Loaded += OnLoaded;
        }

        void OnLoaded(object sender, RoutedEventArgs e)
        {
            SetInitialText();
        }

        void SetInitialText() {

            if (_initParamaters.ContainsKey("initialtext"))
            {
                _initialText = _initParamaters["initialtext"];
            }

            initialText.Text = _initialText;
        }

        void SendResultBackToAspNet(object sender, RoutedEventArgs e)
        {

        }
    }

Notice the ‘SendResultBackToAspNet’ is empty.. That is coming next and is the tricky part.

Coming Next

The code will all be available for download and the much more interesting aspect of sending data back the other way will be presented.

Damon

Digg This

11/28/2008

C# Delegate Shortcut – No more null testing on events for subscribers

kick it on DotNetKicks.com

This is fairly well known but I realized I hadn’t seen it blogged about (sorry if already covered).

Your likely used to doing this:

  public event EventHandler<AnimationImageEventArgs> AnimationImageClicked;

       


 private void OnClick(object sender, AnimationImageEventArgs e)
     


   {
        


    if (AnimationImageClicked != null)
      


          AnimationImageClicked(sender, e);
     


   }

No need for that null check. I for one tend to forget them in the bowels of my teams code. What is better then eliminating the issue!

This is a way to ‘always have one subscriber’ which you can consider a sort of ‘null object’ pattern implementation for delegates. Checking for null just sucks and I love this kind of ubiquitous removal of it.

The first person I saw doing this was Juval Lowy, the master craftsman for basically all things .NET but known recently for utter mastery of WCF in his books and at his firm IDesign. Highly recommend all his writing, code samples and thoughts.

 public event EventHandler<AnimationImageEventArgs> AnimationImageClicked = delegate { };

        


private void OnClick(object sender, AnimationImageEventArgs e)
      


  {
     


           AnimationImageClicked(sender, e);
     


  }

Damon

Digg This