HTML in MVC RouteLink - asp.net-mvc

I have a RouteLink constructed like so
<p class="articleLink">
#MvcHelper.Html.RouteLink(article.Title, "Article_Route", new RouteValueDictionary() { { "articleId", article.Id }, { "seoUrl", article.SeoUrl } }))
</p>
However, article.Title could potentially contain HTML i.e. the value could be <em>Sample</em> Title which in turn gets rendered like so
<em>Sample</em> Title
Is there any way to prevent the HTML from being escaped, and instead to be treated as actual HTML? Or do I need to create a standard HTML <a href... link in this case (thus losing all the niceties associated with the RouteLink helper).

If you want HTML inside your anchor don't use the Html.RouteLink (because it will HTML encode the link text by default as you noticed) instead of build your a tag by hand with using Url.RouteUrl to generate the url:
<p class="articleLink">
<a href="#(Url.RouteUrl("Article_Route",
new RouteValueDictionary()
{ { "articleId", article.Id },
{ "seoUrl", article.SeoUrl } }))">
#Html.Raw(article.Title)
</a>
</p>
Or you can create your own non encoding RouteLink helper.

You can use HtmlHelper.Raw(). Having said that, it is probably not a good idea to keep any HTML in your model/view model, which is against the principle of separation of model and presentation, also a security hazard.

Related

Trying to convert this Html.Action Code to Html.ActionLink

I am using MVC3, ASP.NET4.5 and Razor.
I have some Html.Action Code, and would ideally like to convert it to Html.ActionLink as I am thinking of using a security extension function that has been written for ActionLinks.
My code is:
<span class="fa fa-pencil ss-prime ss-cmd" title="Edit Order"></span>
Can this be implemented using an ActionLink?
The "fa fa-pencil" code is a webfont, and I need this.
Thanks in advance
If you use an action link, you may need to modify your styles slightly:
Html.ActionLink("edit order", "Edit", "Order"
, new { id= 1 }
, new { #class="fa fa-pencil" }) // <-- html attributes
This will create an a href, but attach the css styles to the a tag, not the span.
<a class="fa fa-pencil" href="/Order/Edit/1">edit order</a>

Pass a parameter into partial view to use as query string name in action link?

I am trying to make this code a partial view to add alpha paging to my grids:
<div class="t-pager-wrapper" style="border-bottom:0">
<div class="t-pager t-reset">
#foreach (var letter in CollectionUtil.Alphabet){
#Html.ActionLink(letter, "Index", new { Equipment_filter = "Equipment.Name~startswith~'" + letter + "'" }, new { #class = "t-link" })
}
#Html.ActionLink("All", "Index")
</div>
</div>
How can I pass in the name "Equipment" to use as the parameter in the query string? All of my grids have their own name for their data, so in order for the paging filter to work it would be different on each page, Equipment_filter, Color_filter, Cars_filter, etc.
So example URLs would be:
http://www.mydomain.com/Equipment?Equipment-filter=Equipment.Name~startswith~'B'
http://www.mydomain.com/Color?Color-filter=Color.Name~startswith~'C'
So I would need to have parameters to pass into the partial being "Equipment" for the filter prefix, and "Equipment.Name" for the path to make the object property comparison with.
EDIT:
Well I did this by just using Url.Action inside the href parameter of a link instead:
#letter
At which point supplying "Equipment" and "Equipment.Name" are trivial since everything is a string. If someone wants to post a solution using ActionLink I will mark that as the answer though.
Well I did this by just using Url.Action inside the href parameter of a link instead:
#letter
At which point supplying "Equipment" and "Equipment.Name" are trivial since everything is a string.

How to avoid default URL encoding in ASP.NET MVC Html Helpers like RouteLink

I want my url like this:
"http://domain.com/tag/高兴"
My route mapping:
routes.MapRoute("Tag", "tag/{name}", new { controller = "Tag", action="Index" });
But Html.RouteLink will encode the parameters as default. If I use Html.RouteLink in my View, the generated html is:
高兴
Is there any way to avoid this?
Changed my example.
This works in my case
<%= HttpUtility.UrlDecode(Html.RouteLink("Test", new { id = "高兴" }).ToString())%>
Make sure to change from <%: to <%=

Dynamic RadEditor Creation through HtmlHelper

I am using the Telerik RadEditor (Q1 2009 SP1) in our ASP.NET MVC (RTM) project. The editor works great when rendered as a hardcoded object on the page with a static id. But when extending with an HtmlHelper to do dynamic creation by passing in an Id it seems to render the html as all lowercase for the tag. Does the HtmlHelper object mess with this innately by chance? The attributes look upper and lowercase respectively but this seems strange. Here is my code....thanks in advance!
<% if (placeholder.Type.ToLower() == "richtext") { %>
<%= Html.RadEditor("placeholder_" + placeholder.Name) %>
<% } else { %>
<%= Html.TextBox("placeholder_" + placeholder.Name, null, new { #class = placeholder.Type }) %>
<% } %>
The helper looks like this....
public static string RadEditor(this HtmlHelper html, string Id)
{
var sb = new StringBuilder();
sb.Append("<telerik:RadEditor ID='" + Id + "' Runat='server' DialogHandlerUrl='~/Telerik.Web.UI.DialogHandler.axd'>");
sb.Append("<Content>");
sb.Append("</Content>");
sb.Append("</telerik:RadEditor>");
return sb.ToString();
}
For the time being you cannot render RadEditor without having a valid Page object with a ScriptManager. We (Telerik that is) plan to add support for "standalone" rendering in the near future. Should be announced in a blog post so stay tuned.
The problem is the tag is a server side control. When you place it hardcoded in your page, the server side tag gets translated to html. When you're using the htmlhelper, you're outputting the html and it doesn't get processed as a server side tag.
If you want to do something dynamic, you should use a UserControl (.ascx file) and then use the Html.RenderPartial method.

ASP.NET MVC - Getting Html.BeginForm() to remember Querystring params when submitting via GET

I have a form rendered via Html.BeginForm(), it exists as a component in the Master page so that it appears on every page in the application. I have done this using Html.RenderAction() from Mvc Futures assembly. It's a simple search form that updates some items in the same component underneigh the search form itself, and performs a GET so that the search term appears in the querystring.
<div class="sideBarContent">
<h2>Search Products</h2>
<% using (Html.BeginForm(ViewContext.RouteData.Values["action"].ToString(),
ViewContext.RouteData.Values["controller"].ToString(), FormMethod.Get)) { %>
<fieldset>
<legend>Search Products</legend>
<div class="formRow">
<label for="ProductsSearch">Search</label>
<%= Html.TextBox("ProductsSearch") %>
</div>
<input type="submit" value="Search" class="button" />
</fieldset>
<% } %>
<ul>
// Products will eventually be listed here
</ul>
</div>
I need this form to do the following:
1) It should perform a GET to whatever current page it is on appending 'ProductsSearch' as a querystring parameter (eg. example.com/?ProductsSearch=test or example.com/books/fiction?ProductsSearch=test)
2) It should remember any exising querystring parameters that are already in the querystring, maintaining them after you click Search button eg. example.com/myOrders?page=2 after Search click it should go to example.com/myOrders?page=2&ProductsSearch=test)
I can get it to do 1) but can't work out 2).
I relise that normally for a from to GET and appending querystring params it needs to have hidden form fields, so I could write a utility function that automatically adds a bunch of hidden form fields for any querystring values, but I wanted to check that there's wasn't an easier approach, or maybe I'm going about it the wrong way.
Cheers!
You'll need to do the hidden form field method.
Even if you could attach the entire querystring to the end of the URL in the action attribute of the <form> tag, browsers don't pay attention to this when doing GET form submissions.
Your method isn't too difficult; you'd want to do something like this:
public static string QueryStringAsHidden(this HtmlHelper helper)
{
var sb = new StringBuilder();
foreach (var key in HttpContext.Current.Request.QueryString.AllKeys)
{
if (! key.StartsWith("ProductSearch"))
sb.Append(helper.Hidden(key, HttpContext.Current.Request.QueryString[key]));
}
return sb.ToString();
}
I put the .StartsWith() in there because you don't want to be on a search page and submit the search string twice (and now you can prepend paging and other search-specific variables with ProductSearch.
Edit: PS: To get the form to post to the current page, you don't have to explicitly provide action and controller -- you can also send nulls.
Edit2: Why even bother with a helper method? :)
<% HttpContext.Current.Request.QueryString.AllKeys.Where(k => !k.StartsWith("ProductSearch")).ToList().ForEach(k => Response.Write(Html.Hidden(k, HttpContext.Current.Request.QueryString[k]))); %>
James
A direct to call BeginForm() does keep your query string values. Any other overload tends to fail. I love the ease of using BeginForm() from my forms, but needed a way to class all my styled forms a certain way an not lose the query string values in the action.
Here is what I came up with:
public static MvcForm BeginNormalForm<T>(this HtmlHelper<T> htmlHelper)
{
var dictionary = new Dictionary<string, object> {{"class", "normal"}};
var rvd = new RouteValueDictionary();
if (htmlHelper.ViewContext.HttpContext != null && htmlHelper.ViewContext.HttpContext.Request != null)
{
foreach (var key in htmlHelper.ViewContext.HttpContext.Request.QueryString.AllKeys)
{
rvd[key] = htmlHelper.ViewContext.HttpContext.Request.QueryString[key];
}
}
var form = htmlHelper.BeginForm(null, null, rvd, FormMethod.Post, dictionary);
return form;
}
Seems to work well and keeps my class attribute.
Use one of the overloads of BeginForm that takes a routeValues object or dictionary.
Additional properties not in the route will be added as query parameters.

Resources