/src/Amptools/Public/labels/REST.aspx
ASP.NET | 500 lines | 374 code | 126 blank | 0 comment | 23 complexity | d3f73ea903c9209452923563c0aca304 MD5 | raw file
1<%@ Page Title="amptools.net" Language="C#" MasterPageFile="~/App/Views/Layouts/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="System.Web.Mvc.ViewPage" %> 2<asp:Content ID="Content2" ContentPlaceHolderID="Head" runat="server"> 3 <link href='/Content/default/css/syntax-highlighter.css' rel="stylesheet" type="text/css" /> 4 <link rel="alternate" type="application/rss+xml" title="amptools.net - RSS" href="http://feeds.feedburner.com/amptoolsnet" /> 5 <link rel="service.post" type="application/atom+xml" title="amptools.net - Atom" href="http://www.blogger.com/feeds/7043853799247804655/posts/default" /> 6 <link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://www.blogger.com/rsd.g?blogID=7043853799247804655" /> 7 <style type="text/css"> 8 @import url("http://www.blogger.com/css/blog_controls.css"); 9 @import url("http://www.blogger.com/dyn-css/authorization.css?targetBlogID=7043853799247804655"); 10 </style> 11 12 <script type="text/javascript" src="http://www.blogger.com/js/backlink.js"></script> 13 <script type="text/javascript" src="http://www.blogger.com/js/backlink_control.js"></script> 14 <script type="text/javascript">var BL_backlinkURL = "http://www.blogger.com/dyn-js/backlink_count.js";var BL_blogId = "7043853799247804655";</script> 15</asp:Content> 16 17<asp:Content ID="Content3" ContentPlaceHolderID="Javascript" runat="server"> 18 <script type="text/javascript" src="~/javascripts/prototype.js"></script> 19 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shCore.js"></script> 20 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushCSharp.js"></script> 21 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushRuby.js"></script> 22 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushJScript.js"></script> 23 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushCss.js"></script> 24 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushSql.js"></script> 25 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushXml.js"></script> 26 <script type="text/javascript"> 27 //<[CDATA[ 28 dp.SyntaxHighlighter.HighlightAll('code'); 29 //]]> 30 </script> 31</asp:Content> 32<asp:Content ID="Content1" ContentPlaceHolderID="main" runat="server"> 33 34 35 <div class="left"> 36 <h2 class="silver"> 37 "Working on the complexity that is always indirectly implied by simpilicity." 38 </h2> 39 40 41 42 <h2 class="blog-title"><a name="458120713693871790"></a> 43 44 Amplify's WCF Twitter API Client Library v0.2 45 46 <span class="blog-byline"> 47 by: michael herndon, at: 7/28/2008 12:33:00 AM 48 </span> 49 50 </h2> 51 <div class="blog-content"> 52 <p>After some playing around with WCF and Flickr, I decided to move everything internally for the twitter library to use WCF with it's <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.aspx">ServiceContract</a>.  It was more of a pain that initially thought it would be. WCF is amazingly customizable but still has a couple of downfalls thanks to REST and people not writing their API for all technologies.  </p> <p>The biggest issue is that Twitter throws an Http 403 unknown exception when you call a page and something is incorrect in the url.  Well with WCF, it throws a <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.security.messagesecurityexception.aspx">System.ServiceModel.Security.MessageSecurityException</a>, due to the url returning a status code other than 200, and it wraps the inner exceptions inside of that. </p> <p>I'm sure there is a better way to get around this, but each proxy call is now wrapped by a try/catch in the client class methods in order to check for the <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.security.messagesecurityexception.aspx">MessageSecurityException</a>, then it checks the inner exception and determines if twitter sent back a response error message. If it does the library now throws a twitter exception with error information, otherwise you would only see the WCF exception that would mask the real issue.  </p> <p>Also I renamed the "Service" classes to "Client" seeing that is the proper term for them.  The tests are now updated as well to reflect the changes.  The tests are a good way of seeing of how to use the library. Last but not least, methods now return arrays instead of lists in order to be more REST friendly. </p> <p></p> <pre class="code csharp">using Amplify.Twitter; 53using System.Security; 54 55// ... stuff 56 57public void Test() 58{ 59 try { 60 string temp = "password"; 61 62 Twitter.SetCredentials("Username", temp); 63 64 StatusClient client = Twitter.CreateStatusClient(); 65 // or StatusClient client = new StatusClient("Username", temp); 66 67 Status[] tweets = service.GetUserTimeline(); 68 } catch (TwitterException ex) { 69 Log.Write(ex.ToString()); // write the twitter rest error. 70 } 71 72}</pre> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Amplify.aspx">Amplify</a>, <a rel='tag' href="http://www.amptools.net/labels/BHAG.aspx">BHAG</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/Code.aspx">Code</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/JSON.aspx">JSON</a>, <a rel='tag' href="http://www.amptools.net/labels/REST.aspx">REST</a>, <a rel='tag' href="http://www.amptools.net/labels/Twitter.aspx">Twitter</a>, <a rel='tag' href="http://www.amptools.net/labels/WCF.aspx">WCF</a></p> 73 </div> 74 <div class="blog-footer"> 75 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=458120713693871790"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=458120713693871790;><span style="text-transform:lowercase">2 Comments</span></a> 76 77 <a class="comment-link" href="http://www.amptools.net/2008/07/amplify-wcf-twitter-api-client-library.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 78 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=458120713693871790" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 79 80 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 81 </div> 82 83 84 85 <h2 class="blog-title"><a name="8164722880411458481"></a> 86 87 Using WCF to access the Flickr JSON API 88 89 <span class="blog-byline"> 90 by: michael herndon, at: 7/17/2008 06:40:00 AM 91 </span> 92 93 </h2> 94 <div class="blog-content"> 95 <p>Even though there are quite a few opensource .Net libraries REST API out there, and a really impressive one for Flickr, they tend to never evolve or fork to use the newer framework technologies.  I think its great that they support 1.0, 2.0, and mono, but why not fork and support WCF?  I think part of the problem that .Net 3.5 use is not wide spread as it should be is not only information overload and bad naming for extension libraries, but also lack of opensource support to provide libraries and basis for current technology.  </p> <p>Flickr tends to be a little more tricky to use when calling it than some other REST APIs. WCF is a cool technology, but needs to be massaged when using it with Flickr due to a couple of gotchas and not so obvious things about WCF. In order to use Flickr, you need to register for an api_key and a shared secret code which is used to create an MD5 hash. You also need to create that MD5 each time you call a method, using the url parameters in a certain way. </p> <p>There are also a few not so obvious factors about using the JSON part of Flickr. All of the .Net libraries I've seen so far, use XML. While C# is king of parsing  XML, JSON tends to be more compact, which means less expense over the wire, though it might mean more time parsing once on the developers end point. So there are tradeoffs to using it. </p> <p>When I created the classes needed to use WCF to call Flickr, I have the actual "DataContract" object (DTO, Data Transfer Object), A Hash (Dictionary<string, object>) for adding the parameters to create the MD5 signature, A base class for creating the WCF proxy, a custom "WebContentTypeMapper", The "ServiceContract" interface, the actual "Client class", and a mixins class for creating the MD5. </p> <p>Here are some of the gotchas that I ran into while getting WCF to work with Flickr. </p> <p></p> <ol> <li>Flickr makes you create a md5 hash to send with every call for ALL parameters in alphabetical order using your "Shared Secret" Code as part of the md5.   </li> <li>Flickr's Json response "Content-Type" header is sent not as "application/json" but as "text/plain" which equates to "Raw" in WCF lingo.  </li> <li>The response object is wrapped and not obvious when it comes to json how the DataContract object should be formed.  </li> <li>Flickr will wrap the json response in a javascript function unless you pass in the parameter "nojsoncallback=1" </li> </ol> <p>To get around number one, I created an extension method that takes a Hash (Dictionary<string, object>) and adds method that converts the parameters into a MD5 string. </p> <pre class="code csharp">namespace Amplify.Linq 96{ 97 using System; 98 using System.Collections.Generic; 99 using System.Linq; 100 using System.Text; 101 102#if STANDALONE 103 public class Hash : Dictionary<string, object> 104 { 105 106 107 108 109 } 110#endif 111} 112// different file 113 114namespace Amplify.Linq 115{ 116 using System; 117 using System.Collections.Generic; 118 using System.Linq; 119 using System.Security.Cryptography; 120 using System.Text; 121 122 using Amplify.Linq; 123 124 public static class Mixins 125 { 126 127 128 129 public static string ToMD5(this Hash obj, string secret) 130 { 131 var query = from item in obj 132 orderby item.Key ascending 133 select item.Key + item.Value.ToString(); 134 135 StringBuilder builder = new StringBuilder(secret, 2048); 136 137 foreach (string item in query) 138 builder.Append(item); 139 140 MD5CryptoServiceProvider crypto = new MD5CryptoServiceProvider(); 141 byte[] bytes = Encoding.UTF8.GetBytes(builder.ToString()); 142 byte[] hashedBytes = crypto.ComputeHash(bytes, 0, bytes.Length); 143 return BitConverter.ToString(hashedBytes).Replace("-", "").ToLower(); 144 } 145 146 } 147}</pre> 148 149<p>Well Gotcha number two, took a bit of research to figure it out. The error I got was that it was looking for Json or XML but could not do anything with "Raw". So the solution is to create a custom binding with a custom WebContentTypeManager. </p> 150 151<pre class="code csharp">namespace Amplify.Flickr 152{ 153 using System.ServiceModel; 154 using System.ServiceModel.Channels; 155 using System.Runtime.Serialization; 156 using System.ServiceModel.Web; 157 158 public class JsonContentMapper : WebContentTypeMapper 159 { 160 public override WebContentFormat GetMessageFormatForContentType(string contentType) 161 { 162 return WebContentFormat.Json; 163 } 164 } 165} 166 167// different file 168 169namespace Amplify.Flickr 170{ 171 using System; 172 using System.Collections.Generic; 173 using System.Linq; 174 using System.Text; 175 using System.ServiceModel; 176 using System.ServiceModel.Channels; 177 using System.ServiceModel.Description; 178 using System.ServiceModel.Web; 179 180 using Amplify.Linq; 181 182 public class FlickrClient<T> 183 { 184 protected string Secret { get; set; } 185 186 protected string Key { get; set; } 187 188 protected string Token { get; set; } 189 190 protected string Url { get; set; } 191 192 protected T Proxy { get; set; } 193 194 195 public FlickrClient(string key, string secret) 196 { 197 this.Key = key; 198 this.Secret = secret; 199 this.Url = "http://api.flickr.com/services/rest"; 200 this.Proxy = this.InitializeProxy(); 201 } 202 203 public FlickrClient(string key, string secret, string token) 204 :this(key, secret) 205 { 206 this.Token = token; 207 } 208 209 protected virtual T InitializeProxy() 210 { 211 // using custom wrapper 212 CustomBinding binding = new CustomBinding(new WebHttpBinding()); 213 WebMessageEncodingBindingElement property = binding.Elements.Find<WebMessageEncodingBindingElement>(); 214 property.ContentTypeMapper = new JsonContentMapper(); 215 216 217 ChannelFactory<T> channel = new ChannelFactory<T>( 218 binding, this.Url); 219 220 channel.Endpoint.Behaviors.Add( new WebHttpBehavior()); 221 return channel.CreateChannel(); 222 } 223 224 } 225}</pre> 226 227<p>The 3rd issue, to know that all objects are wrapped in a "Response" object. To create a DataContract for the getFrob method on flickr, it took looking at the json to see what it was returning. The object below is the basic form of the Json object that is returned, it also includes the properties in case an error object is returned. </p> 228 229<pre class="code csharp"> using System; 230 using System.Collections.Generic; 231 using System.Linq; 232 using System.Text; 233 using System.Runtime.Serialization; 234 235 [DataContract] 236 public class FrobResponse 237 { 238 [DataMember(Name = "frob")] 239 public JsonObject Frob { get; set; } 240 241 [DataContract(Name = "frob")] 242 public class JsonObject 243 { 244 [DataMember(Name = "_content")] 245 public string Content { get; set; } 246 247 } 248 249 [DataMember(Name = "stat")] 250 public string Status { get; set; } 251 252 [DataMember(Name = "code")] 253 public int Code { get; set; } 254 255 [DataMember(Name = "message")] 256 public string Message { get; set; } 257 } 258 259 // different file 260 261 262 using System; 263 using System.Collections.Generic; 264 using System.Linq; 265 using System.Text; 266 using System.ServiceModel; 267 using System.ServiceModel.Web; 268 269 [ServiceContract] 270 public interface IAuthClient 271 { 272 [OperationContract, 273 WebInvoke( 274 UriTemplate = "/?method=flickr.auth.getFrob&format=json&nojsoncallback=1&api_key={key}&api_sig={signature}", 275 ResponseFormat = WebMessageFormat.Json, 276 BodyStyle = WebMessageBodyStyle.Bare)] 277 FrobResponse GetFrob(string signature, string key); 278 279 [OperationContract, 280 WebInvoke( 281 UriTemplate = "/?method=flickr.auth.getToken&format=json&nojsoncallback=1&api_key={key}&frob={frob}&api_sig={signature}", 282 ResponseFormat = WebMessageFormat.Json, 283 BodyStyle = WebMessageBodyStyle.WrappedResponse)] 284 Auth GetToken(string signature, string key, string frob); 285 } 286 287 288 // the actual client class. 289 290 using System; 291 using System.Collections.Generic; 292 using System.Linq; 293 using System.Text; 294 295 using Amplify.Linq; 296 297 298 public class AuthClient : FlickrClient<IAuthClient> 299 { 300 301 public AuthClient(string key, string secret) 302 :base(key, secret) 303 { } 304 305 public AuthClient(string key, string secret, string token) 306 :base(key, secret, token) 307 { } 308 309 public string GetFrob() 310 { 311 string md5 = new Hash() { 312 {"api_key", this.Key}, 313 {"format", "json"}, 314 {"method", "flickr.auth.getFrob"}, 315 {"nojsoncallback", 1} 316 }.ToMD5(this.Secret); 317 318 FrobResponse response = this.Proxy.GetFrob(md5, this.Key); 319 if (response.Code > 0) 320 throw new Exception(response.Message); 321 322 return response.Frob.Content; 323 } 324 }</pre> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Amplify.aspx">Amplify</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/Code.aspx">Code</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/Flickr.aspx">Flickr</a>, <a rel='tag' href="http://www.amptools.net/labels/JSON.aspx">JSON</a>, <a rel='tag' href="http://www.amptools.net/labels/REST.aspx">REST</a>, <a rel='tag' href="http://www.amptools.net/labels/WCF.aspx">WCF</a></p> 325 </div> 326 <div class="blog-footer"> 327 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=8164722880411458481"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=8164722880411458481;><span style="text-transform:lowercase">0 Comments</span></a> 328 329 <a class="comment-link" href="http://www.amptools.net/2008/07/using-wcf-to-access-flickr-json-api.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 330 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=8164722880411458481" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 331 332 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 333 </div> 334 335 336 337 <h2 class="blog-title"><a name="3907268195622759157"></a> 338 339 Amplify's TwitterN, Yet Another C# Twitter REST API Library 340 341 <span class="blog-byline"> 342 by: michael herndon, at: 7/13/2008 03:08:00 PM 343 </span> 344 345 </h2> 346 <div class="blog-content"> 347 <p><a href="http://code.google.com/p/twittern">http://code.google.com/p/twittern</a></p> <p>I put together a C# twitter library that uses WCF's <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx">DataContract</a> & <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.aspx">DataMembers</a> and .Net 3.5's <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx">DataContractJsonSerializer</a>.  Its currently in alpha stage, as I need to finish writing the tests, documentation and make a simple WPF client for twitter.  I needed a twitter library for a personal "secret" project of mine and found that most twitter libraries do not keep up with the twitter API and break when using them. Plus they tend to go to great lengths when parsing the xml.  Unfortunately I do not know if this will work on mono yet. It seems that they have "<a href="http://www.mono-project.com/WCF">Olive</a>", which is mono's version of WCF and I've seen where they have a path for the "DataContractJsonSerializer".  If there are any one familiar enough with mono, please by all means use the code, join the project.  </p> <p>One design decision that I made was to use Json rather than xml as its more compact and less data to transfer.  I used WCF because with DataContract & DataMembers you can parse Json and you can name your properties the property way with Pascal Case properties and then tell wcf what attributes of json they represent. This way you don't have properties that look like ruby like "screen_name" or  "profile_sidebar_border_color" in your <a href="http://martinfowler.com/eaaCatalog/dataTransferObject.html">Data Transfer Object</a> in order to deserialize the Json response from twitter. </p> <p> </p> <p>A basic sample of how to use the library is below. </p> <pre class="code csharp"> 348 349using Amplify.Twitter; 350using System.Security; 351 352// ... stuff 353 354public void Test() 355{ 356 SecureString password = new SecureString(); 357 string temp = "password"; 358 for (var i = 0; i < temp.Length; i++) 359 password.AppendChar(temp[i]); 360 361 password.MakeReadOnly(); 362 Twitter.SetCredentials("Username", password); 363 364 StatusService service = Twitter.CreateStatusService(); 365 // or StatusService service = new StatusService("Username", password); 366 367 List<Status> tweets = service.GetUserTimeline("MichaelHerndon"); 368} 369 370</pre> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Amplify.aspx">Amplify</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/DataContractJsonSerializer.aspx">DataContractJsonSerializer</a>, <a rel='tag' href="http://www.amptools.net/labels/JSON.aspx">JSON</a>, <a rel='tag' href="http://www.amptools.net/labels/REST.aspx">REST</a>, <a rel='tag' href="http://www.amptools.net/labels/Twitter.aspx">Twitter</a>, <a rel='tag' href="http://www.amptools.net/labels/WCF.aspx">WCF</a></p> 371 </div> 372 <div class="blog-footer"> 373 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=3907268195622759157"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=3907268195622759157;><span style="text-transform:lowercase">3 Comments</span></a> 374 375 <a class="comment-link" href="http://www.amptools.net/2008/07/amplify-twittern-yet-another-c-twitter.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 376 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=3907268195622759157" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 377 378 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 379 </div> 380 381 </div> 382 <div class="right"> 383 <h3> 384 Connect 385 </h3> 386 <ul> 387 <li> 388 <a href="http://www.twitter.com/michaelherndon"> 389 <img src="/content/images/twitter-badge.png" alt="Twitter badge" /> 390 </a> 391 </li> 392 <li> 393 <a href="http://www.facebook.com/profile.php?id=824905532"> 394 <img src="/content/images/facebook-badge.png" alt="Facebook badge" /> 395 </a> 396 </li> 397 <li> 398 <a href="skype:michaelherndon?add"> 399 <img src="http://download.skype.com/share/skypebuttons/buttons/add_green_transparent_118x23.png" alt="Add me to Skype" /> 400 </a> 401 </li> 402 </ul> 403 404 <h3> 405 <a href="http://feeds.feedburner.com/amptoolsnet" rel="alternate" type="application/rss+xml"> 406 Subscribe in a reader <img src="http://www.feedburner.com/fb/images/pub/feed-icon32x32.png" style="vertical-align:middle" alt="" /> 407 </a> 408 </h3> 409 <ul> 410 <li> 411 412 </li> 413 <li> 414 <a href="http://feeds.feedburner.com/amptoolsnet"> 415 <img src="http://feeds.feedburner.com/~fc/amptoolsnet?bg=990066&fg=CCCCCC&anim=0" alt="" /> 416 </a> 417 </li> 418 <li> 419 <a href="http://add.my.yahoo.com/rss?url=http://feeds.feedburner.com/amptoolsnet" title="amptools.net"> 420 <img src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif" alt="" /> 421 </a> 422 </li> 423 <li> 424 <a href="http://fusion.google.com/add?feedurl=http://feeds.feedburner.com/amptoolsnet"> 425 <img src="http://buttons.googlesyndication.com/fusion/add.gif" alt="Add to Google Reader or Homepage"/> 426 </a> 427 </li> 428 <li> 429 <a href="http://www.pageflakes.com/subscribe.aspx?url=http://feeds.feedburner.com/amptoolsnet" title="Add to Pageflakes"> 430 <img src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&fileName=ATP_blu_91x17.gif" alt="Add to Pageflakes"/> 431 </a> 432 </li> 433 <li> 434 <a href="http://www.bloglines.com/sub/http://feeds.feedburner.com/amptoolsnet" title="amptools.net" type="application/rss+xml"> 435 <img src="http://www.bloglines.com/images/sub_modern11.gif" alt="Subscribe in Bloglines" /> 436 </a> 437 </li> 438 <li> 439 <a href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http://feeds.feedburner.com/amptoolsnet" title="amptools.net"> 440 <img src="http://www.newsgator.com/images/ngsub1.gif" alt="Subscribe in NewsGator Online" /> 441 </a> 442 </li> 443 </ul> 444 <h3 class="sidebar-title"> 445 Previous Posts 446 </h3> 447 <ul id="recently"> 448 449 <li><a href="http://www.amptools.net/2008/11/simple-log-in-amplify.aspx">Simple Log in Amplify </a></li> 450 451 <li><a href="http://www.amptools.net/2008/10/gallio-and-mb-unit-release-v304.aspx">Gallio and Mb-Unit release v3.0.4</a></li> 452 453 <li><a href="http://www.amptools.net/2008/10/moving-amplify-to-git-hub.aspx">Moving Amplify To Git Hub...</a></li> 454 455 <li><a href="http://www.amptools.net/2008/08/getting-datadirectory-folder-in-c-sharp.aspx">Getting the |DataDirectory| folder in C sharp</a></li> 456 457 <li><a href="http://www.amptools.net/2008/08/ampliy-fusion-javascript-libraries.aspx">Amplify-Fusion, JavaScript libraries compatibility...</a></li> 458 459 <li><a href="http://www.amptools.net/2008/07/amplify-wcf-twitter-api-client-library.aspx">Amplify's WCF Twitter API Client Library v0.2</a></li> 460 461 <li><a href="http://www.amptools.net/2008/07/use-c-to-determine-where-and-what.aspx">Use C# to determine where and what version of java...</a></li> 462 463 <li><a href="http://www.amptools.net/2008/07/using-wcf-to-access-flickr-json-api.aspx">Using WCF to access the Flickr JSON API</a></li> 464 465 <li><a href="http://www.amptools.net/2008/07/sample-mixins-for-httprequestbase-to.aspx">Sample Mixins for HttpRequestBase to use with Asp....</a></li> 466 467 <li><a href="http://www.amptools.net/2008/07/amplify-twittern-yet-another-c-twitter.aspx">Amplify's TwitterN, Yet Another C# Twitter REST AP...</a></li> 468 469 </ul> 470 <h3 class="sidebar-title"> 471 Archives 472 </h3> 473 <ul class="archive-list"> 474 475 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_03_30_index.aspx">03.30.2008</a></li> 476 477 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_04_06_index.aspx">04.06.2008</a></li> 478 479 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_06_08_index.aspx">06.08.2008</a></li> 480 481 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_07_06_index.aspx">07.06.2008</a></li> 482 483 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_07_13_index.aspx">07.13.2008</a></li> 484 485 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_07_20_index.aspx">07.20.2008</a></li> 486 487 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_07_27_index.aspx">07.27.2008</a></li> 488 489 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_08_03_index.aspx">08.03.2008</a></li> 490 491 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_08_10_index.aspx">08.10.2008</a></li> 492 493 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_10_26_index.aspx">10.26.2008</a></li> 494 495 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_11_02_index.aspx">11.02.2008</a></li> 496 497 </ul> 498 </div> 499 500</asp:Content>