Razor to talk to class function? - c#

I am trying to add social networking buttons to my site and have build a socialNetworkingHelper class.
I would like to know what i need to do to get the view to see the helper class.
I followed the following link to get where i am now.
http://www.advancesharp.com/Blog/1033/add-facebook-twitter-and-google-plus-in-c-mvc-application
I am using MVC 4 and have placed this div in my layout page in my footer.
<div>
#Html.SocialLinkButtons(Model.Title, Request.Url.ToString())
</div>
The SocialLinkButtons text is underlined in red with the following error message.
'System.Web.Mvc.HtmlHelper' does not contain a definition for
'SocialLinkButtons' and no extension method 'SocialLinkButtons'
accepting a first argument of type
'System.Web.Mvc.HtmlHelper' could be found (are you missing
a using directive or an assembly reference?)
Is there somthing i must add to my view to allow the #html to call my socialLinkButtons?
Or is there something i need to add to my class to allow this?
I have tried placing my class in the contoller folder and the models folder and just plain in the whole project. Where should this helper class be kept?
To see the class please follow the link placed above.
Edit:
Following the answers below the SocialLinkButtons text is no longer underlined but when i run my code i get the following error.
'System.Web.Mvc.HtmlHelper' has no applicable method named
'SocialLinkButtons' but appears to have an extension method by that
name. Extension methods cannot be dynamically dispatched. Consider
casting the dynamic arguments or calling the extension method without
the extension method syntax.

You shoud to put code from link in any namespace:
namespace Helpers {
public static class SocialNetworkingHelper {
...
}
}
and add using directive in your view:
#using Helpers

Probably you extension method SocialLinkButtons is not visible in the view.
You should add #using MyNamespace directive in the view where MyNamespace is actual namespace of your extension method SocialLinkButtons or youcan achieve the same thing via web.config by adding this namespace to
<system.web.webPages.razor>
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Collections" />
<add namespace="MyNamespace" />
</namespaces>
</pages>
</system.web.webPages.razor>

Related

Custom Razor #helpers in MVC5 areas

I have a MVC project which consists of several areas.
I would like to write custom Razor #helper which would be shared just within views inside specific area. Common aproach is to write helpers in .cshtml files stored in App_Code folder in project root, but this makes those helpers accessible from multiple areas.
Is there any way to keep razor #helper separated just for one area?
Razor helpers are "public static" methods inside "public static" classes, they are therefore potentially useful for all views, regardless of areas.
You don't have to put them.in app code. You can create a class and add your static extension methods. If you want to only see them for certain views, create them in a different namespace and add a using to your view.
A custom helper to work, you must declare at beginning of your view, or you can register in your web.config, inside your views folder. For example:
My custom helper is:
namespace MyCustomSystem.Web.Helpers
{
public static class CustomHelpers
{
public static MvcHtmlString GroupedActionButtons(this HtmlHelper helper, string controller, long id)
{
var stringBuilder = new StringBuilder();
//Do your logic here.
return MvcHtmlString.Create(stringBuilder.ToString());
}
}
}
In your web.config:
<system.web.webPages.razor>
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="MyCustomSystem.Web" />
<add namespace="MyCustomSystem.Web.Helpers" />
</namespaces>
</pages>
</system.web.webPages.razor>
Doing this, only areas that has the Helper registered, will work, and you not need to declare a using in your Views.

use namspace within a <script runat="server"> block

I want to use Dictinoary class within a <script runat="server"> block(aspx.cs).Whenever I tried to use that class, it showing The type or namespace name 'Dictionary' could not be found (are you missing a using directive or an assembly reference?) Exception.
How to use Using System.Collections.Generic within a <script runat="server"> block.I don't want to use this namespace in .cs file.
Use the fully qualified name:
System.Collections.Generic.Dictionary<object,object> objName=new System.Collections.Generic.Dictionary<object,object>();
Now, change the parameters, as you wish.
If it still gives you a error, then, there is something else which is throwing that error and not this.
Hi thanks for your answers.
Finally I found solution.
The solution is
you have to insert the required namespace in the web.config file. Then only you can access the namespace within inline server tag, not by using "using" statement. I have added like this:
</assemblies>
</compilation>
<pages>
<namespaces>
<add namespace="System.Collections.Generic"/>
<add namespace="System.Data"/>
<add namespace="System.Configuration"/>
<add namespace="System.Data.OracleClient"/>
<add namespace="System.Resources"/>
<add namespace="System.Globalization"/>
</namespaces>
</pages>

Implicit namespace and service reference

I've got a service reference of type ServiceReference in the namespace MyNamespace, containing some data classes' definitions. That leads to the following syntax in my CSHTML file.
#foreach(MyNamespace.ServiceReference.MyDataType blopp in ViewBag.Blopps) ...
This is less than convenient and I'd like to be able to go like this, instead.
#foreach(MyDataType blopp in ViewBag.Blopps) ...
In a CS file, I'd apply using for this but what's recommended approach for the CSHTML file?
EDIT
Of course, besides #using MyNamespace.ServiceReference; :)
Use:
#using MyNamespace.ServiceReference
EDIT:
Since in your edited question you specified, besides #using, you can add the references in web.config file but they will be available for all the views.
<system.web.webPages.razor>
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<!-- Add following with others -->
<add namespace="MyNamespace.ServiceReference" />
</namespaces>
</pages>
</system.web.webPages.razor>

Using MVC HtmlHelper extension method in a View within an Area

I have an HtmlHelper extension method that pulls in localized text from a database cache. The code is like this. (MVCWeb is the namespace of my MVC app.)
using System.Web;
using System.Web.Mvc;
namespace MVCWeb.PresentationExtensions
{
public static class HtmlHelperExtensions
{
public static HtmlString GetText(this HtmlHelper Html, string keyword)
{
// code to get the text based on the keyword
}
}
}
I am using #using MVCWeb.PresentationExtensions in my Views. In ~/Views folder, calling the extension method is working perfectly.
I recently added an Area. I am using the extension method in the View files in the ~/Areas/AreaName/Views folder, and the code is compiling and it does work, however I am getting errors in the IDE.
Every time I use #Html.GetText("SomeKeyword") from within the Area view, the following two errors are displayed on the errors list.
'System.Web.WebPages.Html.HtmlHelper' does not contain a definition for 'GetText' and the best extension method overload 'MVCWeb.PresenationExtension.HtmlHelperExtensions.GetText(System.Web.Mvc.HtmlHelper, string)' has some invalid arguments
Instance argument: cannot convert from 'System.Web.WebPages.Html.HtmlHelper' to 'System.Web.Mvc.HtmlHelper'
I've figured out that in ~/Views, #Html has the following code comments:
HtmlHelper<dynamic> WebViewPage<dynamic>.Html
Gets or sets the System.Web.Mvc.HtmlHelper object that is used to render HTML elements.
In ~/Area/AreaName/Views, #Html has these comments:
HtmlHelper WebPage.Html
Gets the System.Web.WebPages.Html.HtmlHelper object that is associated with a page.
For reference, my Web.config files in ~/Views and ~/Areas/AreaName/Views match. This is an MVC4 app on .NET 4.5 and hasn't been converted from a previous version of MVC.
Is it normal that #Html is defined as different types in the regular Views vs area Views?
Why is this compiling and running correctly if the IDE is showing errors? Is this an IDE bug?
How can I stop these errors from showing in the IDE?
it runs fine because your web.config contains the correct reference and it matches up at runtime correctly.
it's just an ide bug for areas. To get rid of it you can specify it as an include at the top of your view using #include which will give intellisense a helping hand.
I've just run into the same issue trying to add an MvcSiteMap helper to a View in an Area.
The problem was that the NuGet package added its namespaces to the Web.Config files at the root and Views level but unsurprisingly wasn't smart enough to go looking for the ones buried in the Areas/area_name/Views folders. The solution was just to add the namespaces e.g.
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization" />
<add namespace="System.Web.Routing" />
<add namespace="FarmingtonCo.CacPortalWeb" />
<add namespace="MvcSiteMapProvider.Web.Html" />
<add namespace="MvcSiteMapProvider.Web.Html.Models" />
</namespaces>
</pages>

Using enum in #Url.Action() routevalues

This question is just a quick one. I have a set of links on a page, and they all actually point to the same controller method - the difference between them is that they each pass a different value to that method so that the subsequent process is slightly different. I happened to already have an enum defined to correspond to the possible values passed, so without thinking, I did this:
#Url.Action("QueryStepTwo", new { type = QueryType.UserRecords })
and was pleasantly surprised to see that nothing gained a red underline. I hit compile and navigated to that page to verify, to be presented with an error message for CS0103: "The name 'QueryType' does not exist in the current context". In the editor, QueryType is syntax-highlighted and IntelliSense provides the options list when I type it.
I'm assuming this is just a case of VS/IntelliSense being just a little bit too smart and knowing things that the actual page parse/render engine can't? Casting the enum to its string or int value doesn't help, so I'm guessing this is to do with the order in which things are executed; more specifically, the enum is out of scope by the time Razor gets to see the page. Is there a way to use an enum in URL helpers like this, especially one that doesn't require the enum to be defined as a member of the view model? I dislike using magic strings all over the place; they're too vulnerable to typos and tomfoolery.
Make sure you fully qualify the namespace where this enum is defined:
#Url.Action("QueryStepTwo", new { type = SomeNamespace.QueryType.UserRecords })
or if you don't want to do that you could also add an #using directive to the top of your Razor view:
#using SomeNamespace
And if you want to do this globally for all Razor views you could add this namespace to the <namespaces> node in ~/Views/web.config (not to be confused with ~/web.config):
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="SomeNamespace" />
</namespaces>
</pages>
</system.web.webPages.razor>
As far as the Intellisense in Razor views is concerned, this is not something that could be trusted. Hopefully Microsoft will improve it in future versions.

Categories

Resources