private RestItemData GetOutputData(RestResourceInfo info) { var data = new RestItemData(); data.Add("Name", _pathNameSwitcher(info.Name)); // keys switch naming conventions in .Formatting, but values don't data.Add("Type", info.Type.ToString().SeparateCamelCase("_", true)); // TODO naming convention? and error types too if (!string.IsNullOrEmpty(info.Description)) { data.Add("Description", info.Description); } return(data); }
/// <summary> /// This method displays the documentation page /// </summary> /// <param name="sender">The object raising the event</param> /// <param name="e">The event arguments</param> protected void Page_Load(object sender, EventArgs e) { const string METHOD_NAME = "Page_Load"; try { //Display the current product name in the title this.Title = "Library Information System" + ": REST Web Service"; this.ltrProductName2.Text = "Library Information System"; //Populate the base url string baseUrl = Request.Url.AbsoluteUri; baseUrl = baseUrl.Replace(".aspx", ".svc/"); this.lnkBaseUrl.Text = baseUrl; this.lnkBaseUrl.NavigateUrl = baseUrl; //We need to load in the assembly's XML comments (Web.XML) string xmlCommentsPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase), "Web.XML"); XmlDocument xmlCommentsDoc = new XmlDocument(); try { xmlCommentsDoc.Load(xmlCommentsPath); } catch (Exception exception) { Response.Write("Unable to load Web.XML comments file: " + exception.Message); } //We need to get a list of all the resources Dictionary <string, RestResourceInfo> resourceDic = new Dictionary <string, RestResourceInfo>(); //The first thing we need to do is iterate through all the different service methods in the interface MethodInfo[] methods = typeof(IRestService).GetMethods(); foreach (MethodInfo methodInfo in methods) { //See if it implements the resource attribute RestResourceAttribute resourceAttribute = (RestResourceAttribute)System.Attribute.GetCustomAttribute(methodInfo, typeof(RestResourceAttribute)); if (resourceAttribute != null) { //Get the resource name and description string name = resourceAttribute.ResourceName; string description = resourceAttribute.Description; //See if we have a WebGet or WebInvoke attribute WebGetAttribute webGetAttribute = (WebGetAttribute)System.Attribute.GetCustomAttribute(methodInfo, typeof(WebGetAttribute)); WebInvokeAttribute webInvokeAttribute = (WebInvokeAttribute)System.Attribute.GetCustomAttribute(methodInfo, typeof(WebInvokeAttribute)); //Determine the HTTP Method (GET, PUT, POST, DELETE) string httpMethodName = ""; string uri = ""; if (webGetAttribute != null) { httpMethodName = "GET"; uri = webGetAttribute.UriTemplate; } else if (webInvokeAttribute != null) { httpMethodName = webInvokeAttribute.Method; uri = webInvokeAttribute.UriTemplate; } if (!String.IsNullOrEmpty(httpMethodName)) { //Add it to the list of methods on this resource RestResourceInfo resourceInfo; if (resourceDic.ContainsKey(name)) { resourceInfo = resourceDic[name]; if (String.IsNullOrEmpty(resourceInfo.Description) && !String.IsNullOrEmpty(description)) { resourceInfo.Description = description; } if (!resourceInfo.Methods.Contains(httpMethodName)) { resourceInfo.Methods.Add(httpMethodName); } } else { resourceInfo = new RestResourceInfo() { Name = name, Description = description }; resourceInfo.Methods.Add(httpMethodName); resourceDic.Add(name, resourceInfo); } //Now actually add the method info RestOperationInfo operationInfo = new RestOperationInfo(); operationInfo.Uri = uri; operationInfo.Method = httpMethodName; resourceInfo.Operations.Add(operationInfo); //See if we can find matching XML description for this operation //We need to concatenate the class and method info string methodNamespace = "M:" + typeof(RestService).FullName + "." + methodInfo.Name; XmlNode xmlMethodSummary; if (methodInfo.GetParameters().Length > 0) { xmlMethodSummary = xmlCommentsDoc.SelectSingleNode("/doc/members/member[substring-before(@name,'(')='" + methodNamespace + "']/summary"); } else { xmlMethodSummary = xmlCommentsDoc.SelectSingleNode("/doc/members/member[@name='" + methodNamespace + "']/summary"); } if (xmlMethodSummary != null) { operationInfo.Description = xmlMethodSummary.InnerText; } } } } //Load the resource grid this.grdResources.DataSource = resourceDic; //Display the resource operations this.rptResourceOperations.DataSource = resourceDic; this.DataBind(); } catch (System.Exception exception) { Response.Write("Documentation Unavailable (" + exception.Message + ")!"); Logger.LogErrorEvent(CLASS_NAME + METHOD_NAME, exception); } }