ASP.Net MVC view unable to see HtmlHelper extension method - asp.net-mvc

We're going through an ASP.Net MVC book and are having trouble with using an extenstion method within our view. The Extension method looks like this:
using System;
using System.Runtime.CompilerServices;
using System.Web.Mvc;
namespace MvcBookApplication
{
public static class HtmlHelperExtensions
{
public static string JQueryGenerator(this HtmlHelper htmlHelper, string formName, object model);
}
}
We use the extension method in our view like this:
<%=Html.JQueryGenerator("createmessage", ViewData.Model)%>
The problem is, that line of code says JQueryGenerator isn't a recognized method of HtmlHelper. I believe we've got the correct references set in the web project, but are there other things we can check? There's no using statement for views, is there?

Have you added a reference to MvcBookApplication namespace in your web.config ?

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()

Call one Razor helper from another

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.

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.

Creating Html Helper Method - MVC Framework

I am learning MVC from Stephen Walther tutorials on MSDN website. He suggests that we can create Html Helper method.
Say Example
using System;
namespace MvcApplication1.Helpers
{
public class LabelHelper
{
public static string Label(string target, string text)
{
return String.Format("<label for='{0}'>{1}</label>",
target, text);
}
}
}
My Question under which folder do i need to create these class?
View folder or controller folder? or can i place it in App_Code folder?
I would create a subfolder Extensions in which define helper methods:
namespace SomeNamespace
{
public static class HtmlHelperExtensions
{
public static string MyLabel(this HtmlHelper htmlHelper, string target, string text)
{
var builder = new TagBuilder("label");
builder.Attributes.Add("for", target);
builder.SetInnerText(text);
return builder.ToString();
}
}
}
In your view you need to reference the namespace and use the extension method:
<%# Import Namespace="SomeNamespace" %>
<%= Html.MyLabel("abc", "some text") %>
You can place it wherever you like. The important thing is that it make sense to you (and everyone working on the project). Personally I keep my helpers at this path: /App/Extensions/.
Place it in the app code. However, ASP.NET MVC 2 already has the Label functionality.
You could put in the Models folder, or App_Code (not sure what kinds of support is in MVC for that); it would be best to have in a separate library. Also, html helper extensions are extension methods that must start with the this HtmlHelper html parameter like:
public static class LabelHelper
{
public static string Label(this HtmlHelper html, string target, string text)
{
return String.Format("<label for='{0}'>{1}</label>",
target, text);
}
}
EDIT: You can reference this within the namespace by adding it to the:
<pages>
<namespaces>
Element within the configuration file too, that way you define the namespace once, and it's referenced everywhere.

ASP.NET MVC Programmatically Get a List of Controllers

In ASP.NET MVC is there a way to enumerate the controllers through code and get their name?
example:
AccountController
HomeController
PersonController
would give me a list such as:
Account, Home, Person
Using Jon's suggestion of reflecting through the assembly, here is a snippet you may find useful:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
public class MvcHelper
{
private static List<Type> GetSubClasses<T>()
{
return Assembly.GetCallingAssembly().GetTypes().Where(
type => type.IsSubclassOf(typeof(T))).ToList();
}
public List<string> GetControllerNames()
{
List<string> controllerNames = new List<string>();
GetSubClasses<Controller>().ForEach(
type => controllerNames.Add(type.Name));
return controllerNames;
}
}
You can reflect through your assembly and find all classes which inherit from type System.Web.MVC.Controller. Here's some sample code that shows how you could do that:
http://mvcsitemap.codeplex.com/WorkItem/View.aspx?WorkItemId=1567
All who using this post better read this post before: using Assembly.GetCallingAssembly() not returns the calling assembly
The issue is that razor views are acting as independent dynamic assemblies and you don't get the desired assembly.
Yair
Create the property in every controller and then you get the name like this.

Resources