Contact
Send mail to the author(s) Email Me

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Sign In
Navigation

Tag Cloud
.NET Framework (31) AJAX (9) ASP.NET (16) ASP.NET MVC (3) C# (32) Cloud (2) Database (6) Dev Community (2) Dev Tools (5) Enterprise Library (1) Futures (2) General (6) Javascript (7) LINQ (2) Mobile (1) MSDTC (5) Quotes (3) SQL (3) Transactions (4) WAS (2) WCF (19) WIF (1) Visual Studio (3)

Archive
<June 2008>
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

Categories

Blogroll
Home Feed your aggregator (RSS 2.0)
# Thursday, May 29, 2008

I have been using ScottGu's Visual Studio 2008 theme for the last few weeks and love it. You can see it here and download it here.

Thursday, May 29, 2008 9:21:53 PM (Eastern Standard Time, UTC-05:00)  #    Comments [5]   Dev Tools | Visual Studio  | 
# Wednesday, March 26, 2008

I was looking for guidance on this topic, and came up with nothing. I'm sure people are doing this, but can't find any info. For anyone looking like I was, here's how to do it.

It's much simpler than I imagined, thanks to WCF. You can programmatically create your endpoint, binding, and channel inside your service. This would require that the address be hard-coded and require a recompile to change the address or binding. As long as your host's app.config or web.config has a client endpoint specifying the contract, you don't have to go through all that work. Your service is simply a client of another service, so your code looks just like that of a client of your service. Furthermore, changing the address or binding is as simple as changing config file values.

Service code:

    1 using System;

    2 using System.ServiceModel;

    3 using DataContracts;

    4 namespace ServiceImplementation

    5 {

    6     [ServiceContract]

    7     public interface IEmailService

    8     {

    9         [OperationContract]

   10         void Send(DataContracts.MailMessage msg);

   11     }

   12 

   13     public class EmailService : IEmailService

   14     {

   15         [OperationBehavior]

   16         public void Send(DataContracts.MailMessage msg)

   17         {

   18             // Open client proxy for legacy web service

   19             using (LegacyEmailServiceClient proxy =

   20                 new LegacyEmailServiceClient())

   21             {

   22                 proxy.SendEmail(msg.To,

   23                     msg.CC,

   24                     msg.Bcc,

   25                     msg.Body,

   26                     msg.Attachments);

   27             }

   28         }

   29     }

   30 }

   31 



Host's app.config:

    1 <?xml version="1.0" encoding="utf-8"?>

    2 <configuration>

    3   <system.serviceModel>

    4     <bindings>

    5       <basicHttpBinding>

    6         <binding name="BasicHttpBinding_Common">

    7           <security mode="None"/>

    8         </binding>

    9       </basicHttpBinding>

   10       <netTcpBinding>

   11         <binding name="NetTcpBinding_Common">

   12           <security mode="None"/>

   13         </binding>

   14       </netTcpBinding>

   15     </bindings>

   16     <client>

   17       <endpoint address="http://www.gotjeep.net/legacy/email.asmx"

   18           binding="basicHttpBinding"

   19                 bindingConfiguration="BasicHttpBinding_Common"

   20           contract="LegacyEmailServiceClient"

   21                 name="LegacyEmailServiceClient" />

   22     </client>

   23     <services>

   24       <service name="ServiceImplementation.EmailService"

   25               behaviorConfiguration="returnFaults">

   26         <host>

   27           <baseAddresses>

   28             <add baseAddress="http://localhost:8080/EmailService" />

   29             <add baseAddress="net.tcp://localhost:8088/EmailService" />

   30           </baseAddresses>

   31         </host>

   32         <endpoint name="NetTcpBinding_EmailService"

   33                   binding="netTcpBinding"

   34                   bindingConfiguration="NetTcpBinding_Common"

   35                   contract="ServiceImplementation.IEmailService"/>

   36         <endpoint name="BasicHttpBinding_EmailService"

   37                   binding="basicHttpBinding"

   38                   bindingConfiguration="BasicHttpBinding_Common"

   39                   contract="ServiceImplementation.IEmailService"/>

   40       </service>

   41     </services>

   42     <behaviors>

   43       <serviceBehaviors>

   44         <behavior name="returnFaults" >

   45           <serviceMetadata httpGetEnabled="true" />

   46         </behavior>

   47       </serviceBehaviors>

   48     </behaviors>

   49   </system.serviceModel>

   50 </configuration>

Wednesday, March 26, 2008 9:08:46 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3]   .NET Framework | C# | WCF  | 
# Tuesday, March 25, 2008

If you haven't heard me praise Juval Löwy's book Programming WCF Services or Michele Leroux Bustamante's book Learning WCF: A Hands-on Guide yet... these books are the best WCF books available. Every question I have had has been answered by these two books. In fact, most of the forum and newsgroup resolutions out there come from one or both of these books. If you haven't already, check out their IDesign Code Library and and the IDesign WCF Coding Standard at www.IDesign.net.

OK, problem and resolution of the day... how do I generate a proxy file with the same collection class as my service implementation. My service uses List<T>. WCF converts this to be a more interoperable array of T. When you generate the proxy, it is generated with T[]. To be able to enjoy the same collection features as the service, you only need a few more parameters on svcutil.

    7     [ServiceContract]

    8     public interface IEmailService

    9     {

   10         [OperationContract]

   11         string MyOperation1(string myValue);

   12 

   13         [OperationContract]

   14         List<String> MyOperation2(string myValue);

   15     }

Example 1: Generate proxy with T[]

svcutil http://localhost:8080/EmailService /out:EmailServiceProxy.cs /noconfig

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IEmailService/MyOperation2", ReplyAction="http://tempuri.org/IEmailService/MyOperation2Response")]
string[] MyOperation2(string myValue);

Example 2: Generate proxy with List<T>

svcutil http://localhost:8080/EmailService /out:EmailServiceProxy.cs /noconfig /ct:System.Collections.Generic.List`1

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IEmailService/MyOperation2", ReplyAction="http://tempuri.org/IEmailService/MyOperation2Response")]
System.Collections.Generic.
List<string> MyOperation2(string myValue);

Tuesday, March 25, 2008 9:22:22 PM (Eastern Standard Time, UTC-05:00)  #    Comments [9]   .NET Framework | WCF | C#  | 
# Monday, March 24, 2008

Before you try running a Console Application or Windows Service application that hosts a WCF service with basicHttpBinding or wsHttpBinding, see this MSDN article about "Configuring HTTP and HTTPS". If you are WAS-hosted or Web App-hosted, the urlacl entries are made on your behalf.

You can view the current entries with "netsh http show urlacl". To make the changes, you'll need to "Run as Administrator" when going into your Command Prompt.

I decided to use the following command:

netsh http add urlacl url=http://+:8080/ user=\Everyone

You should adjust the ports and/or path as necessary for your situation:

netsh http add urlacl url=http://+:8080/MyConsoleAppHostedService user=DOMAIN\user

netsh http add urlacl url=http://+:8091/MyWindowsServiceHostedService user=\SYSTEM

Monday, March 24, 2008 8:03:15 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2]   .NET Framework | WCF  | 
# Saturday, March 22, 2008

WCF is seamless, powerful, and (YES) interoperable. Here is a quick walkthrough detailing steps to call your legacy PHP web services from a WCF client. All of the binding types and security options are, of course, not available. But for those of you following the old "security through obscurity" model, this will work fine.

The procedure is just as simple as a WCF-WCF call:
  1. Create client proxy
  2. Add client endpoint to your client config file
  3. Write your proxy-consuming client code

Create the client proxy:

Nusoap provides a similar UI when navigating to your PHP web service to that provided by ASMX services. You can view the WSDL, and copy the URL for svcutil.exe.

From the Visual Studio 2005 Command Prompt, type:

svcutil <url> /out:<name>Proxy.cs /noconfig
svcutil http://gotjeep.net/services/ApproachAngleService.php?wsdl /out:ApproachAngleServiceProxy.cs /noconfig

This generates a file named ApproachAngleServiceProxy.cs.

    1 //------------------------------------------------------------------------------

    2 // <auto-generated>

    3 //    This code was generated by a tool.

    4 //    Runtime Version:2.0.50727.1433

    5 //

    6 //    Changes to this file may cause incorrect behavior and will be lost if

    7 //    the code is regenerated.

    8 // </auto-generated>

    9 //------------------------------------------------------------------------------

   10 

   11 

   12 

   13 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

   14 [System.ServiceModel.ServiceContractAttribute(Namespace="http://www.gotjeep.net/tech", ConfigurationName="GotJeepApproachAngleCalculatorPortType")]

   15 public interface GotJeepApproachAngleCalculatorPortType

   16 {

   17 

   18     [System.ServiceModel.OperationContractAttribute(Action="http://www.gotjeep.net/services/approachAngleService.php/CalculateApproachAngle", ReplyAction="*")]

   19     [System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, Use=System.ServiceModel.OperationFormatUse.Encoded)]

   20     [return: System.ServiceModel.MessageParameterAttribute(Name="return")]

   21     decimal CalculateApproachAngle(decimal height, decimal diameter, decimal distance);

   22 }

   23 

   24 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

   25 public interface GotJeepApproachAngleCalculatorPortTypeChannel : GotJeepApproachAngleCalculatorPortType, System.ServiceModel.IClientChannel

   26 {

   27 }

   28 

   29 [System.Diagnostics.DebuggerStepThroughAttribute()]

   30 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

   31 public partial class GotJeepApproachAngleCalculatorPortTypeClient : System.ServiceModel.ClientBase<GotJeepApproachAngleCalculatorPortType>, GotJeepApproachAngleCalculatorPortType

   32 {

   33 

   34     public GotJeepApproachAngleCalculatorPortTypeClient()

   35     {

   36     }

   37 

   38     public GotJeepApproachAngleCalculatorPortTypeClient(string endpointConfigurationName) :

   39             base(endpointConfigurationName)

   40     {

   41     }

   42 

   43     public GotJeepApproachAngleCalculatorPortTypeClient(string endpointConfigurationName, string remoteAddress) :

   44             base(endpointConfigurationName, remoteAddress)

   45     {

   46     }

   47 

   48     public GotJeepApproachAngleCalculatorPortTypeClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :

   49             base(endpointConfigurationName, remoteAddress)

   50     {

   51     }

   52 

   53     public GotJeepApproachAngleCalculatorPortTypeClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :

   54             base(binding, remoteAddress)

   55     {

   56     }

   57 

   58     public decimal CalculateApproachAngle(decimal height, decimal diameter, decimal distance)

   59     {

   60         return base.Channel.CalculateApproachAngle(height, diameter, distance);

   61     }

   62 }

 

Add client endpoint to your config file:

You have the option of letting svcutil create your config file or using "Generate Service Reference", but I prefer to avoid the extra 20+ lines of config file defaults included by svcutil. It's not hard to write it yourself, and it ensures a much more readable config file.

    1 <?xml version="1.0" encoding="utf-8"?>

    2 <configuration>

    3     <system.serviceModel>

    4         <bindings>

    5             <basicHttpBinding>

    6               <binding name="GotJeepApproachAngleCalculatorBinding">

    7                 <security mode="None"/>

    8               </binding>

    9             </basicHttpBinding>

   10         </bindings>

   11         <client>

   12             <endpoint address="http://www.gotjeep.net/services/approachAngleService.php"

   13                 binding="basicHttpBinding"

   14                 bindingConfiguration="GotJeepApproachAngleCalculatorBinding"

   15                 contract="GotJeepApproachAngleCalculatorPortType"

   16                 name="GotJeepApproachAngleCalculatorPort" />

   17         </client>

   18     </system.serviceModel>

   19 </configuration>

 

Write the client code:

    1 using System;

    2 

    3 namespace Client

    4 {

    5     class Program

    6     {

    7         static void Main(string[] args)

    8         {

    9             using (GotJeepApproachAngleCalculatorPortTypeClient proxy =

   10                 new GotJeepApproachAngleCalculatorPortTypeClient())

   11             {

   12                 decimal result = proxy.CalculateApproachAngle(25.6m, 33.2m, 17.75m);

   13                 Console.WriteLine("decimal result = proxy.CalculateApproachAngle(25.6m, 33.2m, 17.75m);");

   14                 Console.WriteLine("result = " + result.ToString("0.00"));

   15             }

   16         }

   17     }

   18 }

 

Check it out:

A request-reply call between WCF and a Nusoap PHP web service.

Saturday, March 22, 2008 9:25:00 PM (Eastern Standard Time, UTC-05:00)  #    Comments [5]   .NET Framework | C# | WCF  | 
# Sunday, January 20, 2008

In a previous post about the AJAX Extensions, I detailed the copy commands to retrieve the DLLs from the GAC. Same thing, this time for the ASP.NET 3.5 Extensions. If you are demoing CTP material in a hosted environment, you will likely need these in your app's bin to avoid the inevitable configuration error.

copy "C:\WINDOWS\assembly\GAC_MSIL\System.Web.Extensions\3.6.0.0__31bf3856ad364e35" C:\dev\MMVCApp\bin
copy "C:\WINDOWS\assembly\GAC_MSIL\System.Web.Extensions.Design\3.6.0.0__31bf3856ad364e35" C:\dev\MMVCApp\bin

Sunday, January 20, 2008 10:25:40 PM (Eastern Standard Time, UTC-05:00)  #    Comments [6]   .NET Framework | ASP.NET | ASP.NET MVC | C#  | 
# Tuesday, December 18, 2007

A great series of blog posts by Scott Guthrie about the ASP.NET MVC Framework coming soon as part of the ASP.NET 3.5 Extensions release.

Upon hearing the news, a few friends started questioning its intent, usefulness, and longevity. Many of us have been using or contemplating conversion to the MVP pattern, most recently using WCSF. The recent split of the MVP pattern by Fowler has caused many believers to question their faith. While many are still "proving" MVP, MVC has been around for nearly 30 years. Some believe that MVP and MVC can co-exist. Here is a comparison of MVP and MVC that concludes by painting an optimistic picture of MVP and MVC contributing to each other.

ASP.NET MVC appears to be the answer to my unit testing, REST, and code separation prayers. Thank you ScottGu and team!

Check it out!

Tuesday, December 18, 2007 9:06:20 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3]   .NET Framework | AJAX | ASP.NET | ASP.NET MVC | C# | Javascript  | 
# Monday, December 17, 2007

Here is a fantastic solution to a common ORMr problem seen when regenerating code that overwrites changes made to previously generated and more recently manually-modified code.

Monday, December 17, 2007 10:04:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments [6]   .NET Framework | C# | Database  | 
Copyright © 2010 Scott Klueppel. All rights reserved.