How To: Use Asp.Net Web Service and Prototype to Process a Form

Category: Graffiti Tips

sample code

One of the challenges in using Graffiti for a custom application is how to integrate custom functionality with the rich content management provided by native Graffiti. By using the Prototype JavaScript library in combination with a web service, you can add custom forms processing to your site.

The basics of this approach are fairly easy to understand, but the details are pretty difficult to find. Hopefully, this post will help someone avoid the hours I have spent in search of these elusive details!

The Asp.Net Web Service Side

In this example, my web service simply accepts the contents of a form as a JSON object and then processes it. In this case, the processing consists of updating a result object and then echoing it back to the calling client.

Here is the web service code:

       [WebMethod]
       [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public Result ProcessContactUs(ContactUsForm contactUsForm)
        {

            string firstName = contactUsForm.txtFirstName;
            string lastName = contactUsForm.txtLastName;


            Result result = new Result();
            result.ResultCode = "SUCCESS";
            result.Message = String.Format("Successly processed form: First Name: {0} Last Name: {1}", firstName, lastName);

            return result;
        }

The ContactUsForm class is a simple parameter object with fields to hold the data being transmitted and no behaviors.

        [Serializable]
        public class ContactUsForm
        {
            public ContactUsForm()
            {

            }

            private string _txtFirstName;
            private string _txtLastName;
            private string _ddlSelectOne;
            private string _chkJoinList;

            public string txtFirstName
            {
                get { return _txtFirstName; }
                set { _txtFirstName = value; }
            }

            public string txtLastName
            {
                get { return _txtLastName; }
                set { _txtLastName = value; }
            }

            public string ddlSelectOne
            {
                get { return _ddlSelectOne; }
                set { _ddlSelectOne = value; }
            }

            public string chkJoinList
            {
                get { return _chkJoinList; }
                set { _chkJoinList = value; }
            }
        }

The key elements of the ContactUsForm class are: 1) it must be marked as Serializable and 2) the field names match the field names used on the form to simplify serialization on the client side.

On the web service class, you should decorate the class with the attribute  [System.Web.Script.Services.ScriptService] and add in the appropriate using clause to include the System.Web.Script.Services library. The  [ScriptMethod(ResponseFormat = ResponseFormat.Json)] attribute decorating the web method is nice to have from a clarity perspective, but strictly speaking isn't strictly required since I believe this is the default.

The Prototype JavaScript Client Side

The client side has its own eccentricities. The key is the Prototype Ajax.Request API, the serialize method for serializing a form and the Object.toJSON method.

            function ProcessContactUs()
            {

                // for serialize to create an object you must use the name attribute
                // in the form fields   
                var contactUsForm = $("contactUs").serialize(true);


                // determining if a field is present and supplying
                // a value when it isn't
                if (contactUsForm.chkJoinList == undefined) {
                    contactUsForm.chkJoinList = "off";
                }

                // Convert the Object to a JSON string
                var contactUsFormJson = Object.toJSON(contactUsForm);

                // This technique gives you a serialized object for a GET
                var serializedForm = Form.serialize("contactUs");       // "old school" serialization

                var parameterValue = '{formVar: ' + $("contactUs").serialize(true) + '}';

                new Ajax.Request('http://localhost/ExampleServices/FormsProcessor.asmx/ProcessContactUs', {
                    method: 'post',
                    contentType: 'application/json; charset=utf-8',
                    postBody: '{contactUsForm: ' + Object.toJSON(contactUsForm) + '}',      // make sure parameter case matches!
                    onSuccess: SuccessForm,
                    onFailure: Failure
                });
            }

When using the Prototype Ajax.Request call, you must set the contentType to 'application/json; charset=utf-8'. This is a requirement of the Asp.Net framework and ensures JSON style communication. The second non-obvious piece is that the parameters should be passed in the postBody, not in the parameter parameter (at least this has been my experience ...).

The postBody must be formatted as a JSON object. This format is a bit particular and can be hand coded by using string concatenation, but the Object.toJSON() method will do it for you.

When the Prototype serialize method is used on a form, the form is serialized into an object. The Object.toJSON method then serializes the object into JSON.

The JSON Return Object

When you have a successful return, the SuccessForm method is called. The returned result object is in the transport.responseJSON parameter.

One note: this example requires Prototype 1.6. Graffiti 1.1 is shipping with Prototype 1.5, so you will need to upgrade your version of Prototype to get this example to work as shown.

Although I have shown this example using a contact form you can apply it to any form.

Additional useful references: