Think the issue is with the ValidationHelper, it's not part of System.Net, its part of CMS.Helpers. I used that webpart and customized it for v8, see the code here:
using CMS.Helpers;
using CMS.PortalControls;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Script.Serialization;
#region Custom Twitter objects
public class Tweet
{
public string created_at { get; set; }
public string id { get; set; }
public string id_str { get; set; }
public string text { get; set; }
}
#endregion
public partial class CMSWebParts_KehrenDev_OAuthTwitterFeed : CMSAbstractWebPart
{
#region Constants
const string OAuthVersion = "1.0";
const string OAuthSignatureMethod = "HMAC-SHA1";
#endregion
#region Public Properties
/// <summary>
/// OAuth Token
/// </summary>
public string OAuthAccessToken
{
get
{
return ValidationHelper.GetString(this.GetValue("OAuthAccessToken"), "");
}
set
{
this.SetValue("OAuthAccessToken", value);
}
}
/// <summary>
/// OAuth Token Secret
/// </summary>
public string OAuthAccessTokenSecret
{
get
{
return ValidationHelper.GetString(this.GetValue("OAuthAccessTokenSecret"), "");
}
set
{
this.SetValue("OAuthAccessTokenSecret", value);
}
}
/// <summary>
/// OAuth Consumer Key
/// </summary>
public string OAuthConsumerKey
{
get
{
return ValidationHelper.GetString(this.GetValue("OAuthConsumerKey"), "");
}
set
{
this.SetValue("OAuthConsumerKey", value);
}
}
/// <summary>
/// OAuth Consumer Secret
/// </summary>
public string OAuthConsumerSecret
{
get
{
return ValidationHelper.GetString(this.GetValue("OAuthConsumerSecret"), "");
}
set
{
this.SetValue("OAuthConsumerSecret", value);
}
}
/// <summary>
/// Transformation Name
/// </summary>
public string TransformationName
{
get
{
return ValidationHelper.GetString(this.GetValue("TransformationName"), "");
}
set
{
this.SetValue("TransformationName", value);
}
}
/// <summary>
/// Twitter screen name
/// </summary>
public string TwitterScreenName
{
get
{
return ValidationHelper.GetString(this.GetValue("TwitterScreenName"), "");
}
set
{
this.SetValue("TwitterScreenName", value);
}
}
/// <summary>
/// Number of tweets to display
/// </summary>
public string TweetsCount
{
get
{
return ValidationHelper.GetString(this.GetValue("TweetsCount"), "");
}
set
{
this.SetValue("TweetsCount", value);
}
}
/// <summary>
/// Title text of Twitter feed
/// </summary>
public string TitleText
{
get
{
return ValidationHelper.GetString(this.GetValue("TitleText"), "");
}
set
{
this.SetValue("TitleText", value);
}
}
/// <summary>
/// Date format
/// </summary>
public string DateFormat
{
get
{
return ValidationHelper.GetString(this.GetValue("DateFormat"), "");
}
set
{
this.SetValue("DateFormat", value);
}
}
/// <summary>
/// Display the "Follow me..." link?
/// </summary>
public string DisplayFollowMeLink
{
get
{
return ValidationHelper.GetString(this.GetValue("DisplayFollowMeLink"), "");
}
set
{
this.SetValue("DisplayFollowMeLink", value);
}
}
/// <summary>
/// Text for the "Follow me..." link
/// </summary>
public string FollowMeLinkText
{
get
{
return ValidationHelper.GetString(this.GetValue("FollowMeLinkText"), "");
}
set
{
this.SetValue("FollowMeLinkText", value);
}
}
/// <summary>
/// Custom error message when Twitter becomes inaccessible
/// </summary>
public string CustomErrorMessage
{
get
{
return ValidationHelper.GetString(this.GetValue("CustomErrorMessage"), "");
}
set
{
this.SetValue("CustomErrorMessage", value);
}
}
#endregion
/// <summary>
/// Content loaded event handler
/// </summary>
public override void OnContentLoaded()
{
base.OnContentLoaded();
SetupControl();
}
/// <summary>
/// Initializes the control properties
/// </summary>
protected void SetupControl()
{
if (this.StopProcessing)
{
// Do not process
}
else
{
// Retrieve all user tweets and populate the repeater
List<Tweet> UserTweets = GetUserTweets();
rptTweets.TransformationName = TransformationName;
rptTweets.DataSource = UserTweets;
rptTweets.DataBind();
string str = CurrentDocument.NodeAliasPath;
// Check if user has specified a title, if so display it
if(!String.IsNullOrEmpty(TitleText))
{
pnlTwitterHeader.Visible = true;
ltlTitleText.Text = TitleText;
}
// Check if user wants to show the "Follow me..." link; if so, set it up
if (Convert.ToBoolean(DisplayFollowMeLink) == true)
{
lnkFollowMe.Visible = true;
if (!String.IsNullOrEmpty(FollowMeLinkText))
{
lnkFollowMe.Text = FollowMeLinkText;
}
}
}
}
/// <summary>
/// Reloads the control data
/// </summary>
public override void ReloadData()
{
base.ReloadData();
SetupControl();
}
/// <summary>
/// Retrieves a list of specified user's tweets
/// </summary>
public List<Tweet> GetUserTweets()
{
string OAuthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
TimeSpan timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
string OAuthTimestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();
string ResourceUrl = "https://api.twitter.com/1.1/statuses/user_timeline.json";
// Generate an encrypted oAuth signature which Twitter will use to validate the request.
// The formatting of this string is very specific, even the order of the variables matters. Modify with caution.
var baseFormat = "count={7}&oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}";
var baseString = string.Format(baseFormat,
OAuthConsumerKey,
OAuthNonce,
OAuthSignatureMethod,
OAuthTimestamp,
OAuthAccessToken,
OAuthVersion,
Uri.EscapeDataString(TwitterScreenName),
Uri.EscapeDataString(TweetsCount)
);
baseString = string.Concat("GET&", Uri.EscapeDataString(ResourceUrl), "&", Uri.EscapeDataString(baseString));
// Use the base string to generate the OAuth signature
var compositeKey = string.Concat(Uri.EscapeDataString(OAuthConsumerSecret), "&", Uri.EscapeDataString(OAuthAccessTokenSecret));
string OAuthSignature;
using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
{
OAuthSignature = Convert.ToBase64String(hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
}
// Now build the OAuth Authentication header. Again, the header format is very specific, even minor changes like re-ordering varilables
// will result in 401 Unauthorized errors.
var HeaderFormat = "OAuth " +
"oauth_consumer_key=\"{0}\", " +
"oauth_nonce=\"{1}\", " +
"oauth_signature=\"{2}\", " +
"oauth_signature_method=\"{3}\", " +
"oauth_timestamp=\"{4}\", " +
"oauth_token=\"{5}\", " +
"oauth_version=\"{6}\"";
var authHeader = string.Format(HeaderFormat,
Uri.EscapeDataString(OAuthConsumerKey),
Uri.EscapeDataString(OAuthNonce),
Uri.EscapeDataString(OAuthSignature),
Uri.EscapeDataString(OAuthSignatureMethod),
Uri.EscapeDataString(OAuthTimestamp),
Uri.EscapeDataString(OAuthAccessToken),
Uri.EscapeDataString(OAuthVersion)
);
// Finally, create the Twitter API request
var postBody = string.Format("screen_name={0}&count={1}", Uri.EscapeDataString(TwitterScreenName), Uri.EscapeDataString(TweetsCount));
ResourceUrl += "?" + postBody;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ResourceUrl);
request.Headers.Add("Authorization", authHeader);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
// Note, we must also disable the Expect: 100-Continue header using the ServicePointManager. Without this code, .NET sends the header by default, which is not supported by Twitter.
ServicePointManager.Expect100Continue = false;
// Send the request, and deserialize the response. Use a try/catch to gracefully handle Twitter errors.
List<Tweet> UserTweets = new List<Tweet>();
try
{
WebResponse response = request.GetResponse();
string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();
UserTweets = new JavaScriptSerializer().Deserialize<List<Tweet>>(responseData);
// Iterate through the list of tweets and parse their text
for (int tweet = 0; tweet < UserTweets.Count; tweet++)
{
UserTweets[tweet].text = ParseTweet(UserTweets[tweet].text);
DateTime TweetDate = ParseDateTime(UserTweets[tweet].created_at.ToString());
TweetDate = TweetDate.ToLocalTime();
UserTweets[tweet].created_at = TweetDate.ToString(DateFormat);
}
}
catch (Exception ex)
{
// If the Twitter feed fails, display an error message.
if (!String.IsNullOrEmpty(CustomErrorMessage))
{
ltlErrorMessage.Text = CustomErrorMessage;
}
else
{
if (ex.Message.Contains("(401) Unauthorized"))
{
ltlErrorMessage.Text = "Twitter returned a <strong>(401) Unauthorized</strong> error. Please verify your OAuth credentials and try again.";
}
else
{
ltlErrorMessage.Text = "Twitter feed failed with the following error: <strong>" + ex.Message + "</strong>";
}
}
pnlErrorMessage.Visible = true;
}
// All done!
return UserTweets;
}
/// <summary>
/// Parse a tweet by hyperlinking mentions, hashtags
/// Code stolen from: http://csharpmentor.blogspot.ca/2011/12/parsing-twit-with-regex-in-c.html
/// </summary>
/// <param name="_originalText"></param>
/// <returns></returns>
private string ParseTweet(string rawTweet)
{
Regex link = new Regex(@"http(s)?://([\w+?\.\w+])+([a-zA-Z0-9\~\!\@\#\$\%\^\&\*\(\)_\-\=\+\\\/\?\.\:\;\'\,]*)?");
Regex screenName = new Regex(@"@\w+");
Regex hashTag = new Regex(@"#\w+");
string formattedTweet = link.Replace(rawTweet, delegate(Match m)
{
string val = m.Value;
return "<a target='blank' href='" + val + "'>" + val + "</a>";
});
formattedTweet = screenName.Replace(formattedTweet, delegate(Match m)
{
string val = m.Value.Trim('@');
return string.Format("@<a target='blank' href='http://twitter.com/{0}'>{1}</a>", val, val);
});
formattedTweet = hashTag.Replace(formattedTweet, delegate(Match m)
{
string val = m.Value;
return string.Format("<a target='blank' href='http://twitter.com/#search?q=%23{0}'>{1}</a>", val, val);
});
return formattedTweet;
}
/// <summary>
/// This function just parses the date which in the XML to a DateTime. It facilitate the work with DateTime later.
/// Code stolen from the r42 Twitter Feed webpart: http://devnet.kentico.com/Marketplace/Community/Twitter-Feed.aspx
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public DateTime ParseDateTime(string date)
{
string dayOfWeek = date.Substring(0, 3).Trim();
string month = date.Substring(4, 3).Trim();
string dayInMonth = date.Substring(8, 2).Trim();
string time = date.Substring(11, 9).Trim();
string offset = date.Substring(20, 5).Trim();
string year = date.Substring(25, 5).Trim();
string dateTime = string.Format("{0}-{1}-{2} {3}", dayInMonth, month, year, time);
DateTime ret = DateTime.Parse(dateTime);
return ret;
}
}