David
David

Reputation: 3157

Using wcf to expose SyndicationFeedFormatter OR IList<SyndicationItem>

I would like to expose a SyndicationFeedFormatter with wcf and basicHttpBinding. I continue to get errors like that shown below. I have included the interface/class and the web.config wcf configuration.

I have tried to expose SyndicationFeedFormatter as well as IList but am unable to get past the following error. Has anyone been able to do this or someone confirm what the problem is?

thx - dave

Error message

System.ServiceModel.Dispatcher.NetDispatcherFaultException: The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:GetFeaturesResult. The InnerException message was 'Error in line 1 position 123. Element 'http://tempuri.org/:GetFeaturesResult' contains data of the 'http://schemas.datacontract.org/2004/07/System.ServiceModel.Syndication:Rss20FeedFormatter' data contract

My interface/contract looks like

[ServiceContract]
[ServiceKnownType(typeof(Atom10FeedFormatter))]
[ServiceKnownType(typeof(Rss20FeedFormatter))]
public interface IGetData {

    [OperationContract]
    SyndicationFeedFormatter GetFeatures();

    [OperationContract]
    IList<SyndicationItem> GetFeatures2();

}

My method looks like ....

    public SyndicationFeedFormatter GetFeatures()() {
        // Generate some items...
        SyndicationFeed feed = new SyndicationFeed() {
            Title = new TextSyndicationContent("Mike's Feed"),
            Description = new TextSyndicationContent("Mike's Feed Description")
        };

        feed.Items = from i in new int[] { 1, 2, 3, 4, 5 }
                     select new SyndicationItem() {
                         Title = new TextSyndicationContent(string.Format("Feed item {0}", i)),
                         Summary = new TextSyndicationContent("Not much to see here"),
                         PublishDate = DateTime.Now,
                         LastUpdatedTime = DateTime.Now,
                         Copyright = new TextSyndicationContent("MikeT!"),
                     };

        return (new Rss20FeedFormatter(feed));
    }

    public IList<SyndicationItem> GetFeatures2() {

        List<string> includeList = new List<string>();
        includeList.Add("Feature");

        IList<SyndicationItem> mylist = ReaderManager.GetFeedByCategory2(includeList, null, null);
        return mylist;

    }

My web.config looks like the following

binding="webHttpBinding" contract="SLNavigationApp.Web.IGetData"> -->

         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

     </service>
 </services>

 <behaviors>
     <endpointBehaviors>
         <behavior name="webHttpBehavior">
             <webHttp />
         </behavior>
     </endpointBehaviors>
     <serviceBehaviors>
         <behavior name="SLNavigationApp.Web.GetDataBehavior">
             <serviceMetadata httpGetEnabled="true" />
             <serviceDebug includeExceptionDetailInFaults="true" />
         </behavior>
    </serviceBehaviors>
 </behaviors>

Upvotes: 0

Views: 981

Answers (2)

Paul
Paul

Reputation: 303

Cool, I was wondering why my service wasn't producing browser-readable content. I was also using basicHttpBinding (because all the rest of the calls are from Silverlight).

As an unrelated sidenote:

You can change: from i in new int[] { 1, 2, 3, 4, 5 }

To: from i in Enumerable.Range(1, 5)

This can be very handy! I usually use it as "Enumerable.Range(1, pagecount)" in an XLINQ query when I'm pulling paged XML data from a server.

Upvotes: 0

tomasr
tomasr

Reputation: 13849

I'm confused: Are you using WebHttpBinding, or the BasicHttpBinding? You should definitely be using the former, and that should just work.

If you're trying to use BasicHttpBinding, do you mind sharing why? The SyndicationFeedFormatter classes aren't DataContracts or XmlSerializable (which is what you'd need to support for BasicHttpBinding), so it would likely not work in that case unless you did a little bit of extra work. What I'd likely try to get around this would be to simply change my ServiceContract to return Message objects instead, like this:

[ServiceContract]
[ServiceKnownType(typeof(Atom10FeedFormatter))]
[ServiceKnownType(typeof(Rss20FeedFormatter))]
public interface IGetData {
    [OperationContract]
    Message GetFeatures();

}

...

SyndicationFeedFormatter frm = new Rss20FeedFormatter(feed);
return Message.CreateMessage(
   MessageVersion.None, "GetFeatures", 
   new FeedBodyWriter(frm)
   );

...

class FeedBodyWriter : BodyWriter {
   SyndicationFeedFormatter formatter;
   public FeedBodyWriter(SyndicationFeedFormatter formatter) : base(false) {
      this.formatter = formatter;
   }
   protected override void OnWriteBodyContents(XmlDictionaryWriter writer) {
      formatter.WriteTo(writer);
   }
}

Upvotes: 1

Related Questions