/src/Nancy/Diagnostics/Modules/InteractiveModule.cs

https://github.com/csainty/Nancy · C# · 152 lines · 123 code · 29 blank · 0 comment · 11 complexity · 08a9b43b45f80cb89b2d5ba0fc3aeed6 MD5 · raw file

  1. namespace Nancy.Diagnostics.Modules
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Linq;
  7. using Helpers;
  8. public class InteractiveModule : DiagnosticModule
  9. {
  10. private readonly IInteractiveDiagnostics interactiveDiagnostics;
  11. public InteractiveModule(IInteractiveDiagnostics interactiveDiagnostics)
  12. :base ("/interactive")
  13. {
  14. this.interactiveDiagnostics = interactiveDiagnostics;
  15. Get["/"] = _ =>
  16. {
  17. return View["InteractiveDiagnostics"];
  18. };
  19. Get["/providers"] = _ =>
  20. {
  21. var providers = this.interactiveDiagnostics
  22. .AvailableDiagnostics
  23. .Select(p => new
  24. {
  25. p.Name,
  26. p.Description,
  27. Type = p.GetType().Name,
  28. p.GetType().Namespace,
  29. Assembly = p.GetType().Assembly.GetName().Name
  30. })
  31. .ToArray();
  32. return this.Response.AsJson(providers);
  33. };
  34. Get["/providers/{providerName}"] = ctx =>
  35. {
  36. var providerName =
  37. HttpUtility.UrlDecode((string)ctx.providerName);
  38. var diagnostic =
  39. this.interactiveDiagnostics.GetDiagnostic(providerName);
  40. if (diagnostic == null)
  41. {
  42. return HttpStatusCode.NotFound;
  43. }
  44. var methods = diagnostic.Methods
  45. .Select(m => new
  46. {
  47. m.MethodName,
  48. ReturnType = m.ReturnType.ToString(),
  49. m.Description,
  50. Arguments = m.Arguments.Select(a => new
  51. {
  52. ArgumentName = a.Item1,
  53. ArgumentType = a.Item2.ToString()
  54. })
  55. })
  56. .ToArray();
  57. return this.Response.AsJson(methods);
  58. };
  59. Get["/providers/{providerName}/{methodName}"] = ctx =>
  60. {
  61. var providerName =
  62. HttpUtility.UrlDecode((string)ctx.providerName);
  63. var methodName =
  64. HttpUtility.UrlDecode((string)ctx.methodName);
  65. var method =
  66. this.interactiveDiagnostics.GetMethod(providerName, methodName);
  67. if (method == null)
  68. {
  69. return HttpStatusCode.NotFound;
  70. }
  71. object[] arguments =
  72. GetArguments(method, this.Request.Query);
  73. return this.Response.AsJson(new { Result = this.interactiveDiagnostics.ExecuteDiagnostic(method, arguments) });
  74. };
  75. Get["/templates/{providerName}/{methodName}"] = ctx =>
  76. {
  77. var providerName =
  78. HttpUtility.UrlDecode((string)ctx.providerName);
  79. var methodName =
  80. HttpUtility.UrlDecode((string)ctx.methodName);
  81. var method =
  82. this.interactiveDiagnostics.GetMethod(providerName, methodName);
  83. if (method == null)
  84. {
  85. return HttpStatusCode.NotFound;
  86. }
  87. var template =
  88. this.interactiveDiagnostics.GetTemplate(method);
  89. if (template == null)
  90. {
  91. return HttpStatusCode.NotFound;
  92. }
  93. return template;
  94. };
  95. }
  96. private static object[] GetArguments(InteractiveDiagnosticMethod method, dynamic query)
  97. {
  98. var arguments = new List<object>();
  99. foreach (var argument in method.Arguments)
  100. {
  101. arguments.Add(ConvertArgument((string)query[argument.Item1].Value, argument.Item2));
  102. }
  103. return arguments.ToArray();
  104. }
  105. private static object ConvertArgument(string value, Type destinationType)
  106. {
  107. var converter =
  108. TypeDescriptor.GetConverter(destinationType);
  109. if (converter == null || !converter.CanConvertFrom(typeof(string)))
  110. {
  111. return null;
  112. }
  113. try
  114. {
  115. return converter.ConvertFrom(value);
  116. }
  117. catch (FormatException)
  118. {
  119. return null;
  120. }
  121. }
  122. }
  123. }