3

I'm using the ParseControl method in ASP.Net to render some mixed HTML and server control code which is coming from an external data source.

This is working well, however ParseControl does not seem to support inline script blocks (<% %>), and I'm wondering if there is a simple alternative or workaround for this? Here's one simple example (real world implementation is more complex):

string externalCodeString = "<div><%= DateTime.Now %></div>";
Control control = ParseControl(externalCodeString);
placeholder.Controls.Add(control);
TimS
  • 5,922
  • 6
  • 35
  • 55

5 Answers5

2

ParseControl indeed does not support code blocks because it never causes any compilation.

One approach that should work but is more complicated is to instead rely on a UserControl served by a VirtualPathProvider.

You could then in theory wrap that into a simple API like ParseControl, but it would actually compile the user control.

You'd have to do proper caching, to make sure you don't end up compiling on every call, which would kill perf.

Dynamic Languages would work better for something like this :)

David Ebbo
  • 42,443
  • 8
  • 103
  • 117
1

Based on the context given in your question, this might work - unless there is a limitation you might not have mentioned yet.

Is it possible to write to disk first, so that you can use Page.LoadControl instead?

E.g. take your external data source, stream it to a unique file (give it a GUID name if you need, or base the name on a timestamp, or even a hash of the incoming string) and then use Page.LoadControl(pathToFile), passing the file location as the parameter.

The advantage to naming the file based on a hash of the string is that you can save re-writing it for the exact same input if it ever gets repeated.

At some point you will need a clean-up process that deletes any unused files.

Neil Fenwick
  • 6,106
  • 3
  • 31
  • 38
1

Is it possible for you to switch to Razor syntax for your inline code? If yes, than you can use Razor View Engine to parse it (Hosting the Razor Engine for Templating in Non-Web Applications).

You can also use this easy to use razor templating engine to parse and emit the HTML:

  string template = "<div>@DateTime.Now</div>";
  string result = Razor.Parse(template, new { Prop1 = "someValue" });

  placeholder.Controls.Add(new LiteralControl(result));
Mrchief
  • 75,126
  • 20
  • 142
  • 189
1

There is a restriction that no-compile pages can’t have code.

http://www.asp.net/learn/whitepapers/ironpython

The new IronPython that is in an early stage is a solution:

If the parser encounters a code snippet (<% ... %>, <%= ... %>, or <%# ... %>), it replaces the snippet with a special control that holds the code. From the point of view of ASP.NET, there is no code; the snippet just becomes a control that happens to have a string property with the code. This is how we get around the restriction that no-compile pages can’t have code.

The Demz
  • 7,066
  • 5
  • 39
  • 43
-1

Try this out:

placeholder.Controls.Add(new LiteralControl(String.Format("<div>{0}</div>", DateTime.Now)));
James Johnson
  • 45,496
  • 8
  • 73
  • 110
  • The code is coming from an external data source, so requirement is for the code to be inline (if this is possible of course). I have considered using string replacement as above, however the number of possible variables to replace with will be huge, so would not be maintainable. – TimS Aug 15 '11 at 15:27
  • I'm confused... how does your example meet the requirement for inline coding? Is that code in a script block or something? – James Johnson Aug 17 '11 at 15:50
  • Yes, there will be several ASP.Net <% %> script blocks inside the string which comes from the external source. Sorry if I'm using the wrong terminology, should I update the Q? – TimS Aug 17 '11 at 15:59