Cannot return a CollectionContext from a WCF RESTful service
In your Sitefinity Convention Assurance documentation regrading creation of WCF RESTful services (Sitefinity 4.0), you state:
For every OperationContract (web service method) that retrieves a collection of items, return an object of type CollectionContext<T>, where you pass the type of the resource as a generic argument.
When I try to return a CollectionContext I get the following error:
Telerik.Sitefinity.Web.Services.CollectionContext`1[InstaOrderOpenAccess.EsfManufacturer] cannot be serialized because it does not have a parameterless constructor.
This error makes sense as the CollectionContext object does not have a parameterless constructor.
How do I return a CollectionContext object in my WCF service?
Thanks
- Courtney
P.S. Your online SiteFinity 4.0 RC Developer's Guide that talks about each of the Client Binder Controls (where I thought i might find an answer to this in an example) has links to sample code that do not work:
http://www.sitefinity.com/40/help/developer-manual/a3c3e363-2b58-4ac6-8c6b-d3c05171cb87.html
Article sample code: (broken link)
http://sitefinity.com/4.0/help/CodeExamples/RadGridBinderRead.zip
Hello Courtney,
I am sorry that the documentation has been misleading.
The collection context does not need to have a constructor without parameters, as the family of DataContractSerialzier-s use FormatterServices.GetUninitializedObject when Type.GetConstructor( Type.EmptyTypes ) returns null/Nothing.
This exception could be caused when you are not using a WCF service or for some reason it does not use XmlObjectSerializer.
Here are some instructions on how to find out what's wrong:
1.<%@ ServiceHost 2. Language="C#" 3. Debug="true" 4. Service="Telerik.Sitefinity.Modules.News.Web.Services.NewsItemService" 5. Factory="Telerik.Sitefinity.Web.Services.WcfHostFactory"6. %>[ServiceContract(Namespace = "ContentService")][AllowDynamicFields]public interface IContentService<TContent, TContentViewModel> where TContent : SfModel.Content where TContentViewModel : ContentViewModelBase [OperationContract] [WebGet(UriTemplate = "/?sortExpression=sortExpression&skip=skip&take=take&filter=filter&provider=providerName&workflowOperation=workflowOperation", ResponseFormat = WebMessageFormat.Json)] CollectionContext<TContentViewModel> GetContentItems(string sortExpression, int skip, int take, string filter, string providerName, string workflowOperation); /// <summary>/// The WCF web service that is used to work with all types that inherit from base <see cref="Content"/>/// class./// </summary>[ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)][AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]public abstract class ContentServiceBase<TContent, TParentContent, TContentViewModel, TParentContentViewModel, TContentManager> : IContentService<TContent, TContentViewModel> where TContent : Content where TParentContent : Content where TContentViewModel : ContentViewModelBase where TParentContentViewModel : ContentViewModelBase where TContentManager : class, IManager, IContentLifecycleManager<TContent>/// <summary>/// View model class for the <see cref="NewsItem"/> model./// </summary>public class NewsItemViewModel : ContentViewModelBase /// <summary> /// Initializes a new instance of the <see cref="NewsItemViewModel"/> class. /// </summary> public NewsItemViewModel() : base() If you haven't found the problem after completing those steps, here is what we will need to troubleshoot this for you:
Dido, thanks for your reply. I tried all of your suggestions but I still got the same error message:
Telerik.Sitefinity.Web.Services.CollectionContext`1[InstaOrderOpenAccess.TestManufacturer] cannot be serialized because it does not have a parameterless constructor.
After a lot of trial and error, we have discovered the source of the problem.
(Sorry I cannot seem to highlight my text like you were somehow able to!)
[ServiceContract]
public interface IManufacturerService
[OperationContract]
[WebHelp(Comment = "Get all test manufacturers")] [WebGet(UriTemplate = "/test/?sort=sort&skip=skip&take=take&filter=filter", ResponseFormat = WebMessageFormat.Json)] CollectionContext<TestManufacturer> GetTestManufacturers(string sort, int skip, int take, string filter);
[OperationContract] [XmlSerializerFormat()]
[WebHelp(Comment = "Get all test manufacturers")]
[WebGet(UriTemplate = "/test/xml/?sort=sort&skip=skip&take=take&filter=filter", ResponseFormat = WebMessageFormat.Xml)]
CollectionContext<TestManufacturer> GetTestManufacturersInXml(string sort, int skip, int take, string filter);
[OperationContract] [WebGet(UriTemplate = "/id", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat =WebMessageFormat.Json)]
TestManufacturer GetManufacturer(string id);
[OperationContract]
[XmlSerializerFormat()]
[WebGet(UriTemplate = "/xml/id", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat= WebMessageFormat.Xml)] TestManufacturer GetManufacturerInXml(string id);
Hi Courtney,
Without having the code to "play with", I can only suggest that you do remove the XmlSerializerFormat attribute.
Also, I would like to emphasize that we support DataContract serialization only, and XmlSerializer is not exactly tested. They are slightly different and obviously use different serializers: