Call one Razor helper from another - asp.net-mvc

I need to create the second overload of Razor helper and want to call one helper from another (with some specific parameters). Is there any way to implement it?

Sure:
using System.Web.Mvc;
using System.Web.Mvc.Html;
public static class ActionLinkExtensions
{
public static IHtmlString MyActionLink(this HtmlHelper html)
{
// call the base ActionLink helper:
return html.ActionLink("some text", "someAction");
}
}
and then in your view:
#Html.MyActionLink()
If you are talking about #helper Razor helpers you need to pass an instance of the HtmlHelper as argument because it is not available in the helper context:
#helper MyActionLink(HtmlHelper html)
{
#html.ActionLink("some text", "someAction")
}
and then:
#MyActionLink(Html)
Personally I prefer the first approach as it is view engine agnostic and can be ported across any other view engines you like whereas the second is Razor specific and if tomorrow Microsoft invent the Blade view engine you will have to rewrite much of your code.

Related

How do I create something similar to the HTMLHelper namespace for the business name?

I would like to create something that can be called into any view in a website like this
#MyBusinessName.TelephoneNumber
#MyBusinessName.Address
etc...
In the same way I would call a HtmlHelper
#Html.ActionLink()
How do I add a namespace like "MyBusinessName" for use in an MVC view?
Html in Razor pages is a property of the class that pages inherit from, so of course you can't implement what you want in the same way as the standard HTML helper works. But I can suggest a different solution.
You may define a static class in your project that will work as your own helper (define there static methods/properties you want to use in views). I'd suggest something like the following:
using System.Web.Mvc;
namespace YourProject.Infrastructure {
public static class YourBusinessHelper {
public static MvcHtmlString TextBox(string name) {
string html = string.Format("<input name=\"{0}\" />", name);
return new MvcHtmlString(html);
}
// ...
}
}
System.Web.Mvc.MvcHtmlString is a class representing HTML markup that an HTML helper method inserts into the view where it is used. You may create it using a constructor that receives a string parameter containing the needed HTML markup — like in my code.
Now you can use this class in your views. You just need to import the containing namespace with this Razor instruction:
#using YourProject.Infrastructure
I'd suggest to put it into the view start file (_ViewStart.cshtml) so that it applies to all your views.
The sample helper method above can be used simply:
#YourBusinessHelper.TextBox("TextBoxName")
UPDATE: you may also create an extension method for HtmlHelper:
using System.Web.Mvc;
namespace YourProject.Infrastructure {
public static class YourBusinessHelper {
public static string CompanyPhoneNumber(this HtmlHelper helper) {
return "+82649256720";
}
// ...
}
}
You may use string not MvcHtmlString in helper methods if they return plain text (no HTML markup).
Use it like a built-in helper method:
#:Call us: #Html.CompanyPhoneNumber()

How to use HtmlHelper from App_Data to view in MVC3

I have create a simple HtmlHelper class in my MVC3 application and put it in "App_Data\PriceHelper.cshtml"
code in PriceHelper,cshtml
#helper DisplayPrice(double price)
{
#String.Format("{0:N}",price)
}
when i am tried to use this helper in my view at that time it not allow me to use #PriceHelper.DisplayPrice().
but if i put hepler method on same view then it work.
please let me know how can use HtmlHelper from App_Data to my view?
The Razor helpers can be reused when they are stored in App_Code folder not App_Data.
You can find more details here: ASP.NET MVC 3 and the #helper syntax within Razor
App_Data is intended for data resources (xml, text, db files) not code. Use another folder for this, e.g. Views/Shared.
My choice would be to create an HTML helper (and put it in the model):
public static class HtmlHelpers
{
public static string DisplayPrice(this HtmlHelper helper, double price)
{
return String.Format("{0:N}", price);
}
}
used like this in a view:
#Html.DisplayPrice(10)

ASP.NET MVC - Converting a complex control to be MVC-friendly

I have an ASP.NET WebForms control (derived from Control, not WebControl, if it helps) that has a rather complicated Render() function. The control has no viewstate and only uses the Control approach so it can render output directly. I feel it's a fine candidate for working with the MVC approach.
I'd like to use it in an MVC application I'm using, however I don't know what's the best way to go about it.
At first I thought about converting it to a HTML Helper method, but my control renders a large amount of HTML so the Helper method (with it returning strings) isn't too attractive.
The alternative is a PartialView, but those are UserControl derivatives, which wouldn't be appropriate in this case.
I see other HTML Helper methods don't return HtmlString, but actually use HtmlHelper.ViewContext.Writer to write output directly, but according to this question ( HtmlHelper using ViewContext.Writer not rendering correctly ) he was getting strange results. I'd like to avoid that mishap.
EDIT:
I think I've solved it using the HtmlHelper.ViewContext.Writer approach, and I haven't experienced the same problem as the problem I quoted.
Here's the code I wrote:
public static class MiniViewHelper {
public static void RenderMiniView<TModel>(this HtmlHelper html, MiniView<TModel> view, TModel model) {
TextWriter wtr = html.ViewContext.Writer;
HtmlTextWriter hwtr = wtr as HtmlTextWriter;
if( hwtr == null ) hwtr = new HtmlTextWriter( wtr );
view.Render( hwtr );
}
}
public abstract class MiniView<TModel> {
public TModel Model { get; set; }
public abstract void Render(HtmlTextWriter wtr);
}
public class VeryComplicatedMiniView : MiniView<ComplicatedViewModel> {
public override void Render(HtmlTextWriter wtr) {
wtr.WriteLine("VeryComplicatedMiniView ");
}
}
Used like so from my pages:
<% Html.RenderMiniView( new VeryComplicatedMiniView () { Propery1 = foo }, Model.RelevantMiniViewModel ); %>
Any thoughts?
The two approaches you have outlined in your question are correct. You could either try to write a custom HTML helper which will spit the same HTML as the control or use a partial.
I see other HTML Helper methods don't return HtmlString, but actually
use HtmlHelper.ViewContext.Writer to write output directly
ViewContext.Writer should be fine. Returning an IHtmlString from the helper is also fine. Just make sure you are properly encoding it inside since IHtmlString will not be automatically HTML encoded in Razor and it supposes that the helper takes care of this. Using a TagBuilder to generate a DOM tree in a helper is a good approach.

ASP MVC Razor view extension methods, how to create 'global' view methods?

I am using Razor view with asp mvc preview 3
I am trying to create some methods which I would like available directly in the views. These are not really Html helper methods so I don't think extending HtmlHelper makes sense?
my goal, be able to call methods in the view i.e.
#HelloWorld(); vs #Html.HelloWorld()
I can get Html.HelloWorld to work by creating an extension method on HtmlHelper
public static class HtmlExtensions
{
public static string HelloWorld(this HtmlHelper helper)
{
return "Hello";
}
}
I would like to do the same thing but for the view; my problem - what type of object is the view?
Note: I was able to get this to work by defining the methods in the .cshtml page
#functions
{
public string HelloWorld()
{
return "Hello";
}
}
#HelloWorld() #* now this works *#
then I tried to put this code my _viewstart.cshtml file thinking it would be available in all views but it was not
if I knew which type the view was I think it could be easily extended, any help appreciated
As remarked by others, Razor Views all ultimately inherit from WebViewPage:
public abstract class WebViewPage<TModel> : WebViewPage
You can therefore simply write your extension methods for WebViewPage without creating a new base class or changing the config files, which has been suggested by other answers. For example:
public static class WebViewPageExtensions
{
public static string HollowWorld(this WebViewPage wvp)
{
return "Memento mori";
}
}
Add a using statement for that namespace to your View and then:
<p>#this.HollowWorld()</p>
it turns out, the asp runtime is going to define the Execute method at runtime, so the custom view base class must also be abstract
using System;
using System.Web.Mvc;
namespace MyMvcWebApp.Extensions
{
public abstract class ViewBase<TModel>
: System.Web.Mvc.WebViewPage<TModel> where TModel : class
{
// now this will be available in any view #HelloWorld()
public string HelloWorld()
{
return "Hello from the ViewBase class";
}
}
}
this should work with strongly typed views, it looks like with razor all views are strongly typed, when you do not define the type 'dynamic' is used and that is the strong type
also, as Clicktricity stated you then update the web.config (the one under the Views directory)
<pages pageBaseType="MyMvcWebApp.Extensions.ViewBase">
The default base class for Razor views is specified in the Web.config located in the views directory. Usually it is:
<pages pageBaseType="System.Web.Mvc.WebViewPage">
I've not tried it, but I would suggest inheriting from this base class and adding your own functionality, then adjust the web.config accordingly.
The best way to call a method with arguments using razor engine is to use helpers.
Example: let you have a helper #MakeNote(string content)
Then in cshtml page you just need to call #MakeNote("Hi") and you should be fine.
I was going crazy when I was having problem then google sent me to this page but it did not help. I was trying to load content in html <select> with L2E using razor.
The secret is to create a helper in app_code then use with cshtml.

ASP.NET MVC Using Render Partial from Within an Html Helper

I have an HtmlHelper extension that currently returns a string using a string builder and a fair amount of complex logic. I now want to add something extra to it that is taken from a render partial call, something like this ...
public static string MyHelper(this HtmlHelper helper)
{
StringBuilder builder = new StringBuilder();
builder.Append("Hi There");
builder.Append(RenderPartial("MyPartialView"));
builder.Append("Bye!");
return builder.ToString();
}
Now of course RenderPartial renders directly to the response so this doesn;t work and I've tried several solutions for rendering partials to strings but the all seem to fall over one I use the HtmlHelper within that partial.
Is this possible?
Because this question, although old and marked answered, showed up in google, I'm going to give a different answer.
In asp.net mvc 2 and 3, there's an Html.Partial(...) method that works like RenderPartial but returns the partial view as a string instead of rendering it directly.
Your example thus becomes:
//using System.Web.Mvc.Html;
public static string MyHelper(this HtmlHelper helper)
{
StringBuilder builder = new StringBuilder();
builder.Append("Hi There");
builder.Append(helper.Partial("MyPartialView"));
builder.Append("Bye!");
return builder.ToString();
}
I found the accepted answer printed out the viewable HTML on the page in ASP.NET MVC5 with for example:
#Html.ShowSomething(Model.MySubModel, "some text")
So I found the way to render it properly was to return an MvcHtmlString:
public static MvcHtmlString ShowSomething(this HtmlHelper helper,
MySubModel subModel, string someText)
{
StringBuilder sb = new StringBuilder(someText);
sb.Append(helper.Partial("_SomeOtherPartialView", subModel);
return new MvcHtmlString(sb.ToString());
}
You shouldn't be calling partials from a helper. Helpers "help" your views, and not much else. Check out the RenderAction method from MVCContrib (if you need it now) or MVC v2 (if you can wait a few more months). You'd be able to pass your model to a standard controller action and get back a partial result.

Resources