Wednesday 24 April 2013

How to Use XmlAttribute with a Nullable Type?

Imagine you have the below property which should be serialized as an xml attribute if it has value and if not, it should just be ignored from the serialization:
[XmlAttribute("lastUpdated")]
public DateTime? LastUpdated { get; set; }
The solution would be introducing a new property and a new method:
 [XmlIgnore]
        public DateTime? LastUpdated { get; set; }

        [XmlAttribute("lastUpdated")]
        public DateTime LastUpdatedSerializable
        {
            get { return this.LastUpdated.Value; }
            set { this.LastUpdated = value; }
        }

        public bool ShouldSerializeLastUpdatedSerializable()
        {
            return LastUpdated.HasValue;
        }
It's important to know that ShouldSerialize{Property} and {Property}Specified are .NET Conventions to resolve this issue. I liked to find a better/cleaner/simpler approach but haven't found any yet.

Friday 19 April 2013

How to Post a Request to a Web API Web Service?

My test Web API Method looks like this:

 [HttpPost]
        public HttpResponseMessage TestPost(string siteName, User user, string providerName)
        {
            var result = string.Format("sitename is {0}. user is {1}. providername is {2}", 
                siteName,
                user == null 
                ? "null. " 
                : " not null; " + (string.Format("email: {0}, pass: {1}", user.EmailAddress, user.Password)),
                providerName);

            return new HttpResponseMessage()
                {
                    Content = new StringContent(result)
                };
        }

If I had started the naming with "Post" then I didn't need to use "HttpPost" attribute; by convention it could have found it automatically.

How to write the Route Template?

 config.Routes.MapHttpRoute(
             name: "testpost",
             routeTemplate: "sites/{siteName}/User/TestPost/{providerName}",
             defaults: new
             {
                 controller = "User",
                 action = "TestPost",
                 providerName = UrlParameter.Optional
             });

As shown, the last parameter is optional so it accepts the below sample urls:

 http://www.domain.com/sites/sitename1/user/TestPost/provider1 http://www.domain.com/sites/sitename1/user/TestPost

Also, the {siteName} value is automatically mapped to the siteName input parameter of the web method.

As you can see, I don't put the User object in to the url template since it will be posted and not visible in the get.

How to Make Post Calls?
Now, I've written two test methods showing two approaches to make Post Calls to this service. First approach is easier and uses RestSharp and the second approach uses WebRequest.

.NET 4.5 provides a new class called HttpClient which makes it even easier to make such calls.

 [TestClass]
    public class WhenLoadingAUser
    {
        private readonly string _baseUrlForLuis = ConfigurationManager.AppSettings["BaseUrlFor.Luis"];
        
        /// 
        /// Approach 1 using RestSharp
        /// 
        [TestMethod]
        public void Should_post_successfully_with_valid_userDetailsList_usingRestSharp()
        {
            // arrange
            string url = string.Format("{0}/sites/{1}/User/TestPost/viper", this._baseUrlForLuis,
                "viper");

            var client = new RestClient(url);
            
            var request = new RestRequest(Method.POST)
                {
                    RequestFormat = DataFormat.Xml
                };


            // When reaches the Web Service, the below anonymous object gets mapped to the User object automatically.
            request.AddObject(new
                {
                    EmailAddress = "emailAddreess",
                    Password = "some password"
                });

            // act
            var response = client.Execute(request).Content;
        }

        /// 
        /// Approach 2 using WebRequest
        /// 
        [TestMethod]
        public void Should_post_successfully_with_valid_userDetailsList_usingWebRequest()
        {
            // arrange
            string url = string.Format("{0}/sites/{1}/User/TestPost/viper", this._baseUrlForLuis,
                "viper");

            var httpWReq = (HttpWebRequest)WebRequest.Create(url);
            httpWReq.Method = "POST";
            httpWReq.ContentType = "application/x-www-form-urlencoded";
            
            // not sure why the below format is required and not xml 
            string postData = "EmailAddress=email&Password=pass";

            // act
            PostData(httpWReq, postData);
            string response = GetResponseAsString(httpWReq);
        }

        private static string GetResponseAsString(HttpWebRequest httpWReq)
        {
            var response = (HttpWebResponse) httpWReq.GetResponse();

            return  new StreamReader(response.GetResponseStream()).ReadToEnd();
        }

        private static void PostData(HttpWebRequest httpWReq, string postData)
        {
            var encoding = new ASCIIEncoding();

            byte[] data = encoding.GetBytes(postData);

            httpWReq.ContentLength = data.Length;

            using (Stream stream = httpWReq.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }
        }
    }


How to make the post call with Fiddler?

The Content-Type header is important. Also, the data which is sent should be prepended with "=".



How to make a Post Call with just with a browser?

  1. Open a page that you know has the JQuery library; e.g. www.jquery.com 
  2. Click F12 and go to the Console tab where you can write JQuery codes
  3. Type "$.post('your url here',{'':'your data here'});

Monday 15 April 2013

Amazon Simple Storage Services (S3)


Understanding Amazon S3 is very simple, believe me! It’s just like a Windows Folder on the cloud/internet and you can put files and folders in it!

It also enables you to add meta-data for each folder and file.

The root folder is called Bucket and you can have multiple buckets inside which you can have folders, subfolders or any type of file stored.

There are few other features as well.

How to view the Amazon S3 Folders/Buckets?

There are 3 ways you can work with Amazon S3 and view the folders and files:

Useful Links:

Blue Green Deployment Environments

The idea is that we should be having two copies (Blue and Green) of the same application on each environment (Dev, Staging, Live, etc).

One environment is always passive and is where we deploy the changes to and can test and make sure that all the tests pass e.g. blue.app

The other environment is always active which is an old passive application which has been activated after the tests have all passed.