Example #1
0
 public object BindPrimitive(Request request, string parameterName, Type parameterType)
 {
     //TODO: what if there are multiple values here?
     string stringValue = null;
     
     if (request.RouteTokens.ContainsKey(parameterName))
     {
         stringValue = request.RouteTokens[parameterName];
     }
     else if (request.QueryString.ContainsKey(parameterName))
     {
         stringValue = request.QueryString[parameterName][0];
     }
     
     if (parameterType == typeof(int))
     {
         int x = 0;
         var parsed = null != stringValue && int.TryParse(stringValue, out x);
         if(parsed)
         {
             return x;
         }
         
         //TODO: indicate this to the developer
         //I don't like returning 4xx here without calling the action, because it prevents further validations
         return 0;
     }
     
     //TODO: tons of types, I would like to think of a clever way to not have to handcode all of them
     
     return stringValue;
 }
 public void RequestBindsToRequest()
 {
     var binder = new RequestBinder();
     
     Assert.True(binder.SupportsType(typeof(Request)));
     
     var request = new Request();
     
     Assert.Equal(request, binder.Bind(request, "blah", typeof(Request)));
     
 }
 public void BodyGetsDeserializedAsJson()
 {
     var binder = new DefaultBinder();
     
     var request = new Request { RequestBody = GenerateStreamFromString("{ \"name\": \"Fred\", \"isBig\": true }") };
     
     var boundBird = binder.Bind(request, "bird", typeof(Bird)) as Bird;
     
     Assert.NotNull(boundBird);
     Assert.True(boundBird.IsBig);
     Assert.Equal("Fred", boundBird.Name);
 }
Example #4
0
 private object BindParameter(ParameterExpression parameter, Request request, List<ParameterBinder> parameterBinders)
 {
     var binder = parameterBinders.FirstOrDefault(b => b.SupportsType(parameter.Type));
     
     if (null == binder)
     {
         //TODO: figure out how to get this error to the developer
         return null;
     }
     
     return binder.Bind(request, parameter.Name, parameter.Type);
     
     
 }
Example #5
0
 public object HandleRequest(Request request, List<ParameterBinder> parameterBinders)
 {
     //TODO: handle parameter not available
     //TODO: should repeating the key be valid for collection types?
     
     //var callValues = _parameters.Select(p => Convert.ChangeType(queryString[p.Name][0], p.ParameterType)).ToArray();
     var callValues = _parameters.Select(p => BindParameter(p, request, parameterBinders)).ToArray();
     // var stringValue = queryString[_parameterName][0];
     
     // //TODO: let users register converts
     // object castValue = Convert.ChangeType(stringValue, _parameterType);
     
     
     return _handler.DynamicInvoke(callValues);
 }
 public void RouteTokensBind()
 {
     var binder = new DefaultBinder();
     
     Assert.True(binder.SupportsType(typeof(int)));
     Assert.True(binder.SupportsType(typeof(string)));
     
     var routeTokens = new Dictionary<string, string>();
     routeTokens["myInt"] = "2";
     routeTokens["myString"] = "turquoise";
     
     var request = new Request{ RouteTokens = routeTokens, QueryString = new Dictionary<string, string[]>() };
     
     Assert.Equal(2, binder.Bind(request, "myInt", typeof(int)));
     Assert.Equal("turquoise", binder.Bind(request, "myString", typeof(string)));
     
 }
 public void QueryStringBinds()
 {
     var binder = new DefaultBinder();
     
     Assert.True(binder.SupportsType(typeof(int)));
     Assert.True(binder.SupportsType(typeof(string)));
     
     var queryString = new Dictionary<string, string[]>();
     queryString["myInt"] = new []{"2"};
     queryString["myString"] = new []{"turquoise"};
     
     var request = new Request{ QueryString = queryString, RouteTokens = new Dictionary<string, string>() };
     
     Assert.Equal(2, binder.Bind(request, "myInt", typeof(int)));
     Assert.Equal("turquoise", binder.Bind(request, "myString", typeof(string)));
     
 }
 public void RouteTokensHideQueryString()
 {
     //I don't know if this is the behavior I want, but since it's what happens now changing it should fail a test
     var binder = new DefaultBinder();
     
     Assert.True(binder.SupportsType(typeof(int)));
     Assert.True(binder.SupportsType(typeof(string)));
     
     var queryString = new Dictionary<string, string[]>();
     queryString["myInt"] = new []{"not 2"};
     queryString["myString"] = new []{"not turquoise"};
     
     var routeTokens = new Dictionary<string, string>();
     routeTokens["myInt"] = "2";
     routeTokens["myString"] = "turquoise";
     
     var request = new Request{ RouteTokens = routeTokens, QueryString = queryString };
     
     Assert.Equal(2, binder.Bind(request, "myInt", typeof(int)));
     Assert.Equal("turquoise", binder.Bind(request, "myString", typeof(string)));
     
 }
Example #9
0
        //TODO: consider access level - this is primarily public for testing     
        public Task HandleRequest(string method, string path, string queryString,
            IDictionary<string, string[]> requestHeaders,
            Stream requestBody,
            IDictionary<string, string[]> responseHeaders,
            Stream responseStream, Action<int> setStatusCode)
        {
            
            var parsedQueryString = ParseQueryString(queryString);
            var request = new Request { QueryString = parsedQueryString, 
                RequestHeaders = requestHeaders, RequestBody = requestBody,
                RouteTokens = new Dictionary<string, string>()};
            var handler = _router.ResolveRoute(method, path, request.RouteTokens);
            
            if (null != handler)
            {
                //TODO: don't assume the return is a string
                var result = (handler.HandleRequest(request, _binders) ?? "").ToString();
                
                byte[] responseBytes = Encoding.UTF8.GetBytes(result);
                responseHeaders["Content-Length"] = new string[] { responseBytes.Length.ToString(CultureInfo.InvariantCulture) };
                responseHeaders["Content-Type"] = new string[] { "text/plain; charset=utf-8" };

                return responseStream.WriteAsync(responseBytes, 0, responseBytes.Length);
            }
            else
            {
                setStatusCode(404);
                var text = path + " not found";
                byte[] responseBytes = Encoding.UTF8.GetBytes(text);
                responseHeaders["Content-Length"] = new string[] { responseBytes.Length.ToString(CultureInfo.InvariantCulture) };
                responseHeaders["Content-Type"] = new string[] { "text/plain; charset=utf-8" };
                return responseStream.WriteAsync(responseBytes, 0, responseBytes.Length);
            }

            
       
            
        }
Example #10
0
 public override object Bind(Request request, string parameterName, Type parameterType)
 {
     if (_primitiveTypes.Contains(parameterType))
     {
         return BindPrimitive(request, parameterName, parameterType);
     }
                 
     // TODO: content negotiation, assume JSON for this pass
     var requestBody = request.RequestBody;
     
     if (null == requestBody)
     {
         return null;
     }
     
     using (var streamReader = new StreamReader(requestBody))
     {
         using (var jsonReader = new JsonTextReader(streamReader))
         {
             return _serializer.Deserialize(jsonReader, parameterType);
         }
     }
     
 }
Example #11
0
 public override object Bind(Request request, string parameterName, Type parameterType)
 {
     return request;
 }
Example #12
0
 public abstract object Bind(Request request, string parameterName, Type parameterType);