Welcome to Windows Communication Foundation (WCF)
Top Tasks :

WCF Team Bloggers

Browse by Tags

All Tags » Answers » Indigo   (RSS)

  • Waiting for Ready Channels

    When I create a channel to a service, how do I know when the service is ready to process the data for that channel? A channel doesn't really know what the service is doing. The service might be actively processing the data being sent over the channel. Or, the service might not. There is a constant tension in the system between components that want to push data and components that want to pull data. Components that push data actively work as long as there is data available until a back pressure builds up in the system that resists their ability to push. This back pressure is typically the result of some queue or buffer that has filled up and is no longer able to accept the things being pushed into it. Components that push include several transport and protocol channels, as well as the service dispatcher that pushes messages to the service implementation. Components that pull data remain quiescent even if data is available until there is someone that actually wants to consume some data. Many transport and protocol channels pull messages rather than push. A single implementation may feature both push and pull modes. For example, the TCP channel has a small portion that works in a push mode for connection establishment and transferring some initial data while the application portion of TCP works in a pull mode. Depending on the visibility of these push and pull modes, you might be able to tell from the behavior of a particular protocol what the service is doing. For example, if you're using just TCP, then the initial transmissions needed to open a connection can only be completed once a little bit of pulling has been done on the receiving application side, thus telling you that the service is doing some active processing. On the other hand, if you're using a ReliableMessaging channel or a OneWay channel, then those protocols have a visible running state where they are in push mode. You can't actually tell whether the service is working until you fill up some of the buffers in the protocol stack and start getting push back in the form of rejected messages. That means the service is not working as fast as you're sending data. A queued channel would be an extreme example of push mode. A message queue allows you to push large amounts of data when the service is not even running. Therefore, to know in the general case whether the service is ready to process for you, you need to be able to ask that question to the service rather than to the channel. Next time: Composing Read More...
  • Pipe Properties

    How can I find the pipe object on the system created by a named pipe binding? The simplest way to find the named pipe is to use a tool like Process Explorer to examine your running executable. If you look inside a client or service that has the named pipe open, then you'll see a file handle that looks like this: \Device\NamedPipe\f422aed9-6058-4bab-90b1-fe856bdcbd80 The unique identifier at the end will be different on your machine, and in fact, will be different every time you run the program. The named pipe handle may only exist while you've got the pipe open, so it's typically easier to find the pipe from the listener side than the client side. If you're not sure that the named pipe you're looking at is the pipe created by WCF, then you can typically tell by the security properties since WCF has a particular configuration it uses. For a WCF named pipe, everyone will have permission to Synchronize, Query State, or Modify State on the pipe, while Network users will specifically be denied access to the pipe. Next time: Avoiding Infinite Schema Chains Read More...
  • Streaming Web Content

    How do I deliver content from a WCF service as part of a web page? Web page content in this case typically refers to HTML, images, or other data that is directly consumed by the web browser rather than an application running in the web browser. There are a few things you need to do to make your web service serve up content in a way that's indistinguishable from an ordinary web server. I'll serve up a static image at a fixed location for this example but you can get as fancy as you'd like. The first thing you need is the right contract. The initial page load is ordinarily retrieved using the HTTP GET verb rather than the HTTP POST verb assumed by web services. I'll set that up as part of my contract using the WebGet attribute to set the verb and a URI template to set the address. [ServiceContract] public interface IService { [OperationContract] [WebGet(UriTemplate = "/image" )] Stream GetImage(); } The second thing you need is the right content type. Although web browsers can try to autodetect content, you should specify the content type if it is known. This allows the web browser to process the content correctly inline. public class Service : IService { public Stream GetImage() { WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg" ; return new FileStream( "c:\\test.jpg" , FileMode.Open, FileAccess.Read); } } Finally, you may notice that while I've done everything needed in the service implementation to enable streaming, content can only be streamed if the binding supports this as well. When using WebServiceHost, the default bindings do not support streamed content. This may be hard to spot because the typical files are small and a test program running on the same machine completes the transfers before streaming would make a difference. I've wrapped the service implementation in this example to intentionally slow down the transfer to make the difference more apparent. The following code demonstrates enabling streaming on the binding. You can change the transfer mode back to Buffered to observe the difference. Streaming requires support in the receiving application as well to make a difference. Using a large, progressive encoded image will demonstrate this. using System; using System.IO; using System.ServiceModel; using System.ServiceModel.Web; using System.Threading; public class SlowStream : Stream { Stream innerStream; public SlowStream(Stream innerStream) { this .innerStream = innerStream; } public override bool CanRead { get { return Read More...
  • Getting Rid of Namespaces

    How do I write a contract for a wrapped message in the default namespace? I've written a quick sample to demonstrate what happens when you write the contract without taking any namespaces into account. [ServiceContract] public interface IService { [OperationContract] [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "/" )] void ProcessRequest( string data); } public class Service : IService { public void ProcessRequest( string data) { Console.WriteLine(OperationContext.Current.RequestContext.RequestMessage); } } class Program { static void Main( string [] args) { string address = "http://localhost:8000/" ; WebServiceHost host = new WebServiceHost( typeof (Service), new Uri(address)); host.Open(); ChannelFactory<IService> factory = new ChannelFactory<IService>( new WebHttpBinding()); factory.Open(); IService proxy = factory.CreateChannel( new EndpointAddress(address)); using ( new OperationContextScope((IContextChannel)proxy)) { OperationContext.Current.OutgoingMessageHeaders.To = new Uri(address); proxy.ProcessRequest( "data" ); } factory.Close(); host.Close(); Console.ReadLine(); } } Running the sample reveals that the message wrapper gets an unpleasant namespace instead of the default namespace. < ProcessRequest xmlns ="http://tempuri.org/" > < data > data </ data > </ ProcessRequest > By looking at the metadata, you could figure out where this namespace was coming from using the custom namespace sample I published earlier. In this case the problem is with the operation wrapper, which comes from the service contract. Setting the service contract to have a namespace of "" gets us the desired default namespace. Next time: Using Faults with Untyped Messages Read More...
  • 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...
More Posts Next page »

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