I have an extension method that needs to return an HtmlString. The method has a loop which will build the HtmlString, however the HtmlString object has no Append method and does not allow concatenation using the + operator so I am not sure how I would build the HtmlString.
I'd like to use the StringBuilder but it doesn't have a ToHtmlString method...
Any solutions or patterns for this?
Why not just build the string in a stringbuilder and then
return MvcHtmlString.Create(sb.ToString());
I think you want to use TagBuilder. See also Using the TagBuilder Class to Build HTML Helpers like this:
// Create tag builder
var builder = new TagBuilder("img");
// Create valid id
builder.GenerateId(id);
// Add attributes
builder.MergeAttribute("src", url);
builder.MergeAttribute("alt", alternateText);
builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
// Render tag
return builder.ToString(TagRenderMode.SelfClosing);
You could have a look at the fubu spin-off for creating HTML Tags. Here is a SO question that talks a bit about its usage.
You could write the ToHtmlString() method yourself as a extension method on StringBuilder.
There are several solutions to this including using the TagBuilder, but using Html.Raw() worked very well for me:
public static IHtmlString HtmlMethod(this HtmlHelper htmlhelper, Object object)
{
var sb = new StringBuilder();
foreach (var item in object)
{
sb.Append(object.outputStr)
}
return htmlHelper.Raw(sb.ToString());
}
Related
I have a property which is a Rich Text Editor in Umbraco 7.
I want to get a part of the content of this property, to be more exact, the first p tag.
How can I accomplish this in Umbraco? Is their a helper class that I can use?
There isn't a helper method that you can use out of the box but it shouldn't be too difficult to write your own.
If you're using MVC then you could write an extension to the MVC HtmlHelper as follows:
public static string GetFirstParagraph(this HtmlHelper helper, IHtmlString input)
{
if (input != null && input.ToString() != string.Empty)
{
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(input.ToString());
var p = htmlDoc.DocumentNode.SelectSingleNode("//p");
if (p != null)
{
return p.InnerText;
}
}
return null;
}
To call this method in your view simply type:
#Html.GetFirstParagraph(Umbraco.Field("yourPropertyAlias"))
if using the Umbraco Field method, or:
#Html.GetFirstParagraph(Model.YourProperty)
if your view is strongly typed.
If you're actually using Web Forms then you could create a razor macro and use the code above to perform the same task.
I have never worked with actionfilter so i dont really know how to use it, ive done som reseach but i dont completly understand it. But basicly im going to create a new controller, and i want my _Viewstart.cshtml to use this controller. The problem is that i dont know how to use this code to an actionfilter and then call this controller in _viewstart.
The code that i want in my controller is.
var TemplateIDSession = Session["TemplateID"];
if (TemplateIDSession != null)
{
int tempID = (int)TemplateIDSession;
var template = servicetemp.GetEntry(tempID);
var servicetemp = ServiceFactory.Instance.CreateTemplateService();
Response.ContentType = "text/css";
return RazorEngine.Razor.Parse(System.IO.File.ReadAllText(Server.MapPath("Content/Site.css")));
I think you should go about this in a different way, by using a HTML Helper for the CSS, like so:
public static class Helpers
{
public static string OrganizationStyleTemplate(this HtmlHelper html)
{
TagBuilder tagBuilder = new TagBuilder("style");
var templateIDSession = HttpContext.Current.Session["TemplateID"];
if (TemplateIDSession != null)
{
// retrieve your css from the database and insert it into the tag
tagBuilder.InnerHtml = dbObject.CSSYouveStored;
}
return tagBuilder.ToString(TagRenderMode.Normal);
}
}
Then usage would be like so:
#Html.OrganizationStyleTemplate()
P.S. If you need to analyze if the user is authenticated within that method, use:
HttpContext.Current.Request.IsAuthenticated
I am currently running a website, i use a control that inherits from ITemplate to wrap all my usercontrols in.
basically what it is, is a table with a nice border, and i am able to dump anything in there, so if i change the container template, all the containers accross the site changes...
I am now in the process of rebuilding the entire application using MVC 2, does anyone know of a way i can achieve the same "Container" like template in MVC?
There would be several ways to do this in MVC, but I would probably suggest using a custom HTML Helper.
There is an example on how to implement something similar in this post. Look for the section titled "Creating a DataGrid Helper" in that post for more information. I think you will be able to adapt that example to fit your purpose.
I managed Thanx here is an example:
public static class Block
{
public static BlockHelper BeginBlock(this System.Web.Mvc.HtmlHelper content, string title)
{
return new BlockHelper(content, title);
}
}
public class BlockHelper : IDisposable
{
private readonly HtmlHelper _content;
private readonly HtmlHelper _title;
public BlockHelper(System.Web.Mvc.HtmlHelper content, string title)
{
_content = content;
StringBuilder sb = new StringBuilder();
sb.Append("<div>");
sb.Append("<div><h1>" + title + "</h1></div>");
_content.ViewContext.Writer.Write(sb.ToString());
}
public void Dispose()
{
StringBuilder sb = new StringBuilder();
sb.Append("</div>");
_content.ViewContext.Writer.Write(sb.ToString());
}
}
and then i basically uses it as follows:
<% using( Html.BeginBlock("TITLE>CONTENT GOES HERE<%}%>
Consider an extension method whose purpose is to either:
render an <a> tag
on some condition, just return a string without a link
Question: in an extension method, how can you leverage the proper routing logic with Route Values, etc. rather than hardcoding the string. I suspect HtmlHelper.GenerateRouteLink is part of the solution, but please suggest the best way to achieve this.
public static string CreateUserLink(this HtmlHelper html, string userAcctName)
{
if (string.IsNullOrEmpty(userAcctName))
return "--Blank--";
//some lookup to A.D.
DomainUser user = ADLookup.GetUserByAcctName(userAcctName);
if (user == null)
return userAcctName;
//would like to do this correctly!
return string.Format("<a href='/MyAppName/User/View/{0}' title='{2}'>{1}</a>"
, user.Mnemonic, user.DisplayName, user.Location);
//normally returns http://mysite.net/MyAppName/User/View/FOO
}
More info:
using ASP.NET MVC 1.0
I just had to do something similar to this yesterday. There may be a slicker way to do it, but it helps me to see exactly what is going on, so I don't assume anything.
public static string CreateUserLink(this HtmlHelper html, string userAcctName)
{
if (string.IsNullOrEmpty(userAcctName))
return "--Blank--";
//some lookup to A.D.
DomainUser user = ADLookup.GetUserByAcctName(userAcctName);
if (user == null)
return userAcctName;
RouteValueDictionary routeValues = new RouteValueDictionary();
routeValues.Add("controller", "User");
routeValues.Add("action", "View");
routeValues.Add("id", user.Mnemonic);
UrlHelper urlHelper = new UrlHelper(html.ViewContext.RequestContext);
TagBuilder linkTag = new TagBuilder("a");
linkTag.MergeAttribute("href", urlHelper.RouteUrl(routeValues));
linkTag.MergeAttribute("title", user.Location);
linkTag.InnerHtml = user.DisplayName;
return linkTag.ToString(TagRenderMode.Normal);
}
would this work?
public static string CreateUserLink(this HtmlHelper html, string userAcctName)
{
if (string.IsNullOrEmpty(userAcctName))
return "--Blank--";
//some lookup to A.D.
DomainUser user = ADLookup.GetUserByAcctName(userAcctName);
if (user == null)
return userAcctName;
return html.ActionLink(user.DisplayName, "user", "View", new {title=user.Location});
//normally returns http://mysite.net/MyAppName/User/View/FOO
}
My experience with GenerateRouteLink has been an uphill battle. It's been a while since I messed with it but if it's the Method I'm thinking of Microsoft has made it "internal" so you can't access and use it outside the MVC assembly. There are a number of workarounds that I played with and didn't really like.
What I ended up doing to avoid hard coding the url in my helper methods is have it accept a 'string url' parameter and use Url.Action in my view when I call the helper method. It's not the cleanest but it's a workaround that worked well for me.
<%= Html.CreateUserLink("userAcctName", Url.Action("Home", "Controller") %>
I have several pages listing search results, for each result I would like to display I want to create a custom View Helper in order to avoid duplicating the display code.
How do I access the convenient existing view helpers from my custom view helper? I.e. in my custom view helper I would like to use Url.Action(), Html.ActionLink, etc. How do I access them from my custom view helper?
using System;
namespace MvcApp.Helpers
{
public class SearchResultHelper
{
public static string Show(Result result)
{
string str = "";
// producing HTML for search result here
// instead of writing
str += String.Format("{1}", result.id, result.title);
// I would like to use Url.Action, Html.ActionLink, etc. How?
return str;
}
}
}
using System.Web.Mvc gives access to HtmlHelpers, but non of the convenient methods like ActionLink seem to be present.
This example should help you. This helper renders different link text depending on whether the user is logged in or not. It demonstrates the use of ActionLink inside my custom helper:
public static string FooterEditLink(this HtmlHelper helper,
System.Security.Principal.IIdentity user, string loginText, string logoutText)
{
if (user.IsAuthenticated)
return System.Web.Mvc.Html.LinkExtensions.ActionLink(helper, logoutText, "Logout", "Account",
new { returnurl = helper.ViewContext.HttpContext.Request.Url.AbsolutePath }, null);
else
return System.Web.Mvc.Html.LinkExtensions.ActionLink(helper, loginText, "Login", "Account",
new { returnurl = helper.ViewContext.HttpContext.Request.Url.AbsolutePath }, null);
}
EDIT:
All you would need to do to to access the Url.Action() method would be to replace the this HtmlHelper helper param with something like this UrlHelper urlHelp and then just call urlHelp.Action(...
Hope this helps.
A simple gravatar html helpler, your class needs to be static also.
public static string GetGravatarURL(this HtmlHelper helper, string email, string size, string defaultImagePath)
{
return GetGravatarURL(email, size) + string.Format("&default={0}", defaultImagePath);
}
you can extend the default HtmlHelper and UrlHelper just with an extension method (so you have the xxxHelper as first param in your method).
Or you can just create your base view with the method you want and use the Html or URL variable of the view.
In my opinion, you shouldn't be trying to use ActionLink within code. The whole concept of MVC is to separate logic from display, so you should try to stick with that.
I would suggest you pass the result object through to the view (maybe through ViewData) and then parse the result inline within the view. e.g.
<%= Html.ActionLink(result.title,"/showresult/" + result.id, "myController") %>