Sitecore, Web

Sluggish Sitecore Development Environment? Here’s An Easy Method To Disable Sitecore Analytics

When you install a new 8.0 instance of Sitecore you will find the site can be laggy and sluggish to load. To speed up your dev environment I would recommend this easy fix.

First create a folder called z in your app config sitecore path: C:\inetpub\wwwroot\yoursitecore\Website\App_Config\z

Then, create a file called zwoa.config and paste the following in:

<configuration xmlns:patch="<a href="http://www.sitecore.net/xmlconfig/">http://www.sitecore.net/xmlconfig/</a>">
 <sitecore>
 <pipelines>
 <initialize>
 <processor type="Sitecore.Pipelines.Initialize.PrecompileSpeakViews, Sitecore.Speak.Clientpro" >
 <patch:delete />
 </processor>
 <processor type="Sitecore.ContentTesting.Pipelines.Initialize.RegisterContentTestingCommandRoute, Sitecore.ContentTesting" >
 <patch:delete />
 </processor>
 <processor type="Sitecore.Pipelines.Initialize.PrecompileSpeakViews, Sitecore.Speak.Client" use="ContentTesting" >
 <patch:delete />
 </processor>
 </initialize>
 <mvc.renderPageExtenders>
 <processor patch:after="processor[@type='Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderExtendersContainer, Sitecore.Mvc.ExperienceEditor']" type="Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderPageEditorExtender, Sitecore.Mvc.ExperienceEditor"></processor>
 <processor patch:after="processor[@type='Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderExtendersContainer, Sitecore.Mvc.ExperienceEditor']" type="Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderPreviewExtender, Sitecore.Mvc.ExperienceEditor"></processor>
 <processor patch:after="processor[@type='Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderExtendersContainer, Sitecore.Mvc.ExperienceEditor']" type="Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderDebugExtender, Sitecore.Mvc.ExperienceEditor"></processor>
 <processor type=""Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.SpeakRibbon.RenderPageEditorSpeakExtender, Sitecore.Mvc.ExperienceEditor" >
 <patch:delete />
 </processor>
 </mvc.renderPageExtenders>
 </pipelines>
 <settings>
 <setting name="Analytics.Enabled" > <patch:attribute name="value" value="false" />
 </setting>
 </settings>
 </sitecore>
 </configuration>

Refresh your Sitecore in a web browser and watch it go!

API, C#, Programming, SMS, Web Service

C# Send A SMS Text Message Programmatically Using Clickatell HTTP API

I would start off by heading here to better understand the Clickatell HTTP API: https://www.clickatell.com/apis-scripts/apis/http-s/. If you are interested they allow you 10 free text messages to try it out before you buy a package. Just sign up for an account and create your HTTP API and use your information to populate the snippet below.

For a particular project I am using this API to send out texts for verification purposes. I am using my method inside of a web service to send the information about a user as well as their pre-generated pin. Of course it is a lot different in my project but I am providing the bare bones below.

If you are a skimmer and you skipped reading anything I said above then here you go:

Code for MyWebRequest class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.IO;
using System.Text;
using System.Configuration;

namespace CustomWebServices
{
public class MyWebRequest
{
private WebRequest request;
private Stream dataStream;

private string status;

public String Status
{
get
{
return status;
}
set
{
status = value;
}
}

public MyWebRequest(string url)
{
// Create a request using a URL that can receive a post.

request = WebRequest.Create(url);
}

public MyWebRequest(string url, string method)
: this(url)
{

if (method.Equals("GET") || method.Equals("POST"))
{
// Set the Method property of the request to POST.
request.Method = method;
}
else
{
throw new Exception("Invalid Method Type");
}
}

public MyWebRequest(string url, string method, string data)
: this(url, method)
{

// Create POST data and convert it to a byte array.
string postData = data;
byte[] byteArray = Encoding.UTF8.GetBytes(postData);

// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";

// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;

// Get the request stream.
dataStream = request.GetRequestStream();

// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);

// Close the Stream object.
dataStream.Close();

}

public string GetResponse()
{
// Get the original response.
WebResponse response = request.GetResponse();

this.Status = ((HttpWebResponse)response).StatusDescription;

// Get the stream containing all content returned by the requested server.
dataStream = response.GetResponseStream();

// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);

// Read the content fully up to the end.
string responseFromServer = reader.ReadToEnd();

// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();

return responseFromServer;
}
}
}

And now the code for the method itself:

public string SendText(string mobile, string pin)
{
// Make sure to add the country code to ensure the text goes through
string phoneCheck = "";
if (mobile.Length == 10)
{
phoneCheck = "1" + mobile;
}
// Clickatell settings
string textmessage = "Your verification pin is " + pin;
string parameters = "";
parameters = "user=yourclickatellusername";
parameters = parameters + "&amp;password=yourclickatellpassword";
parameters = parameters + "&amp;api_id=youruniqueclickatellhttpapiid";
parameters = parameters + "&amp;to=" + phoneCheck;
parameters = parameters + "&amp;text=" + textmessage;
parameters = parameters + "&amp;mo=1";
parameters = parameters + "&amp;from=15558675309";
MyWebRequest myRequest = new MyWebRequest("<a href="http://api.clickatell.com/http/sendmsg">http://api.clickatell.com/http/sendmsg</a>", "POST", parameters);
myRequest.GetResponse();
} // SendText

* Note: If you put this call on a server that will require a proxy then add it to your MyWebRequest class

C#, SharePoint, Web Service

Add An Item To A Custom SharePoint List Using Batch XML With A Web Service (C#)

If you have multiple active directory environments and SharePoint instances in both of those environments then you will understand why I posted this.

I received a requirement that while users from a separate domain and SharePoint instance would need to fill out a form on their SharePoint and have the form submission be sent to the other SharePoint instance (on the other domain). This was because they did not want to mix and mingle with forest trusting or having users to have two separate AD accounts to manage the information. Say what?!

After some initial discovery I had reached a couple quick conclusions:

– SharePoints on different domains do not talk well to each other without trust

– Using the built-in lists service on SharePoint has to be done on the server itself unless you are going to have an instance stood up somewhere on the same domain that has all the required SharePoint dlls to be referenced

All being said, here is an example of what I used as a web service I placed on the SharePoint server that calls the lists web service doing a list add using batch XML:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Administration.Claims;
using Microsoft.SharePoint.WebControls;

namespace CopyOverItemFromOtherSP
{

{
public string CopyOverFromOtherDomain(string userName, string Name, string userEmail,
string userPhone, string listColumn1, string listColumn2, string listColumn3,
string Comments)
{
Boolean done = false;

/* Declare and initialize a variable for the Lists Web service. */
sitesWebServiceLists.Lists listService = new sitesWebServiceLists.Lists();

/* Authenticate the current user by passing their default credentials to the Web service from the system credential cache. */
listService.Credentials = System.Net.CredentialCache.DefaultCredentials;

/* Set the Url property of the service for the path to a subsite. */
// Service URLs - MUST CHANGE TO POINT TO SPECIFIC SERVICE ENVIRONMENT
// Change the web reference URL on the sitesWebServiceLists web service reference to be the address
// that you are wanting to used based on the environment that you want to write to
listService.Url = "<a href="#">http://sharepointtocopyitemto/_vti_bin/Lists.asmx</a>";

/* Get Name attribute values (GUIDs) for list and view. */
System.Xml.XmlNode ndListView = listService.GetListAndView("NameOfSharePointList", "");
string strListID = ndListView.ChildNodes[0].Attributes["Name"].Value;
string strViewID = ndListView.ChildNodes[1].Attributes["Name"].Value;

/* Create an XmlDocument object and construct a Batch element and its
attributes. Note that an empty ViewName parameter causes the method to use the default view. */
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
System.Xml.XmlElement batchElement = doc.CreateElement("Batch");
batchElement.SetAttribute("OnError", "Continue");
batchElement.SetAttribute("ListVersion", "1");
batchElement.SetAttribute("ViewName", strViewID);

/* Specify methods for the batch post using CAML. To update or delete,
specify the ID of the item, and to update or add, specify
the value to place in the specified column. */
batchElement.InnerXml = "<Method ID='1' Cmd='New'>" +
"<Field Name='ID'>New</Field>" +
"<Field Name='Title'>" + userName.ToString() + "</Field>" +
"<Field Name='Name'>" + Name.ToString() + "</Field>" +
"<Field Name='userEmail'>" + userEmail.ToString() + "</Field>" +
"<Field Name='userPhone'>" + userPhone.ToString() + "</Field>" +
"<Field Name='listColumn1'>" + listColumn1.ToString() + "</Field>" +
"<Field Name='listColumn2'>" + listColumn2.ToString() + "</Field>" +
"<Field Name='listColumn3'>" + listColumn3.ToString() + "</Field>" +
"<Field Name='Comments'>" + Comments.ToString() + "</Field>" +
"</Method>";

/* Update list items. This example uses the list GUID, which is recommended,
but the list display name will also work. */
try
{
listService.UpdateListItems(strListID, batchElement);
done = true;
}
catch
{

}
if (done == true)
{
return done.ToString();
}
else
{
return done.ToString();
}
}
}
}
Active Directory, C#, Certificates, Programming

Programmatically Install A Root CA Certificate So Users Don’t Have To (C#)

So here’s the backstory: I received the task of improving certificate enrollment so that users can

1) Be verified via username, password, captcha & verification pin

2) Auto Enroll without an external approval

3) Simplify the process

As some of you already know, ADCS via web enrollment is…how can we say…dated. So I wrote an application that sits in front of ADCS to first verify the user. Once they are through then the web enrollment is configured to let them run the wizard through to installing their cert. The issue that came to me is that most end-users will not take the time to ensure the root CA makes it to the trusted store (thus giving the classic CA cert is not installed message). So I received the order from on-high to “do it for them”. At first I struggled, attempting to understand how this could be done. I spoke with Microsoft and as I already was aware they indicated that having the user choose the trusted root store for the CA is by design. So what to do…ah I know, let’s just script it out.

So this is as simple as it gets. Download the cert, store it on the local drive and use the built-in certmgr.exe to perform the root CA to trusted store installation. Here it is (this code is just one a basic console app):

Code:

using System.Security.Cryptography.X509Certificates;

WebClient webClient = new WebClient();
webClient.DownloadFile("https://yourserver.domain.com/CertSrv/certnew.cer?ReqID=CACert&amp;Renewal=0&amp;Mode=inst&amp;Enc=b64", @"C:\Temp\certnew.cer");

X509Store store = new X509Store(StoreName.Root,
StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
X509Certificate2Collection collection = new X509Certificate2Collection();
X509Certificate2 cert = new X509Certificate2(@"C:\Temp\certnew.cer");
byte[] encodedCert = cert.GetRawCertData();
Console.WriteLine("We are now installing the CA certificate into the Trusted Root Certificate store ...");
store.Add(cert);
Console.WriteLine("Done! The CA certificate was successfully. Press any key to close.");
Console.ReadKey();
store.Close();

This finishes the root CA portion so they can fly through the rest of web enrollment. Hope this helps.

C#, Oracle, Programming, SQL

Execute An Oracle Stored Procedure With Parameters (C#)

So you want to execute an Oracle stored procedure with parameters, huh? For this example I have an Oracle stored procedure called MEMBER_TYPE_UPDATE that will update what type of membership I have based on the numeric value. This sort of snippet can be used in a web application directly or called by some form of web service.

Here are some example values:

0 = Not a member

1 = Member

2 = Member with first tier privileges

3 = Member with highest level privileges

The update occurs based on their username and based on that username will attempt to update the numeric value. So below we will be calling a method (passing the two parameters to update with). I will then gather the connection string to Oracle and begin to execute my Oracle stored procedure (while giving it the values passed into the method to be used in the stored procedure).

Here’s my snippet:

using System;
using System.Data;
using System.Web.Services;
using Oracle.DataAccess.Client;
using System.Configuration;

public string SetUserMembership(string membershipNetworkUserName, int membershipStatusValue)
{
string errorString = string.Empty;
OracleCommand cmd = null;
try
{

string connectionString = string.Empty;
if (ConfigurationManager.AppSettings["location"].Contains("PROD"))
{
connectionString = ConfigurationManager.ConnectionStrings["ConnectionStringPROD"].ConnectionString;
}
else
{
connectionString = ConfigurationManager.ConnectionStrings["ConnectionStringDEV"].ConnectionString;
}

cmd = new OracleCommand();
cmd.Connection = new OracleConnection(connectionString);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "ORACLE_USER.MEMBER_TYPE_UPDATE";
cmd.Parameters.Add("in_employeeUserName", OracleDbType.Varchar2).Value = membershipNetworkUserName;
cmd.Parameters.Add("in_status_id", OracleDbType.Decimal).Value = membershipStatusValue;
cmd.Parameters.Add("O_RETURN_STATUS", OracleDbType.Varchar2, 4000).Direction = ParameterDirection.Output;
cmd.Connection.Open();
cmd.ExecuteNonQuery();

string returnString = cmd.Parameters["O_RETURN_STATUS"].Value.ToString();
if (!returnString.Contains("SUCCESS"))
{
// obviously there was an issue and we want to display this somewhere
errorString = returnString;
}
}

For a specific call I would call it with SetUserMembership(“username”, “2”);

Ideally you would have variables there. Hope this helps people to see the parameters in use.