Monday, October 10, 2011

Show an object instance as an xnl on your page

This sample code demonstrates how to show an instance of an object in XML format on a page. It encodes the xml serialized string and dumps it as a code into a placeholder.

    public void ShowXmlObject<T>( T instance)
    {
        var ms = new MemoryStream();
        System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(ms, Encoding.Unicode);
        var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
        serializer.Serialize(writer, instance);
        writer.Flush();
        ms.Position = 0;
        var reader = new StreamReader(ms);
        LogCode(HttpUtility.HtmlEncode(IndentXml(reader.ReadToEnd())));
    }
    public string IndentXml(string xml)
    {
        var p = xml.LastIndexOf("?>");
        if (p > 0)
            xml = xml.Substring(p + 2);
        var doc = new System.Xml.XmlDocument();
        doc.LoadXml(xml);

        var settings = new System.Xml.XmlWriterSettings();
        settings.Indent = true;
        settings.IndentChars = "  ";
        settings.NewLineChars = "\r\n";
        settings.NewLineHandling = System.Xml.NewLineHandling.None;
        var  sbOutput = new StringBuilder();
        var writer = System.Xml.XmlWriter.Create(sbOutput, settings);
        doc.Save(writer);
        writer.Close();
        return sbOutput.ToString();
    } 
    public void LogCode(string message)
    {
        placeResult.Controls.Add(new Literal() { Text = "<pre><code>" + message + "</code></pre>" });
    }

Show Items structure in Sitecore

The following example demonstrates how to get the information about a node on the back side of a node by giving the item.ID. You also could do it easier by having the full path instead of creating an ID.
It is important to do all this inside a SecurityDisabler. You might have some nodes that are not accessible to anonymous user, if the code is running for without proper security.

    protected void StartToAnalyse(object sender, EventArgs e)    {
        Sitecore.Data.Database master =
            Sitecore.Configuration.Factory.GetDatabase("master");
        using (new Sitecore.SecurityModel.SecurityDisabler())
        {
             ProcessItem(master.GetItem(new Sitecore.Data.ID(textboxRoot.Text)));
        }
    }
    private void ShowTechnicalDetails(Sitecore.Data.Items.Item item)
    {
        string pageName = item.DisplayName;
        
        var template = item.Template;
        //LogLine(" Template : " + item.TemplateName);
        // LogLine(" Uri : " + item.Uri.Path);
        // string rend = Sitecore.Context.Item.Fields["Renderings"].Value;
        Sitecore.Data.Items.DeviceItem defDevice = Sitecore.Data.Items.DeviceItem.ResolveDevice(Sitecore.Configuration.Factory.GetDatabase("master"));
        var layout = item.Visualization.GetLayout(defDevice);
        if (layout != null)
        {
            LogLine(" Layout : <u> [" + layout.DisplayName + "]</u>" );
        //   //  LogLine(" File : " + layout.FilePath);
        }
        var renderings = item.Visualization.GetRenderings(defDevice, false);
        //LogLine("Renderings:<ul>");
        foreach(var rend in renderings)
        {
            //LogLine(" Layout : " + rend.RenderingItem.DisplayName);
            LogItem(pageName + ";" + rend.RenderingItem.InnerItem["Path"]);
        }
    }
    private void ProcessItem(Sitecore.Data.Items.Item item)
    {
        if (item == null)
        {
            LogLine("Item not found.");
            return;
        }
        
        ShowTechnicalDetails(item);
        foreach (Sitecore.Data.Items.Item child in item.Children)
        {
            ProcessItem(child);
        }
    }
    

Thursday, October 6, 2011

jQuery.Ajax versus Server-side event handler

This sample demonstrates two ways of getting address from the server: using server-side event handler versus calling jQuery.Ajax

The following is the markup that provides two fields with javascript call on the change event. It also provides a button that is wired to a server side methode:

     <div>

         <h3> Address Test</h3>

         tabbing from the textboxes will verify if calling the webservice is required.

         <table  width="100%"><tr><td><table><tr>

                             <td> Huisnummer *</td>

                             <td><div class="FieldContainer">

                                     <asp:TextBox  runat="server"  ID="textboxHousenumber"  ClientIDMode="Static"

                                         CssClass="TextField TextField02" onchange="VerifyAddress();"

                                         ValidationGroup="KlantAddress" />

                                 </div>

                             </td></tr><tr>

                             <td> Postcode *</td>

                             <td><div  class="FieldContainer">

                                     <asp:TextBox  runat="server"  ID="textboxPostcode"      ClientIDMode="Static"

                                                 CssClass="TextField TextField02"  

                                                 MaxLength="7"  onchange="VerifyAddress();"

                                                 ValidationGroup="KlantAddress" 

                                                 />

                                 </div>

                             </td></tr>

                     </table>

                   Server side call:<br  />

                     <asp:Button  ID="Button1"  runat="server"  OnClick="ShowAddress"  Text="Get Adres"  ToolTip="CustomerDataController"  />

                     <asp:Label  runat="server"  ID="lblAddress"  />

                   

 

Assume we have a we DBLLayer that provides an address or throws an exception.
The event handler would be something like this:

 

     /// <summary>Server side event handler</summary>

     public  void  ShowAddress(object  sender, EventArgs  e)

     {

         try

         {

             var  adres = DBLayer.GetAddress(textboxPostcode.Text, textboxHousenumber.Text);

             ShowAdres(adres);

         }

         catch  (Exception  ex)

         {

             LogError("Error :- "  + ex.Message);

         }

     }

 

And the Javascript will look like this:

 

     function  VerifyAddress() {

         // This method is calling the ShowAddress only if both parameters are filled in.  

         $("#<%=lblAddress.ClientID %>" ).text("" );

         var  postcode = $("#<%=textboxPostcode.ClientID %>" ).val();

         var  huisnummer = $("#<%=textboxHousenumber.ClientID %>" ).val();

         if  (postcode && huisnummer && parseInt(huisnummer) > 0) {

             $("#<%=lblAddress.ClientID %>" ).text("calling the server" );

             var  data = "{ postcode:'"  + postcode + <span' , huisnummer: "  + huisnummer + " }" ;

             jQuery.ajax({

                 type: <span' ,

                 contentType: <span'application/json;' ,

                 data: data,

                 dataType: <span' ,

                 url: <span' ,

                 success: OnGetAddressComplete,

                 error: OnErrorReceived

             });

         }

     }

     function  OnErrorReceived(xhr, ajaxOptions, thrownError) {

         var  message = jQuery.parseJSON(xhr.responseText);

         $("#<%=lblAddress.ClientID %>" ).text(

             "ERROR ("  + xhr.status + ") - "  + message.Message);

     }

     function  OnGetAddressComplete(result) {

         // display the result

         var  adres = result.d;

         $("#<%=lblAddress.ClientID %>" ).text(

             adres.Straat + <span''  +

             adres.Huisnummer + <span','  +

             adres.Postcode + <span''  + adres.Plaats);

     }

And finally the webservice will be like:

 

     [System.Web.Services.WebMethod ()]

     public  static  Adres GetAddress(string  postcode, string  huisnummer)

     {

         if  (!IsPostcode(postcode))

             throw  new  Exception ("Invalid Postcode." );

         int  hNr = 0;

         if  (!Int32 .TryParse(huisnummer, out  hNr))

             throw  new  Exception ("Invalid house number." );

         var  result = DBLayer .GetAddress(postcode, huisnummer);

         if  (result == null )

             throw  new  Exception (" Unknown address." );

         return  result;

     }

    

     public static bool IsPostcode(string  zipcode)

     {

         var  ZipcodeRegex = @"^[1-9][0-9]{3}[a-zA-Z]{2}[\\s]*$" ;

         Regex  r = new  Regex (ZipcodeRegex, RegexOptions .IgnoreCase);

         Match  m = r.Match(zipcode);

         return  m.Success;

     }

    

Monday, August 1, 2011

Convert XElements to Json

You need to capture the data type in a class that is serializable.
In this example I use Employee to do so. The first action will be to construct an IEnumerable of Employee:

 XElement empXml = GetEmployees();
 var empJson = from emp in empXml.Descendants("Employee")
               select new Employee
               {
                      ID = emp.Element("ID").Value,
                      FirstName = emp.Element("FirstName").Value,
                      Department = emp.Element("Department").Value,
                      City = emp.Element("City").Value
               };

The second step is to serialize the enumeration into the memory stream.
  var ser = new  DataContractJsonSerializer(typeof(IEnumerable));
  var ms = new MemoryStream();
  ser.WriteObject(ms, empJson);
And at last, we can take the generated stream as a string just before closing the stream.

string json = Encoding.Default.GetString(ms.ToArray());
ms.Close();