forked from BlogEngine/BlogEngine.NET
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRazorHelpers.cs
More file actions
207 lines (182 loc) · 7.39 KB
/
RazorHelpers.cs
File metadata and controls
207 lines (182 loc) · 7.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
using BlogEngine.Core;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Compilation;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.WebPages.Html;
public static class RazorHelpers
{
/// <summary>
/// Returns the HTML markup for a widget zone.
/// </summary>
public static string RenderWidgetZone(this HtmlHelper helper, string zoneName)
{
return RenderControl(helper, "App_Code.Controls.WidgetZone", new List<KeyValuePair<string, object>>() { { new KeyValuePair<string, object>("ZoneName", zoneName) } });
}
/// <summary>
/// Returns the HTML markup for a control which will be created by it's typename.
/// </summary>
public static string RenderControl(this HtmlHelper helper, string typeName, IEnumerable<KeyValuePair<string, object>> properties)
{
try
{
Type t = Type.GetType(typeName);
if (t != null)
{
object obj = Activator.CreateInstance(t);
if (obj != null)
{
Control control = obj as Control;
if (control != null)
{
return RenderControl(helper, control, properties);
}
else
{
Utils.Log($"Unable to cast the instantiated object as a control: {typeName}");
}
}
else
{
Utils.Log($"Unable to activate control: {typeName}");
}
}
else
{
Utils.Log($"Unable to load control type: {typeName}");
}
}
catch (Exception ex)
{
Utils.Log($"Unable to load control: {typeName}", ex);
}
return HttpUtility.HtmlEncode($"ERROR - UNABLE TO LOAD CONTROL : {typeName}");
}
/// <summary>
/// Returns the HTML markup for a user control which will be created by it's virtual path and name.
/// </summary>
public static string RenderUserControl(this HtmlHelper helper, string controlVirtualPath, IEnumerable<KeyValuePair<string, object>> properties)
{
try
{
System.Web.UI.Page page = HttpContext.Current.Handler as System.Web.UI.Page;
if (page != null)
{
Control control = page.LoadControl(controlVirtualPath);
return RenderControl(helper, control, properties);
}
else
{
Utils.Log($"Page is null when trying to render control: {controlVirtualPath}");
}
}
catch (Exception ex)
{
Utils.Log($"Unable to load control: {controlVirtualPath}", ex);
}
return HttpUtility.HtmlEncode($"ERROR - UNABLE TO LOAD CONTROL : {controlVirtualPath}");
}
/// <summary>
/// Returns the HTML markup for a control, invoking any properties on the control.
/// </summary>
public static string RenderControl(this HtmlHelper helper, Control control, IEnumerable<KeyValuePair<string, object>> properties)
{
try
{
if (string.IsNullOrWhiteSpace(control.ID))
{
control.ID = $"control_{Guid.NewGuid()}";
}
if (properties != null && properties.Count() > 0)
{
var type = control.GetType();
foreach (KeyValuePair<string, object> prop in properties)
{
var property = type.GetProperty(prop.Key);
property.SetValue(
control,
Convert.ChangeType(prop.Value, property.PropertyType, CultureInfo.InvariantCulture),
null);
}
}
// To ensure all the events in the lifecycle fire (Init, Load, etc), put
// this control into a page and run that page to get the final control markup.
System.Web.UI.Page page = new System.Web.UI.Page();
page.EnableViewState = false;
HtmlForm form = new HtmlForm();
PlaceHolder ph = new PlaceHolder();
const string delimiterStart = "-|-|-|-|-|-|-|-|- control start -|-|-|-|-|-|-|-|-";
const string delimiterEnd = "-|-|-|-|-|-|-|-|- control start -|-|-|-|-|-|-|-|-";
ph.Controls.Add(new LiteralControl(delimiterStart));
ph.Controls.Add(control);
ph.Controls.Add(new LiteralControl(delimiterEnd));
form.Controls.Add(ph);
page.Controls.Add(form);
StringWriter output = new StringWriter();
HttpContext.Current.Server.Execute(page, output, false);
string markup = output.ToString();
Match m = new Regex(string.Format("{0}(.*?){1}", Regex.Escape(delimiterStart), Regex.Escape(delimiterEnd)), RegexOptions.IgnoreCase | RegexOptions.Singleline).Match(markup);
if (m.Success)
{
return m.Groups[1].Value;
}
return string.Empty;
}
catch (Exception ex)
{
Utils.Log($"Unable to load control: {control.GetType()}", ex);
}
return HttpUtility.HtmlEncode($"ERROR - UNABLE TO LOAD CONTROL : {control.GetType()}");
}
public const string PAGE_BODY_MARKER = "-|-|-|-|-|-|- PAGE-BODY -|-|-|-|-|-|-";
public static string PageBody(this HtmlHelper helper)
{
return PAGE_BODY_MARKER;
}
public const string NESTED_COMMENTS_MARKER = "-|-|-|-|-|-|- NESTED-COMMENTS -|-|-|-|-|-|-";
public static string NestedComments(this HtmlHelper helper)
{
return NESTED_COMMENTS_MARKER;
}
public const string WIDGET_CONTAINER_BODY_MARKER = "-|-|-|-|-|-|- WIDGET-CONTAINER-BODY -|-|-|-|-|-|-";
public static string WidgetContainerBody(this HtmlHelper helper)
{
return WIDGET_CONTAINER_BODY_MARKER;
}
public const string RAZOR_HOST_PAGE_VPATH = "~/Custom/Themes/RazorHost/page.cshtml";
public static string ParseRazor(string virtualPath, object model)
{
string pageVPath = virtualPath;
try
{
Type t = BuildManager.GetCompiledType(pageVPath);
if (t != null)
{
HttpContextWrapper wrapper = new HttpContextWrapper(HttpContext.Current);
object inst = Activator.CreateInstance(t);
System.Web.WebPages.WebPage webpage = inst as System.Web.WebPages.WebPage;
webpage.VirtualPath = pageVPath;
StringWriter writer = new StringWriter();
webpage.ExecutePageHierarchy(new System.Web.WebPages.WebPageContext(wrapper, webpage, model), writer, webpage);
string content = writer.ToString();
return content;
}
}
catch (Exception ex)
{
Utils.Log($"RazorHelper, ParseRazor, VirtualPath: {virtualPath}", ex);
// return the error message since it will usually contain parsing
// details when the Razor markup/syntax is invalid. this will help
// when debugging, so the error log does not need to be checked.
return ex.Message;
}
return null;
}
}