Skip to content

Instantly share code, notes, and snippets.

@atifaziz
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atifaziz/c0adbb8792bf350437cc to your computer and use it in GitHub Desktop.
Save atifaziz/c0adbb8792bf350437cc to your computer and use it in GitHub Desktop.
<%@ WebHandler Class="DemoService" Language="C#" %>
using Jayrock.JsonRpc;
[ JsonRpcHelp("This is a JSON-RPC service that demonstrates the basic features of the Jayrock library.") ]
public class DemoService : JsonRpcHandler
{
[ JsonRpcMethod("add", Idempotent = true)]
[ JsonRpcHelp("Return the sum of two integers.") ]
[ JsonRpcTestExample("{ a: 123, b: 456 }") ]
public int Add(int a, int b)
{
return a + b;
}
}
using System;
using System.Web.Compilation;
using System.Web.UI;
using Jayrock.Services;
[AttributeUsage(AttributeTargets.Method)]
public class JsonRpcTestExampleAttribute : Attribute
{
readonly string _request;
public JsonRpcTestExampleAttribute() : this(null) { }
public JsonRpcTestExampleAttribute(string request)
{
_request = request;
}
public string Request
{
get { return _request ?? string.Empty; }
}
}
public class JsonRpcHandler : Jayrock.JsonRpc.Web.JsonRpcHandler
{
protected override object GetFeatureByName(string name)
{
if ("test".Equals(name, StringComparison.OrdinalIgnoreCase))
{
var type = BuildManager.GetCompiledType("~/JsonRpcTester.aspx");
var feature = (IServiceInjection) Activator.CreateInstance(type);
feature.Inject(this);
return feature;
}
return base.GetFeatureByName(name);
}
}
public interface IServiceInjection
{
void Inject(IService service);
}
public class JsonRpcPage : Page, IServiceInjection
{
public IService Service { get; private set; }
void IServiceInjection.Inject(IService service) { Service = service; }
}
<%@ Page Language="C#" Inherits="JsonRpcPage" %>
<%--
LICENSE, TERMS AND CONDITIONS
Jayrock - JSON and JSON-RPC for Microsoft .NET Framework and Mono
Written by Atif Aziz (www.raboof.com)
Copyright (c) 2005 Atif Aziz. All rights reserved.
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--%>
<%@ Import Namespace="Jayrock.Services" %>
<%@ Import Namespace="Jayrock.Json" %>
<!DOCTYPE html>
<script runat="server">
string PageTitle { get { return "Test " + Service.GetClass().Name; } }
JsonObject GetCallTemplatesObject()
{
var info = new JsonObject();
foreach (var method in Service.GetClass().GetMethods())
{
var example = method.GetCustomAttributes().OfType<JsonRpcTestExampleAttribute>().SingleOrDefault();
var template = example != null ? example.Request : string.Empty;
info.Put(method.Name, string.IsNullOrEmpty(template) ? GetCallTemplateJson(method) : template);
}
return info;
}
static string GetCallTemplateJson(Method method)
{
var parameters = method.GetParameters();
var args = parameters.Length == 0
? "/* void */"
: string.Join(", ", from p in parameters select "\"" + p.Name + "\" : null");
return "{ " + args + " }";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><%= PageTitle %></title>
<style>
body {
margin: 0;
font-family: arial;
font-size: small;
}
h1 {
color: #FFF;
font-size: large;
padding: 0.5em;
background-color: #003366;
margin-top: 0;
}
#Content {
margin: 1em;
}
#Request, #Response {
display: block;
margin-top: 0.5em;
width: 90%;
}
#Response.error {
color: red;
}
#Headers {
font-family: Monospace;
font-size: small;
}
</style>
<!-- https://code.google.com/p/jayrock/source/browse/src/Jayrock/json.js?name=0.9.16530 -->
<script src="json.js"></script>
<script>
var callTemplates = <%= GetCallTemplatesObject() %>;
var theForm = null;
var nextRequestId = 0;
Number.prototype.formatWhole = function()
{
var s = this.toFixed(0).toString();
var groups = [];
while (s.length > 0)
{
groups.unshift(s.slice(-3));
s = s.slice(0, -3);
}
return groups.join();
}
window.onload = function()
{
theForm = document.forms[0];
Method_onchange(theForm.Method);
}
function Method_onchange(sender)
{
theForm.Request.value = callTemplates[sender.options[sender.selectedIndex].value];
}
function Test_onclick(sender)
{
var stats = document.getElementById('Stats');
setText(stats, null);
var headers = document.getElementById('Headers');
setText(headers, null);
var form = theForm;
try
{
var request = {
id : ++nextRequestId,
method : form.Method.value,
params : theForm.Request.value };
form.Response.value = '';
form.Response.className = '';
var response = callSync(request);
setText(stats, 'Time taken = ' + (response.timeTaken / 1000).toFixed(4) + ' milliseconds; Response size = ' + response.http.text.length.formatWhole() + ' char(s)');
setText(headers, response.http.headers);
if (response.error != null) throw response.error;
form.Response.value = JSON.stringify(response.result);
}
catch (e)
{
form.Response.className = 'error';
form.Response.value = JSON.stringify(e);
alert(e.message);
}
}
function callSync(request)
{
var http = window.XMLHttpRequest ?
new XMLHttpRequest() :
new ActiveXObject('Microsoft.XMLHTTP');
http.open('POST', '<%= Request.FilePath %>', false);
http.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');
http.setRequestHeader('X-JSON-RPC', request.method);
http.send('{"id":' + request.id + ', "method":"' + request.method + '","params":' + request.params + '}');
if (http.status != 200)
throw { message : http.status + ' ' + http.statusText, toString : function() { return this.message; } };
var clockStart = new Date();
var response = JSON.parse(http.responseText);
response.timeTaken = (new Date()) - clockStart;
response.http = { text : http.responseText, headers : http.getAllResponseHeaders() };
return response;
}
function setText(e, text)
{
while (e.firstChild)
e.removeChild(e.firstChild);
if (text == null)
return;
text = text.toString();
if (0 === text.length)
return;
var textNode = document.createTextNode(text);
e.appendChild(textNode);
}
</script>
</head>
<body>
<h1><%= PageTitle %></h1>
<div id="Content">
<% var description = Service.GetClass().Description;
if (description.Length > 0) { %>
<span class="service-help"><%= description %></span>
<% } %>
<form id="TestForm">
<p>Select method to test:
<select id="Method" onchange="return Method_onchange(this)">
<% foreach (var method in Service.GetClass()
.GetMethods()
.OrderBy(m => m.Name, StringComparer.Ordinal)
.ToArray())
{ %> <option><%= method.Name %></option> <% } %>
</select>
<input type="button" id="Test" value="Test" accesskey="T" onclick="return Test_onclick(this)" />
<a href="<%= Request.FilePath %>?help">Help</a>
</p>
<p>Request parameters:</p>
<textarea id="Request" rows="10"
title="Enter the array of parameters (in JSON) to send in the RPC request."></textarea>
<p>Response result/error:</p>
<textarea id="Response" rows="10" readonly="readonly"
title="The result or error object (in JSON) from the last RPC response."></textarea>
<p id="Stats"></p>
<% %><pre id="Headers"></pre>
</form>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment