Skip to content

Commit ff1d2ea

Browse files
committed
Introducing controllers and controller handler
1 parent 26c3b00 commit ff1d2ea

15 files changed

Lines changed: 569 additions & 30 deletions
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using uhttpsharp;
7+
using uhttpsharp.Handlers;
8+
9+
namespace uhttpsharpdemo.Controllers
10+
{
11+
public class JsonController
12+
{
13+
public class Question
14+
{
15+
public string TheQuestion { get; set; }
16+
}
17+
public JsonController(int id)
18+
{
19+
}
20+
21+
[HttpMethod(HttpMethods.Post)]
22+
public Task<IControllerResponse> Post([FromBody] Question question)
23+
{
24+
return Response.Render(HttpResponseCode.Ok, question);
25+
}
26+
}
27+
public class MyController
28+
{
29+
private readonly int _id;
30+
public MyController(int id)
31+
{
32+
_id = id;
33+
}
34+
public MyController()
35+
{
36+
}
37+
38+
[HttpMethod(HttpMethods.Post)]
39+
public Task<IControllerResponse> Post([FromPost("a")] MyRequest request, [FromHeaders("header")]string hello, [FromQuery("query")]string world)
40+
{
41+
return Response.Render(HttpResponseCode.Ok, null);
42+
}
43+
44+
[Indexer]
45+
public async Task<object> Get(IHttpContext context, int id)
46+
{
47+
return new MyController(id);
48+
}
49+
}
50+
public class MyRequest
51+
{
52+
public int A { get; set; }
53+
}
54+
class DemoController
55+
{
56+
}
57+
}

uhttpsharp-demo/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ private static void Main()
5252
//httpServer.Use(new ListenerSslDecorator(new TcpListenerAdapter(new TcpListener(IPAddress.Loopback, 443)), serverCertificate));
5353

5454
//httpServer.Use(new SessionHandler<DateTime>(() => DateTime.Now));
55+
httpServer.Use(new ControllerHandler(new JsonController(0), new JsonModelBinder(), new JsonView()));
5556
httpServer.Use(new ExceptionHandler());
5657
httpServer.Use(new ClassRouter(new MySuperHandler()));
5758
httpServer.Use(new TimingHandler());

uhttpsharp-demo/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
33
<package id="log4net" version="2.0.3" targetFramework="net45" />
4-
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net45" />
4+
<package id="Newtonsoft.Json" version="6.0.3" targetFramework="net45" />
55
</packages>

uhttpsharp-demo/uhttpsharp.Demo.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@
4242
<Reference Include="log4net">
4343
<HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
4444
</Reference>
45-
<Reference Include="Newtonsoft.Json">
46-
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
45+
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
46+
<SpecificVersion>False</SpecificVersion>
47+
<HintPath>..\packages\Newtonsoft.Json.6.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
4748
</Reference>
4849
<Reference Include="System" />
4950
<Reference Include="System.Core" />
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
3+
namespace uhttpsharp.Attributes
4+
{
5+
public class HttpMethodAttribute : Attribute
6+
{
7+
private readonly HttpMethods _httpMethod;
8+
public HttpMethodAttribute(HttpMethods httpMethod)
9+
{
10+
_httpMethod = httpMethod;
11+
}
12+
13+
public HttpMethods HttpMethod
14+
{
15+
get { return _httpMethod; }
16+
}
17+
}
18+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using uhttpsharp.ModelBinders;
7+
8+
namespace uhttpsharp.Attributes
9+
{
10+
internal interface IModelBinding
11+
{
12+
T Get<T>(IHttpContext context, IModelBinder binder);
13+
}
14+
15+
internal class FromBodyAttribute : Attribute, IModelBinding
16+
{
17+
public T Get<T>(IHttpContext context, IModelBinder binder)
18+
{
19+
return binder.Get<T>(context.Request.Post.Raw);
20+
}
21+
}
22+
23+
public class FromPostAttribute : PrefixAttribute
24+
{
25+
public FromPostAttribute(string prefix = null)
26+
: base(prefix)
27+
{
28+
}
29+
public override T Get<T>(IHttpContext context, IModelBinder binder)
30+
{
31+
return binder.Get<T>(context.Request.Post.Parsed, Prefix);
32+
}
33+
}
34+
35+
public class FromQueryAttribute : PrefixAttribute
36+
{
37+
public FromQueryAttribute(string prefix)
38+
: base(prefix)
39+
{
40+
}
41+
public override T Get<T>(IHttpContext context, IModelBinder binder)
42+
{
43+
return binder.Get<T>(context.Request.QueryString, Prefix);
44+
}
45+
}
46+
47+
public class FromHeadersAttribute : PrefixAttribute
48+
{
49+
public FromHeadersAttribute(string prefix)
50+
: base(prefix)
51+
{
52+
}
53+
54+
public override T Get<T>(IHttpContext context, IModelBinder binder)
55+
{
56+
return binder.Get<T>(context.Request.Headers, Prefix);
57+
}
58+
}
59+
60+
public abstract class PrefixAttribute : Attribute, IModelBinding
61+
{
62+
private readonly string _prefix;
63+
64+
public PrefixAttribute(string prefix)
65+
{
66+
_prefix = prefix;
67+
}
68+
69+
public bool HasPrefix
70+
{
71+
get { return !string.IsNullOrEmpty(_prefix); }
72+
}
73+
74+
public string Prefix
75+
{
76+
get { return _prefix; }
77+
}
78+
79+
public abstract T Get<T>(IHttpContext context, IModelBinder binder);
80+
}
81+
}

uhttpsharp/Handlers/ClassRouter.cs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,17 @@ private Func<IHttpContext, IHttpRequestHandler, string, Task<IHttpRequestHandler
115115
{
116116
return null;
117117
}
118+
return CreateIndexerFunction<IHttpRequestHandler>(arg, indexer);
119+
}
120+
internal static Func<IHttpContext, T, string, Task<T>> CreateIndexerFunction<T>(Type arg, MethodInfo indexer)
121+
{
118122
var parameterType = indexer.GetParameters()[1].ParameterType;
119123

120124
var httpContext = Expression.Parameter(typeof(IHttpContext));
121-
var inputHandler = Expression.Parameter(typeof(IHttpRequestHandler));
125+
var inputHandler = Expression.Parameter(typeof(T));
122126
var inputObject = Expression.Parameter(typeof(string));
123127

124-
var tryParseMethod = parameterType.GetMethod("TryParse", new[] { typeof(string), parameterType.MakeByRefType() });
128+
var tryParseMethod = parameterType.GetMethod("TryParse", new[] {typeof(string), parameterType.MakeByRefType()});
125129

126130
Expression body;
127131

@@ -130,11 +134,11 @@ private Func<IHttpContext, IHttpRequestHandler, string, Task<IHttpRequestHandler
130134
var handlerConverted = Expression.Convert(inputHandler, arg);
131135
var objectConverted =
132136
Expression.Convert(
133-
Expression.Call(typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) }), inputObject,
137+
Expression.Call(typeof(Convert).GetMethod("ChangeType", new[] {typeof(object), typeof(Type)}), inputObject,
134138
Expression.Constant(parameterType)), parameterType);
135139

136140
var indexerExpression = Expression.Call(handlerConverted, indexer, httpContext, objectConverted);
137-
var returnValue = Expression.Convert(indexerExpression, typeof(IHttpRequestHandler));
141+
var returnValue = Expression.Convert(indexerExpression, typeof(T));
138142

139143
body = returnValue;
140144
}
@@ -146,23 +150,25 @@ private Func<IHttpContext, IHttpRequestHandler, string, Task<IHttpRequestHandler
146150
var objectConverted = inputConvertedVar;
147151

148152
var indexerExpression = Expression.Call(handlerConverted, indexer, httpContext, objectConverted);
149-
var returnValue = Expression.Convert(indexerExpression, typeof(Task<IHttpRequestHandler>));
150-
var returnTarget = Expression.Label(typeof(Task<IHttpRequestHandler>));
151-
var returnLabel = Expression.Label(returnTarget, Expression.Convert(Expression.Constant(null), typeof(Task<IHttpRequestHandler>)));
153+
var returnValue = Expression.Convert(indexerExpression, typeof(Task<T>));
154+
var returnTarget = Expression.Label(typeof(Task<T>));
155+
var returnLabel = Expression.Label(returnTarget,
156+
Expression.Convert(Expression.Constant(null), typeof(Task<T>)));
152157
body =
153158
Expression.Block(
154-
new[] { inputConvertedVar },
159+
new[] {inputConvertedVar},
155160
Expression.IfThen(
156-
Expression.Call(tryParseMethod, inputObject,
157-
inputConvertedVar),
158-
Expression.Return(returnTarget, returnValue)
159-
),
161+
Expression.Call(tryParseMethod, inputObject,
162+
inputConvertedVar),
163+
Expression.Return(returnTarget, returnValue)
164+
),
160165
returnLabel);
161166
}
162167

163-
164-
return Expression.Lambda<Func<IHttpContext, IHttpRequestHandler, string, Task<IHttpRequestHandler>>>(body, httpContext, inputHandler,
165-
inputObject).Compile();
168+
return
169+
Expression.Lambda<Func<IHttpContext, T, string, Task<T>>>(body, httpContext,
170+
inputHandler,
171+
inputObject).Compile();
166172
}
167173
private MethodInfo GetIndexer(Type arg)
168174
{

0 commit comments

Comments
 (0)