views:

525

answers:

4

When accessing Silverlight in WCF you get proxies generated with ObservableCollection

Thats fine when you're databinding, but a little clumsy when you're just calling a method. For instance the following service method :

    [OperationContract]
    public SearchOrdersMsgOut SearchOrders(ShippingStatusType[] shippingStatuses,
                                           string[] orderId)
    {
    }

gets generated with ObservableCollection. What! They're just parameters. Why would I ever want to 'observe' them?

I'm fine if I have to do this - but it seems like there should be a way to force simple array structures when I know I'm never databinding - especially on input messages.

I'd much rather do this :

 searchCriteria.PaymentStatus = new [] { PaymentStatusType.PaymentFailed, PaymentStatusType.Unpaid };

than this :

 searchCriteria.PaymentStatus = new ObservableCollection<PaymentStatusType> { PaymentStatusType.PaymentFailed, PaymentStatusType.Unpaid };

Is there a way?

PS. I do actually use a SearchCriteria object for my search criteria - but I simplified for this example wondering if parameters were handled differently.

+1  A: 

You can do this service-wide, but not on a per-method basis. In the Add Service Reference dialog box, click on "Advanced", and choose "System.Array" for the Collection type. But I'm not aware of any way to do it method-by-method, i.e., use array for some methods and ObservableCollection for others.

Ken Smith
A: 

OK here's a bizarre twist after having got used to using ObservableCollection for my silverlight clients.

I tried to return a Linq2XSD object from my WCF service - and then suddenly low and behold it changed all the ObservableCollection<T> properties into simple arrays [].

I thought it was something specific to Linq2XSD - so I tried just adding a simple XTypedElement property to the service definition:

    public XTypedElement[] PipelineLogs { get; set; }

This triggers [] instead of ObservableCollection<T> in the generated proxy - where normally string[] would become ObservableCollection<string>.

Don't ask me why!

I've since removed it because I actually prefer ObservableCollection<T>. I just thought the observation might interest someone with a similar problem - especially if anyone can explain why its doing it!

Simon_Weaver
I've seen some really weird behavior from the "Add Service References" feature, including randomly switching all my ObservableCollections to Arrays. It's apparently a known bug, and I read somewhere recently that MS plans to fix it in the VS2010 RC (presumably coming in late February/early March). But it's really darned annoying, and I have no idea if MS plans to fix it in a VS2008 service pack.
Ken Smith
ya this one was pretty random
Simon_Weaver
A: 

Ended having the OPPOSITE problem when VS2010 RC had a bug preventing it from generating ObservableCollections.

Fortunately there are two workarounds:

Option 1: Believe the best option – this is to update the “Reference.svcmap” file for the impacted service reference. In Solution Explorer, select “show all files” and expand the impacted reference node. There you will find the “Reference.svcmap” file, double click to open into the editor. For the observablecollection mapping, you should see currently something like this:

 <CollectionMapping TypeName="System.Collections.ObjectModel.ObservableCollection`1" Category="List" />

Change TypeName value to include the Silverlight assembly “System.Windows” – like below :

 <CollectionMapping TypeName="System.Collections.ObjectModel.ObservableCollection`1, System.Windows" Category="List" />

Option 2: Generate your Reference.vb/.cs service reference proxy code files outside of VS by using directly SLSvcUtil.exe. Example of running the tool via command-line where it will address the observablecollection issue code generation issue: "C:\Program Files (x86)\Microsoft SDKs\Silverlight\v3.0\Tools\SlSvcUtil.exe” /r:"C:\Program Files (x86)\Microsoft Silverlight\3.0.40818.0\System.Windows.dll" /ct:System.Collections.ObjectModel.ObservableCollection`1 http:///Service1.svc This will by default generate a C# version of your service reference proxy code. If you need to generate a VB version, you can pass a “/Language:VB” switch.

Simon_Weaver
A: 

Another thing to check (if you want ObservableCollection<T> but you're getting T[]) - is the Reference.svcmap file

Make sure that you have included 'System.Windows' in the typename.

  <CollectionMapping TypeName="System.Collections.ObjectModel.ObservableCollection`1, System.Windows" Category="List" />

and not

  <CollectionMapping TypeName="System.Collections.ObjectModel.ObservableCollection`1" Category="List" />

I'm guessing perhaps it can't find the Dll and defaults to []

Simon_Weaver