MVC 5 custom HtmlHelper for lightweight content editing
asp.net-mvc, asp.net-mvc-5, html-helper, razor
Solution
You can not get the html within the `@using{...}` statement the way you are doing right now.
The closest thing you can do is use `Templated Razor Delegates`
public static HelperResult EditableSimpleHtml(this HtmlHelper helper, string key,
Func<string, HelperResult> template)
{
var templateResult = template(null);
//you have your value here that you can return directly
//or you can return HelperResult to write to the response directly
var templateResultHtml = templateResult.ToHtmlString();
return new HelperResult(writer =>
{
templateResult.WriteTo(writer);
});
}
And in your view:
@Html.EditableSimpleHtml("MyKey", @<text>
<h3>Test</h3>
<p>@DateTime.Now</p>
</text>)
Problem
After years of working with WebForms I recently started the transition to MVC. I'm trying to create a plugable, lightweight content editing module but I've run into some problems. The idea is simple: create a HtmlHelper named EditableSimpleHtml that can be used in a @using... { } syntax so that the following can be achieved in a razor view: ``` @using (Html.EditableSimpleHtml("MyKey")) { <h3>Test</h3> <p> 1<br /> </p> } ``` The value between the {...} is the default value for when no content can not be found in the data storage. I've create a HtmlHelper. Below is a simplified version: ``` public static IDisposable EditableSimpleHtml(this HtmlHelper helper, string key) { // Get the content from the data storage using the key (I will not show the provider itself, its just a provider that will access a db) var provider = ContentEditing.Provider; string value = provider.GetValue(key); if (value == null) { // No value found in the data storage for the supplied key, we have to use the default value from within the @using... { } statement // Can I get that value here? I want to to store it initialy in the data storage value = "..."; // How to get html from within the @using... { }? } return new ContentEditableHtmlString(helper, value); } public class ContentEditableHtmlString : IDisposable { private readonly HtmlHelper _helper; public ContentEditableHtmlString(HtmlHelper helper, string value) { _helper = helper; var builder = new TagBuilder("div"); var writer = _helper.ViewContext.Writer; writer.Write(builder.ToString(TagRenderMode.StartTag)); writer.Write(value); } public void Dispose() { _helper.ViewContext.Writer.Write("</div>"); } } ``` The problem is that I can't get the (default) content from within the @using... { } statement in the HtmlHelper, or at least I don't know how. I need it in case I want to store it to the database initially. Second problem is that the value between the @using... { } statement will always be rendered. In the case when the content can be loaded from the data storage I want the default value to be replaced with the value from the data storage. Is there a way to achieve this or did I start of on a completely wrong path?