Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

render child requests in razor views #671

Closed
wants to merge 1 commit into from

4 participants

@tylerburd

This is a proof of concept on rendering child requests within views.
This allows for more modular view pieces than you get with Partial
views, as the parent doesn't have to worry about constructing the model
for the child view piece. To see the proof in action, launch the
Nancy.Demo.Hosting.Aspnet project and browse to the /viewwithchildview
route.

@tylerburd tylerburd render child requests in razor views
This is a proof of concept on rendering child requests within views.
This allows for more modular view pieces than you get with Partial
views, as the parent doesn't have to worry about constructing the model
for the child view piece.  To see the proof in action, launch the
Nancy.Demo.Hosting.Aspnet project and browse to the /viewwithchildview
route.
0a7ea1f
@grumpydev
Owner

Will check this for perf, and probably hide the actual engine from the context behind some kind of facade, rather than expose the engine directly.

@phillip-haydon

We already support Partials now in Razor so I don't think this is required anymore.

@thecodejunkie I vote to close this.

@damianh
Owner

Closing this because A) partials and B) Almost 2 years old and no other user has weighted in. @thecodejunkie re-open if you disagree.

@damianh damianh closed this
@grumpydev
Owner

I started something that did the same thing a while back too, with storing the engine in the context and allowing rendering through it.. will finish it at some point :)

@damianh damianh removed this from the Future milestone
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 6, 2012
  1. @tylerburd

    render child requests in razor views

    tylerburd authored
    This is a proof of concept on rendering child requests within views.
    This allows for more modular view pieces than you get with Partial
    views, as the parent doesn't have to worry about constructing the model
    for the child view piece.  To see the proof in action, launch the
    Nancy.Demo.Hosting.Aspnet project and browse to the /viewwithchildview
    route.
This page is out of date. Refresh to see the latest.
View
12 src/Nancy.Demo.Hosting.Aspnet/MainModule.cs
@@ -88,6 +88,18 @@ public MainModule(IRouteCacheProvider routeCacheProvider)
return View[new SomeViewModel()];
};
+ Get["/viewwithchildview"] = x =>
+ {
+ var model = new RatPack { FirstName = "Parent" };
+ return View["viewwithchildview.cshtml", model];
+ };
+ Get["/childview"] = x =>
+ {
+ var firstNameFromQueryString = Request.Query["FirstName"];
+ var model = new RatPack { FirstName = firstNameFromQueryString };
+ return View["childview.cshtml", model];
+ };
+
Get["/spark"] = x => {
var model = new RatPack { FirstName = "Bright" };
return View["spark.spark", model];
View
2  src/Nancy.Demo.Hosting.Aspnet/Nancy.Demo.Hosting.Aspnet.csproj
@@ -108,6 +108,8 @@
<Content Include="Content\scripts.js" />
<Content Include="Views\razor-error.cshtml" />
<Content Include="Views\razor-layout-error.cshtml" />
+ <Content Include="Views\viewwithchildview.cshtml" />
+ <Content Include="Views\childview.cshtml" />
<None Include="Views\FileUpload.sshtml">
<SubType>Designer</SubType>
</None>
View
5 src/Nancy.Demo.Hosting.Aspnet/Views/childview.cshtml
@@ -0,0 +1,5 @@
+<div>
+ <h1>View: ChildView</h1>
+ <h1>First Name From (Child) Model: @Model.FirstName</h1>
+ <p>This is the child view being rendered within parent view!</p>
+</div>
View
11 src/Nancy.Demo.Hosting.Aspnet/Views/viewwithchildview.cshtml
@@ -0,0 +1,11 @@
+<html>
+<head>
+ <title>Razor View Engine Demo</title>
+</head>
+<body>
+ <h1>View: ViewWithChildView</h1>
+ <h1>First Name From Model: @Model.FirstName</h1>
+ <p>This is a sample of using a child view within a parent view!</p>
+ @Html.Get("/childview", new { firstName = "ImmaChild" })
+</body>
+</html>
View
73 src/Nancy.ViewEngines.Razor/HtmlHelpers.cs
@@ -1,4 +1,9 @@
-namespace Nancy.ViewEngines.Razor
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using Nancy.Helpers;
+
+namespace Nancy.ViewEngines.Razor
{
using System;
using System.IO;
@@ -94,5 +99,71 @@ public IHtmlString AntiForgeryToken()
return new NonEncodedHtmlString(String.Format("<input type=\"hidden\" name=\"{0}\" value=\"{1}\"/>", tokenKeyValue.Key, tokenKeyValue.Value));
}
+
+ /// <summary>
+ /// Allows you to perform a child request and insert the output somewhere into a parent view.
+ /// </summary>
+ /// <param name="route">the route you wish to </param>
+ /// <param name="queryStringParams"></param>
+ /// <returns></returns>
+ public IHtmlString Get(string route, object queryStringParams)
+ {
+ return Get(route, GetDictionaryFromObjectProps(queryStringParams));
+ }
+
+ public IHtmlString Get(string route, IDictionary<string, object> queryStringParams)
+ {
+ var currentContext = this.RenderContext.Context;
+ var headers = new Dictionary<string, IEnumerable<string>>();
+ foreach (var key in currentContext.Request.Headers.Keys)
+ {
+ headers[key] = currentContext.Request.Headers[key];
+ }
+
+ var queryString = GetQueryString(queryStringParams);
+
+ var nancyEngine = currentContext.NancyEngine;
+ var req = new Request("GET", route, headers, null, currentContext.Request.Url.Scheme, queryString, currentContext.Request.UserHostAddress);
+ var childContext = nancyEngine.HandleRequest(req);
+
+ Action<Stream> action = childContext.Response.Contents;
+ var mem = new MemoryStream();
+ action.Invoke(mem);
+ mem.Position = 0;
+ var reader = new StreamReader(mem);
+
+ return new NonEncodedHtmlString(reader.ReadToEnd());
+ }
+
+
+ private static Dictionary<string, object> GetDictionaryFromObjectProps(object parameters)
+ {
+ var publicAttributes = BindingFlags.Public | BindingFlags.Instance;
+ var dictionary = new Dictionary<string, object>();
+
+ foreach (PropertyInfo property in parameters.GetType().GetProperties(publicAttributes))
+ {
+ if (property.CanRead)
+ dictionary.Add(property.Name, property.GetValue(parameters, null));
+ }
+
+ return dictionary;
+ }
+
+ private static string GetQueryString(IDictionary<string, object> d)
+ {
+ if (d == null || d.Count == 0)
+ return "";
+
+ var paramList = new List<string>();
+ foreach (var keyAndVal in d)
+ {
+ var val = keyAndVal.Value == null ? "" : keyAndVal.Value.ToString();
+ paramList.Add(string.Format("{0}={1}", HttpUtility.UrlEncode(keyAndVal.Key), HttpUtility.UrlEncode(val)));
+ }
+
+ return string.Join("&", paramList.ToArray());
+ }
+
}
}
View
2  src/Nancy/NancyContext.cs
@@ -55,6 +55,8 @@ public Request Request
}
}
+ public INancyEngine NancyEngine { get; set; }
+
/// <summary>
/// Gets or sets the outgoing response
/// </summary>
View
1  src/Nancy/NancyEngine.cs
@@ -73,6 +73,7 @@ public NancyContext HandleRequest(Request request)
var context = this.contextFactory.Create();
context.Request = request;
+ context.NancyEngine = this;
var pipelines =
this.RequestPipelinesFactory.Invoke(context);
Something went wrong with that request. Please try again.