Passing #Url.Content as parameter in ASP MVC - asp.net-mvc

I am building a custom control in ASP MVC using razor generator. It will take an image as parameter. I want to be able to make the method call in my view like this
#Html.MyMethod(#Url.Content("~/Content/images/photo1.jpg"))
I want to know what is the type of the #Url.Content so that I can declare it in the definition of MyMethod.
Thanks.

You don't need a second # here. Return type of Url.Content is System.String.

MyMethod can take a string as Content returns a string:
public static IHtmlString MyMethod(this HtmlHelper helper, string url)
{
return new MvcHtmlString("<img src=\"" + url + "\" />");
}
Also, you won't need the # operator:
#Html.MyMethod(Url.Content("~/Content/images/photo1.jpg"))

Related

Is there a function similar to Eval() in asp.net razor?

Is there a way by which I can do somethin like this inside a Razor view:
<h1>Normal razor code</h2>
#Html.Action("NormalRazorCode")
#Eval(" #Html.Action(\"RuntimeEval\") ")
Basically a text-to-razor compiler at runtime (that doesnt create a whole new view like RazorEngine does for example).
I think you could assume that the views exist at compile time, and create the actual files at runtime, this way the ViewEngine will work the way it does by default
basically you could create a Html.Eval helper that will create the .cshtml file and after Render it using Html.Action or Html.Partial
I wanted to do something similar; I have model data (under my control) stored in a database, and it would simplify my life if I was able to include HTML helpers in those strings that could be "expanded" when included in a page.
Main motivation was to allow me to re-use existing partial views.
There's no eval function, but you can easily write an extension method that will evaluate methods that you choose to allow in advance. In my case, I want to evaluate calls to #Html.Partial(). The example here is pretty simple - it looks specifically for #Html.Partial("somePartialView") calls and replaces it with the actual partial:
public static IHtmlString ExpandHtmlString(
this HtmlHelper htmlHelper,
String html)
{
if (String.IsNullOrEmpty(html))
return new HtmlString(html);
const String IDENTIFY_PARTIAL = #"#Html.Partial\(""([a-zA-Z0-9\-_]*)""\)";
var partialFinder = new Regex(IDENTIFY_PARTIAL);
var matches = partialFinder.Matches(html);
foreach (Match m in matches) {
var matchedStr = m.Value;
var viewName = m.Groups[1].Value;
var partial = htmlHelper.Partial(viewName);
html = html.Replace(matchedStr, partial.ToHtmlString());
}
return new HtmlString(html);
}
And you call it from your Razor page as so:
#Html.ExpandHtmlString((String)Model.SomeStringField)
You could easily expand on this to to evaluate a set of methods or operators that you decide in advance you will accept.

Get Current View's Url with HtmlHelper in ASP.NET MVC 3

I ask a similar question here I think this is a really easy one (of course not for me). I have a extension method for Html helper and I need to get current view's url with HtmlHelper. Does anyone have any idea about it?
Based on your comment and the original thread you linked to I think you want to use a Url helper to get the URL for the form action, but I could have misunderstood what you wanted:
In a View:
#Url.Action(null) returns the current controller/action
#Url.Action("Action") returns a custom action with current controller
#Url.Action("Action","Controller") returns a custom controller and action
In a HTML Helper:
public static MvcHtmlString MySpecialHelper(this HtmlHelper htmlHelper)
{
UrlHelper urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext,htmlHelper.RouteCollection);
string url = urlHelper.Action("Controller","Action");
//To get the action based on the current Action/Controller use:
url = urlHelper.Action(htmlHelper.ViewData["action"] as string);
//or
url = urlHelper.Action(null);
return new MvcHtmlString(url);
}
if you want to get information about the route information , like the controller or action method that are called
you can access the RouteData dictionary from the ViewContext Object
will be like this
#ViewContext.RouteData.Values["Controller"]
with the RouteData Dictionary you can get all the info needed about the controller , action and extra parameters' name , depending on what you want
If you just want the requested url then you can just get it via the Request.Url object. This returns a Uri, but if you want the raw url then Request.RawUrl.
Necromancing
public static MvcHtmlString MyHelper(this HtmlHelper htmlHelper)
{
var url = htmlHelper.ViewContext.HttpContext.Request.Url;
//more code
}
The OP asked about "extension method for Html helper" - so yeah, this is it.
You could use the Request.RawUrl property or Request.Url.ToString() or Request.Url.AbsoluteUri.
You can use a Html Helper passing the object page as reference, like this:
#helper GoHome(WebViewPage page)
{
}
An in the View just use:
#Links.GoHome(this)

HTML.Encode but preserve line breaks

I take user input into a text area, store it and eventually display it back to the user.
In my View (Razor) I want to do something like this...
#Message.Replace("\n", "</br>")
This doesn't work because Razor Html Encodes by default. This is great but I want my line breaks.
If I do this I get opened up to XSS problems.
#Html.Raw(Message.Replace("\n", "</br>"))
What's the right way to handle this situation?
Use HttpUtility.HtmlEncode then do the replace.
#Html.Raw(HttpUtility.HtmlEncode(Message).Replace("\n", "<br/>"))
If you find yourself using this more than once it may be helpful to wrap it in a custom HtmlHelper like this:
namespace Helpers
{
public static class ExtensionMethods
{
public static IHtmlString PreserveNewLines(this HtmlHelper htmlHelper, string message)
{
return message == null ? null : htmlHelper.Raw(htmlHelper.Encode(message).Replace("\n", "<br/>"));
}
}
}
You'll then be able to use your custom HtmlHelper like this:
#Html.PreserveNewLines(Message)
Keep in mind that you'll need to add a using to your Helpers namespace for the HtmlHelper to be available.
You can encode your message, then display it raw. Something like:
#Html.Raw(Server.HtmlEncode(Message).Replace("\n", "<br/>"))
For those who use AntiXssEncoder.HtmlEncode
As AntiXssEncoder.HtmlEncode encode the /r/n character to
so the statement should be
_mDraftMsgModel.wnItem.Description = AntiXssEncoder.HtmlEncode(draftModel.txtMsgContent, false).Replace("
", "<br/>");
In my case, my string contained html that I wanted to encode but I also wanted the HTML line breaks to remain in place. The code below turns the HTML line breaks in to \n then encodes everything. It then turns all instances of \n back in to HTML line breaks:
#Html.Raw(HttpUtility.HtmlEncode(message.Replace("<br/>", "\n").Replace("<br />", "\n")).Replace("\n", "<br/>"))

How does ASP.Net MVC ActionLink Work?

I am trying to write my own LightWeight MVC for .Net 2.0 using NHaml as the view engine.
In ASP.Net 3.5 MVC the View file we used to specify the link by the code snippet.
Html.ActionLink("Add Product","Add");
In MVC binary there is no function to match this call.
I Only found:
(In class System.Web.Mvc.Html.LinkExtensions )
public static string ActionLink(this System.Web.Mvc.HtmlHelper htmlHelper,
string linkText, string actionName)
There are more similar static classes like FormExtensions, InputExtensions etc.
How does ASP.Net MVC handle it? Does it generates dynamic code for Html.ActionLink?
The ActionLink method is an extension method (hence the this before the type of the first parameter). This means you can use this method as an instance method on all HtmlHelper instances, even though it is not defined on HtmlHelper.
Html is a property on the View of type HtmlHelper. This means you can use the ActionLink extensionmethod on it.
The ActionLink method itself does nothing more than generate a link string (with regards to its arguments) and return that string.
Have you checked out the code on Codeplex? The MVC Framwork is open source, so you can dig around as much as you need to.

Create an ActionLink with HTML elements in the link text

In an ASP.NET MVC view I'd like to include a link of the form:
Link text <span>with further descriptive text</span>
Trying to include the <span> element in the linkText field of a call to Html.ActionLink() ends up with it being encoded (as would be expected).
Are there any recommended ways of achieving this?
You could use Url.Action to build the link for you:
link text <span>with further blablah</span>
or use Html.BuildUrlFromExpression:
text <span>text</span>
if you like using Razor, this should work:
link text <span>with further blablah</span>
Another option is to render your action link to an MvcHtmlString as per normal, using either HTML.ActionLink, or Ajax.ActionLink (depending on your context), then write a class that takes the rendered MvcHtmlString and hacks your html link text directly into the already rendered MvcHtmlString, and returns another MvcHtmlString.
So this is the class that does that: [please note that the insertion/substitution code is VERY simple, and you may need to beef it up to handle more nested html]
namespace Bonk.Framework
{
public class CustomHTML
{
static public MvcHtmlString AddLinkText(MvcHtmlString htmlString, string linkText)
{
string raw = htmlString.ToString();
string left = raw.Substring(0, raw.IndexOf(">") + 1);
string right = raw.Substring(raw.LastIndexOf("<"));
string composed = left + linkText + right;
return new MvcHtmlString(composed);
}
}
}
And then you would use it in the view like this:
#Bonk.Framework.CustomHTML.AddLinkText(Ajax.ActionLink("text to be replaced", "DeleteNotificationCorporateRecipient"), #"Link text <span>with further descriptive text</span>")
This approach has the advantage of not having to reproduce/understand the tag-rendering process.

Resources