tags:

views:

560

answers:

1

I'm testing out WPF for the first time and I'm trying to call a WCF service with an ObjectDataProvider.

WCF Service named WcfService1 with a single method:

namespace WcfService1
{
    public class Service1 : IService1
    {

        public String HelloWorld()
        {
            return "Hello World!";
        }
    }
}

I added a Service Reference to my WPF project and named it TestService

In my main window, I can call this without issue in code behind. It seems simple; like a web service call:

TestService.Service1Client service = new TestService.Service1Client(); MessageBox.Show(service.HelloWorld());

I'm trying to create an ObjectDataProvider that points to this service. I guess I'm confused as to what the ObjectType should be? I've tried local, the service namespace, src; I'm lost:

<Window.Resource>
    <ObjectDataProvider 
        x:Key="odpTestService" 
        ObjectType="{x:Type **TestService**:Service1Client}" 
        MethodName="HelloWorld" />
</Window.Resources>

Ultimatly it will bind to a TextBlock:

<TextBlock Grid.Column="0" Grid.Row="0" 
Grid.ColumnSpan="2" Background="AliceBlue"
Text="{Binding Source={StaticResource odpTestService}}" />

I was trying to work from the Flickr example posted here: http://khason.net/blog/wpf-binding-to-wcf-and-more/

Update: The answer from Denis did solve part of the issue here. Now, I'm getting an error on compile: System.Windows.Data Error: 34 : ObjectDataProvider: Failure trying to invoke method on type;

The ObjectDataProvider can't invoke the HelloWorld method with type IService1 (Using the method and type from my example). Any ideas why?

+1  A: 

You need to import the service's namespace through an xmlns directive at the top of the file:

Assuming that the reference has been added directly to your application, and that your application's root namespace is "MyApplication":

<Window x:class="MyApplication.MyWindow"
        xmlns:srv="MyApplication.TestService">

        <Window.Resource>
            <ObjectDataProvider 
                x:Key="odpTestService" 
                ObjectType="{x:Type srv:Service1Client}" 
                MethodName="HelloWorld" />
        </Window.Resources>

        <TextBlock Grid.Column="0" Grid.Row="0" 
          Grid.ColumnSpan="2" Background="AliceBlue"
          Text="{Binding Source={StaticResource odpTestService}}" />

</Window>
Denis Troller
Wow Denis, that's a big brain fart on my part. Thank you.
Coov
Denis,When running my app, I noticed an error in the object window "System.Windows.Data Error: 34 : ObjectDataProvider: Failure trying to invoke method on type; Method='GetData'; Type='IPhoenixText';". IPhoenixText is the ServiceContract interface. Is that correct? Is the type the interface and not the class?
Coov
That looks a bit weird. ow did you set-up your ObjectDataProvider?
Denis Troller
<ObjectDataProvider x:Key="odpTestService" ObjectType="{x:Type srv:Service1Client}" MethodName="HelloWorld" /> - I've tried making the Service1Client the type and that prevents me from compiling.<ObjectDataProvider x:Key="odpTestService" ObjectType="{x:Type srv:IService1}" MethodName="HelloWorld" /> - I've tried making the interface IService1 the type and that generates the failure to invoke method error.I suspect it may be an issue with the app.config but that was auto generated for me by adding the WCF service.
Coov
It should really be the concrete class, not the interface, otherwise ObjectDataProvider has no way of knowing what class to instantiate before calling the method. What happens when you set it to srv:Service1Client? You say it prevents you from compiling, but what error do you get?
Denis Troller
When I use the class Service1Client, I get this error: "Could not find default endpoint element that references contract". This is a design time error and is what leads me to believe its an app config issue.
Coov
It certainly is weird. I'm not sure what to make of it.Can you actually instantiate a Service1Client in code and call its method (bypassing you xaml completely)?
Denis Troller
Affirmative. Code behind was a snap.
Coov