diff --git a/src/ServiceStack/HttpHandlerFactory.cs b/src/ServiceStack/HttpHandlerFactory.cs
index b0ebe4e04e1..50511c643c4 100644
--- a/src/ServiceStack/HttpHandlerFactory.cs
+++ b/src/ServiceStack/HttpHandlerFactory.cs
@@ -290,13 +290,7 @@ public static IHttpHandler GetHandlerForPathInfo(IHttpRequest httpReq, string fi
: ForbiddenHttpHandler;
}
- if (appHost.Config.FallbackRestPath != null)
- {
- restPath = appHost.Config.FallbackRestPath(httpReq);
- if (restPath != null)
- return new RestHandler { RestPath = restPath, RequestName = restPath.RequestType.GetOperationName(), ResponseContentType = contentType };
- }
-
+ // Check for PagedBasedRouting before wildcard Fallback Service
foreach (var httpHandlerResolver in appHost.FallbackHandlersArray)
{
var httpHandler = httpHandlerResolver(httpMethod, pathInfo, filePath);
@@ -304,6 +298,13 @@ public static IHttpHandler GetHandlerForPathInfo(IHttpRequest httpReq, string fi
return httpHandler;
}
+ if (appHost.Config.FallbackRestPath != null)
+ {
+ restPath = appHost.Config.FallbackRestPath(httpReq);
+ if (restPath != null)
+ return new RestHandler { RestPath = restPath, RequestName = restPath.RequestType.GetOperationName(), ResponseContentType = contentType };
+ }
+
return null;
}
diff --git a/src/ServiceStack/TemplateBootstrapFilters.cs b/src/ServiceStack/TemplateBootstrapFilters.cs
index 75c54e5dcde..4a25936436b 100644
--- a/src/ServiceStack/TemplateBootstrapFilters.cs
+++ b/src/ServiceStack/TemplateBootstrapFilters.cs
@@ -222,7 +222,7 @@ public IRawString formControl(TemplateScopeContext scope, object inputAttrs, str
var cls = inline ? " custom-control-inline" : "";
sbInput.AppendLine($"
");
var inputId = name + "-" + kvp.Key;
- var selected = selectedValues.Contains(formValue) || selectedValues.Contains(kvp.Key) ? " checked" : "";
+ var selected = kvp.Key == formValue || selectedValues.Contains(kvp.Key) ? " checked" : "";
sbInput.AppendLine($" ");
sbInput.AppendLine($" ");
sbInput.AppendLine("
");
diff --git a/src/ServiceStack/TemplatePagesFeature.cs b/src/ServiceStack/TemplatePagesFeature.cs
index 7958b143439..4c312632b05 100644
--- a/src/ServiceStack/TemplatePagesFeature.cs
+++ b/src/ServiceStack/TemplatePagesFeature.cs
@@ -447,6 +447,21 @@ public async Task ProcessRequestAsync(IRequest req, object dto, Stream out
}
}
+ TemplatePage layoutPage = null;
+ var layoutName = req.GetItem(Keywords.Template) as string;
+ Dictionary args = null;
+
+ if (codePage == null && viewPage == null && explicitView != null)
+ {
+ if (PageBasedRoutingHandler(req.Verb, explicitView, null) is TemplatePageHandler pageHandler)
+ {
+ viewPage = pageHandler.Page;
+ args = pageHandler.Args;
+ if (layoutName == null)
+ layoutPage = pageHandler.LayoutPage;
+ }
+ }
+
if (codePage == null && viewPage == null)
return false;
@@ -455,14 +470,13 @@ public async Task ProcessRequestAsync(IRequest req, object dto, Stream out
else
await viewPage.Init();
- var layoutName = req.GetItem(Keywords.Template) as string;
- var layoutPage = codePage != null
+ layoutPage = layoutPage ?? (codePage != null
? Pages.ResolveLayoutPage(codePage, layoutName)
- : Pages.ResolveLayoutPage(viewPage, layoutName);
-
+ : Pages.ResolveLayoutPage(viewPage, layoutName));
+
var handler = codePage != null
? (HttpAsyncTaskHandler)new TemplateCodePageHandler(codePage, layoutPage) { OutputStream = outputStream, Model = dto }
- : new TemplatePageHandler(viewPage, layoutPage) { OutputStream = outputStream, Model = dto };
+ : new TemplatePageHandler(viewPage, layoutPage) { OutputStream = outputStream, Model = dto, Args = args };
await handler.ProcessRequestAsync(req, req.Response, req.OperationName);
@@ -810,8 +824,8 @@ public object Any(TemplatesAdmin request)
public class TemplatePageHandler : HttpAsyncTaskHandler
{
- private TemplatePage page;
- private TemplatePage layoutPage;
+ public TemplatePage Page { get; private set; }
+ public TemplatePage LayoutPage { get; private set; }
public Dictionary Args { get; set; }
public object Model { get; set; }
public Stream OutputStream { get; set; }
@@ -827,21 +841,21 @@ public TemplatePageHandler(string pagePath, string layoutPath=null)
public TemplatePageHandler(TemplatePage page, TemplatePage layoutPage = null)
{
this.RequestName = !string.IsNullOrEmpty(page.VirtualPath) ? page.VirtualPath : nameof(TemplatePageHandler);
- this.page = page;
- this.layoutPage = layoutPage;
+ this.Page = page;
+ this.LayoutPage = layoutPage;
}
public override async Task ProcessRequestAsync(IRequest httpReq, IResponse httpRes, string operationName)
{
- if (page == null && pagePath != null)
+ if (Page == null && pagePath != null)
{
var pages = httpReq.TryResolve();
- page = pages.GetPage(pagePath)
+ Page = pages.GetPage(pagePath)
?? throw new FileNotFoundException($"Template Page not found '{pagePath}'");
if (!string.IsNullOrEmpty(layoutPath))
{
- layoutPage = pages.GetPage(layoutPath)
+ LayoutPage = pages.GetPage(layoutPath)
?? throw new FileNotFoundException($"Template Page not found '{layoutPath}'");
}
}
@@ -857,16 +871,16 @@ public override async Task ProcessRequestAsync(IRequest httpReq, IResponse httpR
}
}
- var pageResult = new PageResult(page)
+ var pageResult = new PageResult(Page)
{
Args = args,
- LayoutPage = layoutPage,
+ LayoutPage = LayoutPage,
Model = Model,
};
try
{
- httpRes.ContentType = page.Format.ContentType;
+ httpRes.ContentType = Page.Format.ContentType;
if (OutputStream != null)
{
await pageResult.WriteToAsync(OutputStream);
@@ -900,7 +914,7 @@ public override async Task ProcessRequestAsync(IRequest httpReq, IResponse httpR
}
catch (Exception ex)
{
- await page.Format.OnViewException(pageResult, httpReq, ex);
+ await Page.Format.OnViewException(pageResult, httpReq, ex);
}
}
}
@@ -911,6 +925,8 @@ public class TemplateCodePageHandler : HttpAsyncTaskHandler
private readonly TemplatePage layoutPage;
public object Model { get; set; }
public Stream OutputStream { get; set; }
+
+ public Dictionary Args { get; set; }
public TemplateCodePageHandler(TemplateCodePage page, TemplatePage layoutPage = null)
{
@@ -933,6 +949,14 @@ public override async Task ProcessRequestAsync(IRequest httpReq, IResponse httpR
Model = Model,
};
+ if (Args != null)
+ {
+ foreach (var entry in Args)
+ {
+ result.Args[entry.Key] = entry.Value;
+ }
+ }
+
try
{
httpRes.ContentType = page.Format.ContentType;
diff --git a/tests/CheckWebCore/wwwroot/_layout.html b/tests/CheckWebCore/wwwroot/_layout.html
index c608c7ae211..42f56e63065 100644
--- a/tests/CheckWebCore/wwwroot/_layout.html
+++ b/tests/CheckWebCore/wwwroot/_layout.html
@@ -29,10 +29,10 @@ MyApp
-
+
-
{{ title }}
+ {{#if title}}{{ title }}
{{/if}}
{{ page }}
diff --git a/tests/CheckWebCore/wwwroot/validation/server-js/contacts/edit.html b/tests/CheckWebCore/wwwroot/validation/server-js/contacts/_id/edit.html
similarity index 71%
rename from tests/CheckWebCore/wwwroot/validation/server-js/contacts/edit.html
rename to tests/CheckWebCore/wwwroot/validation/server-js/contacts/_id/edit.html
index a90b5ce8760..817c318249c 100644
--- a/tests/CheckWebCore/wwwroot/validation/server-js/contacts/edit.html
+++ b/tests/CheckWebCore/wwwroot/validation/server-js/contacts/_id/edit.html
@@ -2,13 +2,13 @@
{{ '/validation/server-js/contacts/' | assignTo: continue }}
-{{ { Id } | sendToGateway('GetContact', {catchError:'ex'}) | assignTo: response }}
+{{ { id } | sendToGateway('GetContact', {catchError:'ex'}) | assignTo: response }}
{{#with response.Result}}
Update Contact