2011-08-26 27 views
8

Trong khi sử dụng lớp Rss20FeedFormatter trong một dự án WCF, tôi đã cố gắng bọc nội dung của các phần tử mô tả của mình với một phần <![CDATA[ ]]>. Tôi thấy rằng không có vấn đề gì tôi đã làm, nội dung HTML của các yếu tố mô tả luôn được mã hóa và phần CDATA chưa bao giờ được thêm vào. Sau khi nhìn vào mã nguồn của Rss20FeedFormatter, tôi thấy rằng khi xây dựng nút Tóm tắt, về cơ bản nó tạo ra một cá thể TextSyndicationContent mới xóa sạch mọi cài đặt đã được chỉ định trước đó (Tôi nghĩ).Rss20FeedFormatter Bỏ qua TextSyndicationLoại nội dung cho SyndicationItem.Summary

Mã My

public class CDataSyndicationContent : TextSyndicationContent 
{ 
    public CDataSyndicationContent(TextSyndicationContent content) 
     : base(content) 
    { 
    } 

    protected override void WriteContentsTo(System.Xml.XmlWriter writer) 
    { 
     writer.WriteCData(Text); 
    } 
} 

... (Các mã sau đây nên quấn Tóm tắt thông tin với một phần CDATA)

SyndicationItem item = new SyndicationItem(); 
item.Title = new TextSyndicationContent(name); 
item.Summary = new CDataSyndicationContent(
        new TextSyndicationContent(
         "<div>This is a test</div>", 
         TextSyndicationContentKind.Html)); 

Rss20FeedFormatter Mã (AFAIK, các mã trên không hoạt động vì logic này)

... 
else if (reader.IsStartElement("description", "")) 
    result.Summary = new TextSyndicationContent(reader.ReadElementString()); 
... 

Giải pháp thay thế, tôi đã sử dụng RSS20FeedFormatter để tạo RSS và sau đó vá RSS theo cách thủ công. Ví dụ:

 StringBuilder buffer = new StringBuilder(); 
     XmlTextWriter writer = new XmlTextWriter(new StringWriter(buffer)); 
     feedFormatter.WriteTo(writer); // feedFormatter = RSS20FeedFormatter 

     PostProcessOutputBuffer(buffer); 
     WebOperationContext.Current.OutgoingResponse.ContentType = 
            "application/xml; charset=utf-8"; 
     return new MemoryStream(Encoding.UTF8.GetBytes(buffer.ToString()));  

...

public void PostProcessOutputBuffer(StringBuilder buffer) 
    { 
     var xmlDoc = XDocument.Parse(buffer.ToString()); 
     foreach (var element in xmlDoc.Descendants("channel").First() 
             .Descendants("item") 
             .Descendants("description")) 
     { 
      VerifyCdataHtmlEncoding(buffer, element); 
     } 

     foreach (var element in xmlDoc.Descendants("channel").First() 
             .Descendants("description")) 
     { 
      VerifyCdataHtmlEncoding(buffer, element); 
     } 

     buffer.Replace(" xmlns:a10=\"http://www.w3.org/2005/Atom\"", 
         " xmlns:atom=\"http://www.w3.org/2005/Atom\""); 
     buffer.Replace("a10:", "atom:"); 
    } 

    private static void VerifyCdataHtmlEncoding(StringBuilder buffer, 
               XElement element) 
    { 
     if (!element.Value.Contains("<") || !element.Value.Contains(">")) 
     { 
      return; 
     } 

     var cdataValue = string.Format("<{0}><![CDATA[{1}]]></{2}>", 
             element.Name, 
             element.Value, 
             element.Name); 
     buffer.Replace(element.ToString(), cdataValue); 
    } 

Ý tưởng cho việc này xuất phát từ vị trí sau, tôi chỉ thích nghi nó để làm việc với WCF thay vì MVC. http://localhost:8732/Design_Time_Addresses/SyndicationServiceLibrary1/Feed1/

Tôi chỉ tự hỏi liệu đây có phải là lỗi trong Rss20FeedFormatter hay là do thiết kế? Ngoài ra, nếu có ai có giải pháp tốt hơn, tôi rất muốn nghe nó!

Trả lời

2

Vâng @Page Brooks, tôi thấy điều này như một giải pháp sau đó là một câu hỏi :). Cảm ơn!!! Và để trả lời câu hỏi của bạn (;)), có, tôi chắc chắn nghĩ rằng đây là một lỗi trong Rss20FeedFormatter (mặc dù tôi đã không đuổi theo nó), bởi vì đã gặp chính xác cùng một vấn đề mà bạn mô tả.

Bạn có giới thiệu 'localhost: 8732' trong bài đăng của mình nhưng không có sẵn trên máy chủ cục bộ của tôi;). Tôi nghĩ rằng bạn có nghĩa là để tín dụng thực hiện giải pháp 'PostProcessOutputBuffer' bài này: http://damieng.com/blog/2010/04/26/creating-rss-feeds-in-asp-net-mvc

Hoặc thực sự nó không phải là trong bài viết này, nhưng trong một chú thích cho nó bằng cách David Whitney, mà sau này ông đưa vào một ý chính riêng biệt ở đây: https://gist.github.com/davidwhitney/1027181

Cảm ơn bạn đã cung cấp sự thích nghi của giải pháp này theo nhu cầu của tôi, vì tôi cũng đã tìm được cách giải quyết, nhưng vẫn đang vật lộn để thực hiện việc thích ứng từ MVC. Bây giờ tôi chỉ cần tinh chỉnh giải pháp của bạn để đặt nguồn cấp dữ liệu RSS cho yêu cầu hiện tại của Http trong trình xử lý .ashx mà tôi đang sử dụng nó.

Về cơ bản tôi đoán rằng bản sửa lỗi bạn đã đề cập bằng CDataSyndicationContent, là từ feb 2011, giả sử bạn nhận được từ bài đăng này (ít nhất là tôi đã làm): SyndicationFeed: Content as CDATA?

Sửa chữa này đã ngừng hoạt động trong một số ASP mới hơn.NET phiên bản hoặc một cái gì đó, do mã của Rss20FeedFormatter thay đổi những gì bạn đưa vào bài viết của bạn. Sự thay đổi mã này cũng có thể đã được cải thiện cho những thứ khác mà IS trong khuôn khổ MVC, nhưng đối với những người sử dụng CDataSyndicationContent sửa chữa nó chắc chắn gây ra một lỗi!

0

Tôi tìm thấy mã cho CDATA nơi khác

public class CDataSyndicationContent : TextSyndicationContent 
{ 
    public CDataSyndicationContent(TextSyndicationContent content) 
     : base(content) 
    { 
    } 

    protected override void WriteContentsTo(System.Xml.XmlWriter writer) 
    { 
     writer.WriteCData(Text); 
    } 
} 

Mã để gọi nó là một cái gì đó dọc theo dòng:

item.Content = new Helpers.CDataSyndicationContent(new TextSyndicationContent("<span>TEST2</span>", TextSyndicationContentKind.Html)); 

Tuy nhiên, "WriteContentsTo" chức năng đã không được gọi.

Thay vì Rss20FeedFormatter tôi đã dùng Atom10FeedFormatter - và nó đã hoạt động! Rõ ràng điều này cung cấp cho nguồn cấp dữ liệu Atom thay vì RSS truyền thống - nhưng đáng nói đến.

đang Output là:

//var formatter = new Rss20FeedFormatter(feed); 
    Atom10FeedFormatter formatter = new Atom10FeedFormatter(feed); 
    using (var writer = XmlWriter.Create(response.Output, new XmlWriterSettings { Indent = true })) 
    { 
     formatter.WriteTo(writer); 
    } 
0
string stylesheet = @"<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""><xsl:output cdata-section-elements=""description"" method=""xml"" indent=""yes""/></xsl:stylesheet>"; 
XmlReader reader = XmlReader.Create(new StringReader(stylesheet)); 
XslCompiledTransform t = new XslCompiledTransform(true); 
t.Load(reader); 

using (MemoryStream ms = new MemoryStream()) 
{ 
    XmlWriter writer = XmlWriter.Create(ms, t.OutputSettings); 
    rssFeed.WriteTo(writer); // rssFeed is Rss20FeedFormatter 
    writer.Flush(); 
    ms.Position = 0; 
    string niko = Encoding.UTF8.GetString(ms.ToArray()); 
} 

Tôi chắc rằng ai đó chỉ ra điều này đã nhưng điều này một cách giải quyết ngu ngốc tôi đã sử dụng. t.Oputputettings là loại XmlWriterSettings với cdataSections được dân cư với một XmlQualifiedName "mô tả" duy nhất.

Hy vọng nó sẽ giúp người khác.

Các vấn đề liên quan