Welcome to Windows Communication Foundation (WCF)
Top Tasks :

WCF Team Bloggers

Browse by Tags

All Tags » Answers   (RSS)

  • Certificate Revocation Cache

    How do I force propagation of changes to information about a certificate revocation list after an update? A service is going to have several kinds of caching around the information that links the certificate to revocation information. The first kind of caching is based on the revocation mode of the certificate. A revocation mode of NoCheck disables checking on the certificate while a revocation mode of Offline directs checking to use a cached certificate revocation list. A revocation mode of Online gets the freshest data. The second kind of caching is at the service process. Information is stored in memory as long as the process continues to run to reduce the number of active checks required. This memory cache is cleared when the process restarts. The third kind of caching is at the machine. Information is cached by the machine for a limited time to again reduce the number of active checks required. The machine cache can be viewed by running "certutil -urlcache" and the same command is used to delete or force updating of specific cache entries. Next time: Getting Rid of Namespaces Read More...
  • Trusting IP Addresses

    How do I find the address of a client connection to make a trust decision? Don't base security decisions on the perceived client address. Any address that we have comes from the underlying socket implementation and could be spoofed. The data that the socket has is sourced by the client. You should be using a source of information that has a verification process that the server trusts, such as a certificate, to distinguish clients. Next time: Reader Trends Read More...
  • Finding a Client Channel

    Where can I get the IContextChannel that OperationContextScope requires? OperationContextScope allows you to create a temporary scope in which context for a service operation can build up before and after the operation is actually called. The constructor for OperationContextScope takes an instance of IContextChannel, which is a type that you've probably never seen before. Why are you expected to have this unknown type? It's because you have instances of it floating around all the time even though there's no particular hint of this. There are different ways to get an IContextChannel depending on whether you're using a proxy generated by svcutil or a proxy generated at runtime. In either case, pretend that I've got service contract called IService with a single method called Foo. When I generate a service client using svcutil, the client object has a member called InnerChannel that works as an IContextChannel. ServiceClient client = new ServiceClient(binding, new EndpointAddress(address)); using ( new OperationContextScope(client.InnerChannel)) { WebOperationContext.Current.OutgoingRequest.Headers[ "X" ] = "from compiled proxy" ; client.Foo(); } client.Close(); Otherwise, if I'm using a ChannelFactory to create the proxy at runtime, the channel that I get back happens to be an IContextChannel as well. ChannelFactory<IService> factory = new ChannelFactory<IService>(binding); factory.Open(); IService proxy = factory.CreateChannel( new EndpointAddress(address)); using ( new OperationContextScope((IContextChannel)proxy)) { WebOperationContext.Current.OutgoingRequest.Headers[ "X" ] = "from runtime proxy" ; proxy.Foo(); } factory.Close(); Next time: Standards Guide Read More...
  • Adding Headers to a Call

    How do I add SOAP headers to an outgoing request? There are a few different ways to add headers to a message depending on how you need to control the header content and where you need to insert the header. I like to think of these methods as being split among the application, the proxy, and the protocol. In your application code you can create an OperationContextScope around the request in order to change some of the request properties. Inside an OperationContextScope, you have a valid instance of OperationContext.Current, which allows manipulation of the message headers through the OutgoingMessageHeaders collection. Use of this method deeply bakes control of the headers into the application code. You would have to be responsible for copying the appropriate code wherever it was needed. Now, assume that you want the header to be present whenever you're talking to a particular service and the header value can be determined consistently. Rather than having to put the same code at each call site, you can centralize the code in the proxy or in a protocol. The simplest way to centralize header manipulation in the proxy is to create an instance of the IClientMessageInspector and attach that to the proxy. This gives you a hook for every message going through the proxy to modify the message headers. An instance of IChannel similarly gives you a hook for every message going through the channel stack to modify the message headers. Using the Message Interceptor sample gives you an extensibility point in the binding that is similar in spirit to the extensibility point provided by a message inspector. The primary difference from your perspective of a message inspector and a channel is a matter of timing. A message inspector always runs before any of the protocols in the binding while a channel can be positioned precisely in the protocol stack. In most cases you don't need precise positioning, so you should go with the simpler approach. Next time: Adding Headers to a Call (HTTP Version) Read More...
  • Security Session Inactivity

    What does the InactivityTimeout on a secure channel do? The inactivity timeout on a message security channel controls how long the channel will allow pending security sessions to linger in its cache before giving up on them. This is completely different from the inactivity timeout on a reliable messaging channel, which controls how long the reliable session will live without an infrastructure message before being torn down, and the inactivity timeout in the application, which controls how long the service instance will live without an application message before being torn down. Next time: JSON Service Speed Read More...
  • Mapping Client Certificates

    Whenever my service receives a message the service operation fails because the user identity is not mapped to a Windows identity. How can I make this mapping? What's probably going wrong is that the user identity is specified by a certificate but there's no active mapping from the client certificate to a Windows account. By default, no mapping is performed. You can enable certificate mapping by setting mapClientCertificateToWindowsAccount on the service credentials to be true. < serviceCredentials > < clientCertificate > < authentication mapClientCertificateToWindowsAccount ="true" /> </ clientCertificate > </ serviceCredentials > The actual mappings are not provided by the service configuration. Mappings are typically defined using the certificate mapping features of either IIS or Active Directory. IIS mappings can be varied from web site to web site but it's difficult to manage more than a small number of mappings. Active Directory mappings are the same all across the directory but the centralized directory makes the mappings easier to manage. Next time: How WebServiceHost Works Read More...
  • Serializing XML to XML

    How should I represent raw XML content in a contract? It seems like it would be really easy to have within the large blob of XML that makes up a message, a small blob of XML. However, it's more challenging to deal with that situation than you might expect because that small blob of XML has to be handled unlike everything else. With most contracts you can chew along the message and place each of the resulting bits in its proper place. When trying to preserve the raw XML though, you have to know when not to chew. In your contract you should use XMLSerializer formatted fields to turn off most of the unnecessary thinking regarding the XML content. Then, XmlSerializer knows about special handling for XmlElement and XmlAttribute to complete the mapping between pieces in the message and fields in your type. These two types work under the covers with XmlSerializer even though they don't implement the standard contract for serialization. With Orcas, you can also use the new XElement type that is defined by XLinq. XLinq doesn't have any deep integration with XmlSerializer but XElement directly implements the IXmlSerializable contract to make things work. Next time: Mapping Client Certificates Read More...
  • Acting on Open

    How do I run a custom event once when the service is first started? The easiest way to execute some custom code when a service is started is to hook the service's Open method. Although the Open method has two different moments in time that you might be interested in, I'll just say Open to refer to them both. Opening is the moment in time just before the service is started; Opened is the moment in time just after. There a few different ways of hooking Open depending on what objects you have available. If you have access to a ServiceHost instance before Open is called, then you can hook Open by attaching an event handler to either the Opening or Opened events. This is the least invasive approach. If you're the one that's actually responsible for creating the ServiceHost instance, then you can also build your custom event directly into the host. You do this by overriding either the OnOpened or OnOpening methods. In either case, be sure to call the base method at some point. This is a more invasive approach because you have to make a subclass but you have finer control over the timing of the custom event relative to other code. If you don't control the ServiceHost, then you're probably running inside a hosted environment that uses ServiceHostFactory. Similar to subclassing ServiceHost, you can subclass ServiceHostFactory to install your custom event. Typically you would create an instance of a ServiceHost subclass from the ServiceHostFactory rather than putting the custom event logic in the ServiceHostFactory itself. Here's an example program showing the ServiceHost subclass approach. using System; using System.ServiceModel; using System.ServiceModel.Channels; public class MyServiceHost : ServiceHost { public MyServiceHost(Type serviceType, params Uri[] baseAddresses) : base (serviceType, baseAddresses) { } protected override void OnOpened() { base .OnOpened(); Console.WriteLine( "On opened" ); } protected override void OnOpening() { base .OnOpening(); Console.WriteLine( "On opening" ); } } [ServiceContract] public interface IMyService { [OperationContract] string Echo( string s); } public class MyService : IMyService { public string Echo( string s) { return s; } } class Program { static void Main( string [] args) { string address = "http://localhost:8000/" ; Binding binding = new BasicHttpBinding(); ServiceHost host = new MyServiceHost( typeof (MyService), new Uri(address)); host.AddServiceEndpoint( typeof (IMyService), binding, "" ); host.Open(); ChannelFactory<IMyService> Read More...
  • You Are Here

    Inside of a service method, how do I know where the message was delivered? Without defining what distinguishes a location it's hard to explain where 'here' is. I've got a few guesses though based on the most common variations of this question: OperationContext.Current.IncomingMessageHeaders.To OperationContext.Current.IncomingMessageProperties.Via HostingEnvironment.ApplicationVirtualPath Assembly.GetExecutingAssembly().Location HostingEnvironment.ApplicationPhysicalPath Next time: Serialization Temporary Assemblies Read More...
  • Forwarding Transactions

    I want to receive messages that contain a transaction and forward those messages to another service. How do I configure WCF to accept transactions without executing the service method under a transaction? In normal transactional messaging processing you would use the TransactionScopeRequired attribute to declare your interest in having a transaction. By setting TransactionScopeRequired to true, you are requesting a guarantee that a transaction scope exists when the service method is executed. If you've also set the TransactionFlow attribute to true and the sender flowed a transaction with the message, then that flowed transaction would be used to construct the transaction scope. Otherwise, a new transaction would be created before your service method is invoked. In this case you want the behavior of supporting a flowed transaction without actually creating the transaction scope. By setting TransactionScopeRequired to false, you are requesting that the service method not be provided with a transaction scope. However, you can still set TransactionFlow to true to allow the sender to flow a transaction with the message. This gives you the flowed transaction to forward to another service without creating unwanted transaction scopes. The incoming messages will include a TransactionMessageProperty if you want to access the flowed transaction. Next time: Tracing Network Calls Read More...
  • Quotas for Copying Messages

    Is it possible to copy a very large message? The CreateBufferedCopy method of Message requires a quota parameter that is only integer sized. There has always been a direct way around the problem of copying messages, which is that any message allows you to run it through an XmlReader or XmlWriter, depending on the convenience of your perspective. The XML APIs allow you to synchronously pull limitless amounts of content at your leisure, although they optionally can enforce quotas as well. The XML approach is somewhat painful though as running a message through a null loop to create a new copy requires much more careful coding than a method that is directly designed to stamp out copies. The XML approach also, while not implying any performance disadvantage, negates any potential performance advantage that might be gained by cleverly optimizing the copy operation for a specific implementation of message. However, I'm willing to take the interpretation that the quota of CreateBufferedCopy refers to the largest buffer that the copy may allocate rather than the largest message that the copy may represent. This is an important distinction because I may be able to represent a message that is much larger than I could hold in memory. For example, the message may be backed by a non-memory store or be algorithmically generated. The essence of a streamed message is that the message object in memory is much smaller than the message itself. Of course, none of the message implementations that I know of today decouple the representation size and message buffer size, but that doesn’t preclude an implementation like that existing in the future. Next time: Forwarding Transactions Read More...
  • Finding the Service Instance

    How do I get access to the service instance from inside of a service operation? Assuming that you're executing somewhere that a service operation is meaningful, you'll have access to the service operation context OperationContext.Current. From the service operation context you can get the service instance context and from the instance context you can ask it to GetServiceInstance. How does the context know how to give you a service instance? Early on in the execution of the operation, the service operation context was created. Shortly thereafter, a service instance context was created or one was reused if we happened to have it lying around and the service instance context was attached to the service operation context. The service instance context had attached to it an IInstanceProvider, which is the extensibility point for managing instances. There are a variety of instance providers for different uses that come with the system. An instance provider is able to cough up an instance based on a service instance context and optionally the message that is being processed. Next time: Building with Encoders Read More...
  • Disabling the Visual Studio Service Host

    When debugging a WCF project in Visual Studio the WCF Service Host starts up to host my service. How do I stop this from happening so that I can use my own service host? One of the new tools in Orcas is the WCF Service Host that allows you to automatically host and test a service that you've implemented. The WCF Service Host comes along with some of the specialized WCF project templates in Visual Studio, such as WCF Service Library and Syndication Service Library. If you've picked one of these project templates, then I don't know of a good way of disabling the service host. This should be fixed in SP1 by adding some user interface to toggle the service host on and off. In the meantime, you can perform some surgery on the project file to work around this. If you look inside the actual csproj file for your project, then you'll see a PropertyGroup section that defines the project. < PropertyGroup > < Configuration Condition =" '$(Configuration)' == '' " > Debug </ Configuration > < Platform Condition =" '$(Platform)' == '' " > AnyCPU </ Platform > < ProductVersion > 9.0.21022 </ ProductVersion > < SchemaVersion > 2.0 </ SchemaVersion > < ProjectGuid > {3CC71D2E-7EC2-46B5-B985-F889B65E3DCD} </ ProjectGuid > < OutputType > Library </ OutputType > < AppDesignerFolder > Properties </ AppDesignerFolder > < RootNamespace > WcfServiceLibrary1 </ RootNamespace > < AssemblyName > WcfServiceLibrary1 </ AssemblyName > < ProjectTypeGuids > {3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} </ ProjectTypeGuids > < StartArguments > /client:"WcfTestClient.exe" </ StartArguments > < TargetFrameworkVersion > v3.5 </ TargetFrameworkVersion > </ PropertyGroup > The ProjectTypeGuids list is what controls these special features of projects. Removing the {3D9AD99F-2412-4246-B90B-4EAA41C64699} entry from the list will disable automatic service hosting. Next time: Debugging Type Loading Read More...
  • Setting the Configuration Name

    What's the difference between the Name and ConfigurationName on service contracts and behaviors? The Name property sets the name of the service in metadata while the ConfigurationName property sets the name of the service in configuration. Metadata is the part of the service description that is transmitted to others when they interrogate your service. Configuration is the purely local settings for controlling the service. Since Name is more commonly used, I'll just run through a quick example focusing on setting ConfigurationName instead. Here I've got a service contract and implementation setting both the Name and ConfigurationName properties. [ServiceContract(Name= "NotIService" , ConfigurationName= "IService" )] public interface IMyService { [OperationContract] void DoNothing(); } [ServiceBehavior(Name = "NotService" , ConfigurationName = "Service" )] public class MyService : IMyService { public void DoNothing() { } } In my app.config file, the way I'd refer to that service and service endpoint is by the ConfigurationName. < service name ="Service" > < endpoint address ="http://localhost:8000/" binding ="basicHttpBinding" bindingConfiguration ="myBindingConfiguration" contract ="IService" /> </ service > On the other hand, everywhere in the metadata, generated proxy, and even the generated proxy configuration file the service will appear as NotIService and NotService. Next time: Disabling the Visual Studio Service Host Read More...
  • Generating Types with Lists

    I have a data contract that contains a collection type but the generated proxy appears as an array. How can I make the proxy use a collection type as well? I've talked in the past about how the representation of a type in metadata is decoupled from the CLR representation of a type in the service. For example, if I have a data contract that uses a List: [DataContract] class Data { [DataMember] public List< string > data; } Then, the metadata representation of this data contract is actually described as an array because arrays are the only primitive type for collections in schema. < xs:schema xmlns:tns ="http://schemas.datacontract.org/2004/07/" elementformdefault ="qualified" targetnamespace ="http://schemas.datacontract.org/2004/07/" xmlns:xs ="http://www.w3.org/2001/XMLSchema" > < xs:import namespace ="http://schemas.microsoft.com/2003/10/Serialization/Arrays" > < xs:complexType name ="Data" > < xs:sequence > < xs:element xmlns:q1 ="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minoccurs ="0" name ="data" nillable ="true" type ="q1:ArrayOfstring" > </ xs:element > </ xs:sequence > < xs:element name ="Data" nillable ="true" type ="tns:Data" > </ xs:element > </ xs:complexType ></ xs:import ></ xs:schema > However, just as the metadata representation isn't coupled to the service, the metadata representation also isn't coupled to the client. You can on the client generate proxies with any type for this collection that similarly can be serialized or deserialized to an array. The mechanism for doing this with svcutil.exe is the /ct switch. The /ct switch, which stands for collectionType, allows you to give a qualified type name that is used for collection data types when generating a proxy. As an example, to get back to the original collection class used by the server, the proxy would need to be constructed using /ct:System.Collections.Generic.List`1 as the option passed to svcutil.exe. However, you could leave the proxy using arrays or provide a different collection class such as /ct:System.Collections.ObjectModel.Collection`1 and with any of these configurations the proxy would be able to exchange messages with the server. Next time: Setting the Configuration Name Read More...
More Posts Next page »

Copyright © 2006 Microsoft Corporation. All Rights Reserved. | Terms of Use | Privacy Statement | Contact Us