Cross-Domain External Stylesheets with RadEditor

2 posts, 0 answers
  1. digitall
    digitall avatar
    169 posts
    Member since:
    Jun 2006

    Posted 07 May 2012 Link to this post

    Requirements

    RadControls version

     Q1 - 2012+

    .NET version

     All

    Visual Studio version

     All

    programming language

     C#

    browser support

    all browsers supported by RadControls


    PROJECT DESCRIPTION                                    
    Due to security limitations with browsers and JavaScript, the RadEditor control doesn't natively support adding stylesheets from different domains to the editor control. Getting around this is actually very easy though and should work in any version of .Net, although my development was with version 4 and VS11. The only requirement for this solution is knowing the name and location of the stylesheet you need and a basic understanding of HTTP Handlers.

    To start, you will need to create a generic HTTP Handler with any name you wish - I chose "getstyles.ashx". Next, you'll need to add automatic caching/expiration to the handler so you always get the latest copy of the stylesheet. This becomes essential if you pass query string values to this URL (detailed at the end of this tutorial) because the browser will cache the file you return and subsequent calls with different query string parameters will always load the previously cached version. To do this, add this inside the ProcessRequest(HttpContext) method:
    context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    context.Response.Cache.SetExpires(DateTime.MinValue);

    After those lines, you build the real meat of the handler. Assuming you know the name/location of the stylesheet you wish to link to, you just write a simple HttpWebRequest to connect to that location, download the CSS file and then return it's contents back to the editor. For the scenario I implemented this with, I used query string values to further customize which CSS file I needed to pull down (based on individual sites inside a common backend implementation). The full code for making the request is below (including the caching):

    public class getstyles : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            //disable caching to force new pulls every tyime
            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            context.Response.Cache.SetExpires(DateTime.MinValue);
     
            //create a request to the url of the stylesheet you need access to in the editor
            var request = HttpWebRequest.Create("http://www.mysite.com/styles/cms.css") as HttpWebRequest;
            try
            {
                //only return the values if there is a response and the type is text/css
                if (request.GetResponse().ContentLength > 0 && request.GetResponse().ContentType == "text/css")
                {
                    context.Response.ContentType = "text/css";
                     
                    //write the css out to the response stream
                    using (var reader = new StreamReader(request.GetResponse().GetResponseStream()))
                        context.Response.Write(reader.ReadToEnd());
     
                    //forces end of response and returning from the method
                    context.Response.End();
                }
            }
            //an empty response is returned for any web exceptions (404, 401, etc)
            catch (WebException) { }
     
            context.Response.Write(string.Empty);
            context.Response.End();
        }
     
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

    If you passed query string values to the handler, you can access them inside the HttpContext value passed into ProcessRequest like so:
    context.Request.QueryString[key]

    Once you've implemented the handler, the rest is very simple. Just link to the handler in your RadEditor code as a standard CSS file like so:

    C# Version
    this.RadEditor1.CssFiles.Add(new Telerik.Web.UI.EditorCssFile { Value = "~/getstyles.ashx" });

    C# Version with query string values
    this.RadEditor1.CssFiles.Add(new Telerik.Web.UI.EditorCssFile { Value = "~/cms/getstyles.ashx?qs1=value1&qs2=value2" });

    ASPX/Markup Version (doesn't support dynamic query string values):
    <telerik:RadEditor id="RadEditor1" runat="server">
        <CssFiles>
            <telerik:EditorCssFile Value="~/getstyles.ashx" />
       </CssFiles>
    </telerik:radeditor>

    As with any solution that involves dynamically pulling external resources, make sure you have permission from the site owner to retrieve the CSS files you're utilizing in your editor.

    Hopefully this helps someone out!
  2. Rumen
    Admin
    Rumen avatar
    12851 posts

    Posted 08 May 2012 Link to this post

    Hi,

    Thank you for sharing this very useful solution. I updated your Telerik points for your contribution to our community.

    Best regards,
    Rumen
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
Back to Top