예제 #1
0
        internal static string GetQueryString(object request, IDictionary <string, RouteMember> propertyMap)
        {
            var result = new StringBuilder();

            foreach (var queryProperty in propertyMap)
            {
                var value = queryProperty.Value.GetValue(request, true);
                if (value == null)
                {
                    continue;
                }

                result.Append(queryProperty.Key)
                .Append('=')
                .Append(RestRoute.FormatQueryParameterValue(value))
                .Append('&');
            }

            if (result.Length > 0)
            {
                result.Length -= 1;
            }
            return(result.ToString());
        }
예제 #2
0
 /// <summary>Success.</summary>
 ///
 /// <param name="route">The route.</param>
 /// <param name="uri">  URI of the document.</param>
 ///
 /// <returns>A RouteResolutionResult.</returns>
 public static RouteResolutionResult Success(RestRoute route, string uri)
 {
     return new RouteResolutionResult { Route = route, Uri = uri };
 }
예제 #3
0
 /// <summary>Errors.</summary>
 ///
 /// <param name="route">   The route.</param>
 /// <param name="errorMsg">Message describing the error.</param>
 ///
 /// <returns>A RouteResolutionResult.</returns>
 public static RouteResolutionResult Error(RestRoute route, string errorMsg)
 {
     return new RouteResolutionResult { Route = route, FailReason = errorMsg };
 }
예제 #4
0
 /// <summary>Success.</summary>
 ///
 /// <param name="route">The route.</param>
 /// <param name="uri">  URI of the document.</param>
 ///
 /// <returns>A RouteResolutionResult.</returns>
 public static RouteResolutionResult Success(RestRoute route, string uri)
 {
     return(new RouteResolutionResult {
         Route = route, Uri = uri
     });
 }
예제 #5
0
 /// <summary>Errors.</summary>
 ///
 /// <param name="route">   The route.</param>
 /// <param name="errorMsg">Message describing the error.</param>
 ///
 /// <returns>A RouteResolutionResult.</returns>
 public static RouteResolutionResult Error(RestRoute route, string errorMsg)
 {
     return(new RouteResolutionResult {
         Route = route, FailReason = errorMsg
     });
 }
예제 #6
0
        /// <summary>An IReturn extension method that converts this object to an URL.</summary>
        ///
        /// <exception cref="InvalidOperationException">Thrown when the requested operation is invalid.</exception>
        ///
        /// <param name="request">                        The request to act on.</param>
        /// <param name="httpMethod">                     The HTTP method.</param>
        /// <param name="formatFallbackToPredefinedRoute">The format fallback to predefined route.</param>
        ///
        /// <returns>The given data converted to a string.</returns>
        public static string ToUrl(this IReturn request, string httpMethod, string formatFallbackToPredefinedRoute = null)
        {
            httpMethod = httpMethod.ToUpper();

            var requestType   = request.GetType();
            var requestRoutes = routesCache.GetOrAdd(requestType, GetRoutesForType);

            if (requestRoutes.Count == 0)
            {
                if (formatFallbackToPredefinedRoute == null)
                {
                    throw new InvalidOperationException("There are no rest routes mapped for '{0}' type. ".Fmt(requestType)
                                                        + "(Note: The automatic route selection only works with [Route] attributes on the request DTO and"
                                                        + "not with routes registered in the IAppHost!)");
                }

                var predefinedRoute = "/{0}/syncreply/{1}".Fmt(formatFallbackToPredefinedRoute, requestType.Name);
                if (httpMethod == "GET" || httpMethod == "DELETE" || httpMethod == "OPTIONS" || httpMethod == "HEAD")
                {
                    var queryProperties = RestRoute.GetQueryProperties(request.GetType());
                    predefinedRoute += "?" + RestRoute.GetQueryString(request, queryProperties);
                }

                return(predefinedRoute);
            }

            var routesApplied  = requestRoutes.Select(route => route.Apply(request, httpMethod)).ToList();
            var matchingRoutes = routesApplied.Where(x => x.Matches).ToList();

            if (matchingRoutes.Count == 0)
            {
                var errors = string.Join(String.Empty, routesApplied.Select(x => "\r\n\t{0}:\t{1}".Fmt(x.Route.Path, x.FailReason)).ToArray());
                var errMsg = "None of the given rest routes matches '{0}' request:{1}"
                             .Fmt(requestType.Name, errors);

                throw new InvalidOperationException(errMsg);
            }

            RouteResolutionResult matchingRoute;

            if (matchingRoutes.Count > 1)
            {
                matchingRoute = FindMostSpecificRoute(matchingRoutes);
                if (matchingRoute == null)
                {
                    var errors = String.Join(String.Empty, matchingRoutes.Select(x => "\r\n\t" + x.Route.Path).ToArray());
                    var errMsg = "Ambiguous matching routes found for '{0}' request:{1}".Fmt(requestType.Name, errors);
                    throw new InvalidOperationException(errMsg);
                }
            }
            else
            {
                matchingRoute = matchingRoutes[0];
            }

            var url = matchingRoute.Uri;

            if (httpMethod == HttpMethods.Get || httpMethod == HttpMethods.Delete || httpMethod == HttpMethods.Head)
            {
                var queryParams = matchingRoute.Route.FormatQueryParameters(request);
                if (!String.IsNullOrEmpty(queryParams))
                {
                    url += "?" + queryParams;
                }
            }

            return(url);
        }