Quite often I am writing an MVC web application, WCF REST service, and AJAX to make calls from the web application to the REST service. Every time I have to look at one of my old projects on how I did it last time. So I decided to create a project with the skeleton code for the purpose that I can use as the basis for my next web application, rather trying to recall every time.In the Part I of this blog I'll show how to set up the WCF REST service for JSON payload. It will have a skeleton code to process incoming data, throw exceptions, set location headers, and return resource data as needed.In Part II we'll go over how to set the MVC 4 application and how to call the REST service from it with JSON payload using AJAX and parse the returned resources.You can download the sample project over at the end of the blog; let's start with the description of major step and caveats.PART I - WCF REST ServicePrerequisites:Make sure you have .NET Framework 4 and MVC 4 installed on your machine. If not, you can install them through Web Platform Installer. Remember to register .NET 4 with IIS after installation.In VS 2010, install "WCF Rest Service Template 40(CS)" either using the Tools->"Extention Manager" menu or from this link: http://visualstudiogallery.msdn.microsoft.com/fbc7e5c1-a0d2-41bd-9d7b-e54c845394cd.Setup the SolutionStart Visual Studio 2010 as an administrator and create a Blank Solution BoilerPlateMvcWcfAjax.Set up the basic WCF REST ServiceAdd a new project using the "WCF REST Service Application" template to the solution. I called this project WcfRestService.Select the Properties of the project, select the Web tab, and check the radio button "Use Local IIS Web Server". Enter http://localhost/WcfRestService for the project URL and click "Create Virtual Directory" button.Assuming you are using DefaultAppPool to run the "Default Web Site" on the IIS, make sure your DefaultAppPool is configured to use .NET 4Grant identity "IIS AppPool\DefaultAppPool" the read, write, execute, and list folders permissions to the BoilerPlateMvcWcfAjax project folder. Do the same for IUSR machine identity.At this point you should be able to build the project and access the service help: http://localhost/WcfRestService/Service1/help that lists all the methods you can call on the service.The WCF REST ServiceBy default VS2010 creates service file Service1.cs and data transfer object SampleItem.cs. which is fine for our demo. I made some changes in the service code, let's start with the code for GET verb to request an item by id: 1: [WebGet(UriTemplate = "{id}", 2: ResponseFormat = WebMessageFormat.Json)] 3: public SampleItem Get(string id) 4: { 5: int i = 1; 6: // return 400 if there's an error parsing incoming parameters 7: if (!Int32.TryParse(id, out i)) 8: { 9: throw new WebFaultException<string>("Uri parse error.", HttpStatusCode.BadRequest); 10: } 11: 12: bool dbError = false; 13: // retrieve data from the database here 14: // if there's an error, throw appropriate exception. 15: if (dbError) 16: { 17: throw new WebFaultException(HttpStatusCode.InternalServerError); 18: } 19: 20: return new SampleItem() { Id = i, Value = "Hello" }; 21: }We want the response to be in JSON so we can easily parse the in JavaScript; for that we need to configure the ResponseFormat to be WebMessageFormat.Json. We'll get into how to setup the JSON payload for the SampleItem parameter in the body of the POST request when we get to the MVC application in Part II.The GET request has no body, we can skip the RequestFormat as well as live with the the default BodyStyle of WebMessageBodyStyle.Bare. Other thing to note here is that we are returning HTTP error codes to the caller by throwing WebFaultException.The GET request for the collection of resources is similar. The difference is that we return all the resources whose URI is relative to the incoming URI. 1: [WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)] 2: public List<SampleItem> GetCollection() 3: { 4: bool dbError = false; 5: // retrieve data from the database here 6: // if there's an error, throw appropriate exception. 7: if (dbError) 8: { 9: throw new WebFaultException(HttpStatusCode.InternalServerError); 10: } 11: 12: // return all the resources under the path in the body of the response 13: return 14: new List<SampleItem>() 15: { 16: new SampleItem() { Id = 1, Value = "Hello" }, 17: new SampleItem() { Id = 2, Value = "World" } 18: }; 19: } 20: Let's look at the handling of the POST request used to create a resource on the server: 1: [WebInvoke(Method = "POST", UriTemplate = "", 2: RequestFormat = WebMessageFormat.Json, 3: ResponseFormat = WebMessageFormat.Json)] 4: public SampleItem Create(SampleItem instance) 5: { 6: bool dbError = false; 7: // update database here 8: // if there's an error, throw appropriate exception. 9: if (dbError) 10: { 11: throw new WebFaultException(HttpStatusCode.InternalServerError); 12: } 13: 14: // let's assume this is the id of the newly created resource 15: instance.Id = 1; 16: 17: // calculate the URI of the newly created resource 18: Uri baseUri = new Uri(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri.AbsoluteUri 19: + "/", UriKind.Absolute); 20: Uri locationUri = new Uri(baseUri, instance.Id.ToString()); 21: 22: // return 201 Created status code along with the URI of the newly created resource in the 23: // location header. 24: WebOperationContext.Current.OutgoingResponse.SetStatusAsCreated(locationUri); 25: 26: // return the newly created instance in the body of the response 27: return instance; 28: } 29: If successful, it must return the HTTP status code 201 CREATED instead of 200 OK. Also the URI of the newly created resource is returned in the LOCATION header. This achieved through the following line:WebOperationContext.Current.OutgoingResponse.SetStatusAsCreated(locationUri);The newly created resource itself is return in the body of the request.The code for the rest of the verbs is similar, we are including it here for the sake of completeness: 1: [WebInvoke(Method = "PUT", UriTemplate = "{id}", RequestFormat = WebMessageFormat.Json, 2: ResponseFormat = WebMessageFormat.Json)] 3: public SampleItem Update(string id, SampleItem instance) 4: { 5: int i = 1; 6: // return 400 if there's an error parsing incoming parameters 7: if (!Int32.TryParse(id, out i)) 8: { 9: throw new WebFaultException<string>("Uri parse error.", HttpStatusCode.BadRequest); 10: } 11: 12: bool dbError = false; 13: // update database here 14: // if there's an error, throw appropriate exception. 15: if (dbError) 16: { 17: throw new WebFaultException(HttpStatusCode.InternalServerError); 18: } 19: 20: // return the updated instance in the body of the response 21: return instance; 22: } 23: 24: [WebInvoke(Method = "DELETE", UriTemplate = "{id}", RequestFormat = WebMessageFormat.Json, 25: ResponseFormat = WebMessageFormat.Json)] 26: public SampleItem Delete(string id) 27: { 28: int i = 1; 29: // return 400 if there's an error parsing incoming parameters 30: if (!Int32.TryParse(id, out i)) 31: { 32: throw new WebFaultException<string>("Uri parse error.", HttpStatusCode.BadRequest); 33: } 34: 35: bool dbError = false; 36: // update database here 37: // if there's an error, throw appropriate exception. 38: if (dbError) 39: { 40: throw new WebFaultException(HttpStatusCode.InternalServerError); 41: } 42: 43: // return the deleted instance in the body of the response 44: return new SampleItem() { Id = i, Value = "Hello" }; 45: }Here's the link to download the project and here is the link to the Part II of this blog post.