Skip to content
Permalink
Browse files

Add new CreateRequestFromUrl() API

  • Loading branch information...
mythz committed Apr 18, 2018
1 parent 22fbef2 commit ec2db1b41558264a593255f190c8856538c123b6
Showing with 71 additions and 3 deletions.
  1. +43 −3 src/ServiceStack/Host/ServiceMetadata.cs
  2. +28 −0 tests/ServiceStack.WebHost.Endpoints.Tests/RouteTests.cs
@@ -131,9 +131,8 @@ public Operation GetOperation(Type operationType)
{
if (operationType == null)
return null;

Operation op;
OperationsMap.TryGetValue(operationType, out op);

OperationsMap.TryGetValue(operationType, out var op);
return op;
}

@@ -358,6 +357,47 @@ public HashSet<Type> GetAllDtos()
return to;
}

public RestPath FindRoute(string pathInfo, string method = HttpMethods.Get)
{
var route = RestHandler.FindMatchingRestPath(method, pathInfo, out _);
return (RestPath)route;
}

public object CreateRequestFromUrl(string relativeOrAbsoluteUrl, string method = HttpMethods.Get)
{
var relativeUrl = relativeOrAbsoluteUrl.StartsWith("http:")
|| relativeOrAbsoluteUrl.StartsWith("https:")
? relativeOrAbsoluteUrl.RightPart("://").RightPart("/")
: relativeOrAbsoluteUrl;

if (!relativeUrl.StartsWith("/"))
relativeUrl = "/" + relativeUrl;

var parts = relativeUrl.SplitOnFirst("?");
var pathInfo = parts[0];

var route = FindRoute(pathInfo, method);
if (route == null)
throw new ArgumentException($"No matching route found for path {method} '{pathInfo}'");

Dictionary<string, string> query = null;
if (parts.Length == 2)
{
query = new Dictionary<string, string>();
var qs = parts[1];
var qsParts = qs.Split('&');
foreach (var qsPart in qsParts)
{
var kvp = qsPart.SplitOnFirst("=");
if (kvp.Length == 1) continue;
query[kvp[0]] = kvp[1].UrlDecode();
}
}

var requestDto = route.CreateRequest(pathInfo, query, route.RequestType.CreateInstance());
return requestDto;
}

private void AddReferencedTypes(HashSet<Type> to, Type type)
{
if (type == null || to.Contains(type) || !IsDtoType(type))
@@ -5,8 +5,10 @@
using Funq;
using NUnit.Framework;
using ServiceStack.Formats;
using ServiceStack.Host;
using ServiceStack.Host.Handlers;
using ServiceStack.Text;
using ServiceStack.WebHost.Endpoints.Tests.Support.Services;

namespace ServiceStack.WebHost.Endpoints.Tests
{
@@ -258,6 +260,32 @@ public async Task Can_POST_to_IdWithAlias_with_JsonHttpClient_async()
var response = await client.PostAsync(new IdWithAlias { Id = 1 });
Assert.That(response.Id, Is.EqualTo(1));
}

[Test]
public void Can_create_request_DTO_from_URL()
{
Assert.That(HostContext.Metadata.CreateRequestFromUrl("/hello") is Hello);

var request = (Hello)HostContext.Metadata.CreateRequestFromUrl("/hello/foo");
Assert.That(request.Name, Is.EqualTo("foo"));

request = (Hello)HostContext.Metadata.CreateRequestFromUrl("http://domain.org/hello/foo");
Assert.That(request.Name, Is.EqualTo("foo"));

request = (Hello)HostContext.Metadata.CreateRequestFromUrl("https://www.sub.domain.org/hello/foo");
Assert.That(request.Name, Is.EqualTo("foo"));

request = (Hello)HostContext.Metadata.CreateRequestFromUrl("/hello?name=bar");
Assert.That(request.Name, Is.EqualTo("bar"));

var responseType = HostContext.Metadata.GetResponseTypeByRequest(request.GetType());
Assert.That(responseType, Is.EqualTo(typeof(HelloResponse)));

request = (Hello)HostContext.Metadata.CreateRequestFromUrl("/hello?name=gateway");
var response = (HelloResponse)HostContext.AppHost.GetServiceGateway(new BasicRequest()).Send(responseType, request);
Assert.That(response.Result, Is.EqualTo("Hello, gateway"));
}

}

public class RouteAppHost : AppHostHttpListenerBase

0 comments on commit ec2db1b

Please sign in to comment.
You can’t perform that action at this time.