I have a simple console app that calls a WCF service over net.tcp and uploads a file (using Stream). The WCF service is self-hosted, Framework 4.0.
I am looking for a way to now add some "progress info" on the client-side. Should this be done with hand-written IASync operations, or something else altogether?
This is actually pretty easy, though the solution doesn't really have anything to do with WCF. Create a wrapper Stream subclass that you pass the actual source Stream into. In the various Read overrides, first delegate to the underlying Stream you're wrapping. Next, increment a custom property with the number of bytes read and either fire a custom event or maybe implement INotifyPropertyChanged on the custom Stream subclass. By doing this, as WCF reads from the wrapper Stream to get the bytes to send over the wire, your client will be able to observe the changes.
Related
Now I need to reference a WCF service in a UWP program. However, the address of the WCF service may change frequently in the future.
I don't want to rebuild/republish the project every time when the address change.
So I want to use a LocalSettings to Save/Load the address of WCF service. Every the program begins, it will reload the address from the LocalSettings. And if the address changes, I just only let the customer change the LocalSettings from UI but not need to rebuild/republish the project.
How can I do it? Or there is any other better to do it?
If it's a RESTful service, you could use HttpClient relevant APIs to consume a REST service in UWP.
Please note that REST is a resource that implements a uniform interface using standard HTTP GET, POST, PUT methods that can be located by URI. So, you could use HttpClient to call it in code-behind. You will get response after you send http request, then you could analysis the response result.
The similar thread for your reference: Calling web service asynchronously in page constructor.
Using LocalSettings for such thing is a good solution.
LocalSettings are just a dictionary where you can assign values you want to store and later take out.
ApplicationData.Current.LocalSettings["ServiceAddress"] = "something";
Debug.WriteLine(ApplicationData.Current.LocalSettings["ServiceAddress"]);
Such setting will survive app restart and is stored in applicaton's private storage.
You will probably want to seed this setting with a default value at first startup.
I'm developing an app using MonoTouch and have to get some data from a 3rd party web service. I have a WCF binding to do such.
The particular web service method I am calling could potentially return an XML string in the range of several hundred megabytes, which could take a while to download to a mobile device.
I'm looking for some way to capture how many bytes have been read from the network at the system level, with the end-game being to display a progress indicator to the user. Is there some way I can achieve this using Behaviors?
Note, I don't have any way to modify the web service code to return a Stream object, which is what most of the articles I have found require doing.
Any help or direction would be much appreciated. Thanks
As a last resort, I can always fall back on using an NSURLConnection to do this, instead of WCF, because I know there are NSURLConnectionDelegate methods to hook into that will provide this. I wanted to avoid NSURLConnection, so that I will be able to easily drop this code into an Android project in the future.
Is there a reason to use WCF instead of the plain HttpWebRequest?
WCF is not exactly efficient at parsing data, it will keep multiple copies in memory to deserialize the various chunks of information.
There is no system level API that can provide this information, the Stream that you get back from the HttpWebRequest is the best value that you will get.
Has anybody been able to implement HTML 5 server-sent events using WCF REST? I have attempted to do it by creating a rest service that returns a Stream and this works if I use a "hard coded" event stream (i.e. I just create a string with the event text in, turn it into a MemoryStream that is then returned by the service operation). I can then see the events happening in my test page in Chrome. However, when I try to add events to the stream asynchronously, it fails because the stream is already closed. I think I need a way of keeping the stream open permanently.
Any advice greatly appreciated!
p.s. I can't use a duplex WCF binding for this because the HTML 5 specifies non-SOAP clients (obviously).
I think you have to implement your own Binding in this case. There's no built-in Binding for comet (server-push).
There is now a WCF binding for this called NetHttpBinding:
http://msdn.microsoft.com/en-us/library/system.servicemodel.nethttpbinding.aspx
Alternatively the same thing can be achieved using SignalR, which is part of ASP.Net
http://signalr.net/
I am using wcf 4 and trying to transparently transfer context information between client and server.
I was looking at behaviors and was able to pass things around. My problem is how to flow the context received in the incoming headers to the other services that might be called by a service.
In the service behavior I intercept the the message and read the headers but don't know where to put that data to be accessible to the next service call that the current service might make.
What I am looking for is something like:
public void DoWork()
{
var someId = MyContext.SomeId;
//do something with it here and call another service
using(var proxy = GetProxy<IAnotherService>())
proxy.CallSomeOtherMethodThatShouldGetAccessTo_ MyContextualObject();
}
If I store the headers in thread local storage I might have problems due to thread agility(not sure this happens outside ASP.NET, aka custom service hosts). How would you implement the MyContext in the code above.
I chose the MyContext instead of accessing the headers directly because the initiator of the service call might not be a service in which case the MyContext is backed by HttpContext for example for storage.
In the service behavior I intercept
the the message and read the headers
but don't know where to put that data
to be accessible to the next service
call.
Typically, you don't have any state between calls. Each call is totally autonomous, each call gets a brand new instance of your service class created from scratch. That's the recommended best practice.
If you need to pass that piece of information (language, settings, whatever) to a second, third, fourth call, do so by passing it in their headers, too. Do not start to put state into the WCF server side! WCF services should always be totally autonomous and not retain any state, if at ever possible.
UPDATE: ok, after your comments: what might be of interest to you is the new RoutingService base class that will be shipped with WCF 4. It allows scenarios like you describe - getting a message from the outside and forwarding it to another service somewhere in the background. Google for "WCF4 RoutingService" - you should find a number of articles. I couldn't find antyhing in specific about headers, but I guess those would be transparently transported along.
There's also a two-part article series Building a WCF Router Part 1 (and part 2 here) in MSDN Magazine that accomplishes more or less the same in WCF 3.5 - again, not sure about headers, but maybe that could give you an idea.
Is it possible to pass a delegate to a WCF remote object from the client and have the remote object execute the delegate?
I would guess not since a delgate is a function pointer for the client process.
My goal is to have an interface structure that I can "subscribe" to events from a client to the interface. I would pass a delgate from the client to the interface and I want the interface to be able to execute the event.
The idea is to have the ability for the interface to be loaded either the assembly or remotly and have the code work the same.
If I can't pass the delegate how can I implement an event structure?
not a "delegate" in C# per se, but in WCF you have duplex bindings to enable call back from the service side to the client side
http://msdn.microsoft.com/en-us/library/system.servicemodel.wsdualhttpbinding.aspx
I doubt you could come up with a cohesive way to pass a delegate from a C# client to a Java service implementation and have it properly executed......
WCF is not a strict .NET implementation and thus has to deal with interop issues. It cannot rely on the assumption that both ends of the conversation are in .NET - that's why you shouldn't throw around custom exceptions between server and client either (exceptions are a .NET construct) - you need to use SOAP faults instead (which are interoperable).
So I don't think what you want to do can be done with a delegate - you'll have to come up with another way to achieve your goal.
Marc