I'm not talking about javascript functions, but server side functions written in c#.
For the html table in my view, I'm creating table headers that act like sortable columns. But the sortability depends on a complex logic so I want to put the logic into a function instead of writring it for each column.
#Amr ElGarhy
Thank you for suggesting customer helper, but the helper class I create is not being regonizied.
Helper Code:
namespace MyHtmlHelpers
{
public static class CustomHelpers
{
public static string MySortColumn(this HtmlHelper helper, string label, string col, string dir, UrlHelper url)
{
return string.Empty;
}
}
}
web.config:
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<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.Web.WebPages"/>
<add namespace="MyHtmlHelpers"/>
</namespaces>
</pages>
But in View, neither #HtmlHelper.MySortColumn nor #Html.MySortColumn is regonized. Am I missing something here? I even restarted my pc.
UPDATE
adding namespace in web.config didn't work for me. adding in View page works.
I think you need to take a look at HTML Helpers and how to create a custom one:
http://www.asp.net/mvc/tutorials/creating-custom-html-helpers-cs
http://www.asp.net/mvc/videos/how-do-i-create-a-custom-html-helper-for-an-mvc-application
Try this
helper syntax
It's better to create base class with the logic and derive your views from this class. Normally you shouldn't reveal/share any methods to reuse between views.
Are you using areas? Areas have their own view folder and usually have their own web.config. If that's the case, you can try to add namespace to that web.config.
Also, web.config files are resolved hierarchically through folders. It means you can have web.config in your base Area directory which affects all area specific views.
In my case, I have two web.config files where I add my namespaces - one is in View directory and other one in Area directory.
Related
I have an MVC application which I am deploying out to a staging server using Team City. I have created a Web.Staging.config transform to handle the different database connection, certificates and service calls.
On this staging server I have had a request to have the title of the Index view to read "TEST SYSTEM" and to have a different colour scheme to signify, at a glance that the user is on the test system.
So far I have handled this by changing the view on the file system in notepad, and swapping the bootstrap.css file to one with a different theme however every time I do a new commit/deploy these changes are wiped and its becoming tiresome.
Is there anyway to handle CSS/view changes per server by using a similar transform system as employed to handle the web.config
There's not really an easy way to transform CSS files like that, but what you could do is have your master CSS file link in your config file, so your view would be something like:
<link href='#ConfigurationManager.AppSettings["MainCSS"]'>
Then your web.Debug (and other transformations) could point to the correct path:
<add key="MainCSS" value="/Content/Site.css" />
And your web.Staging config could point to another:
<add key="MainCSS" value="/Content/Staging/Site.css" />
You can also apply the above logic for your Index view:
public ActionResult Index()
{
string viewName = ConfigurationManager.AppSettings["MainView"];
return View(viewName);
}
Then have in your web.Debug (and others):
<add key="MainView" value="Index" />
And in your web.Staging:
<add key="MainView" value="IndexStaging" />
One solution could be to add a key to the web.config and read it using the WebConfigurationManager.AppSettings. Those settings can be transformed. In your view you can check this setting if you need to change the title and if you need to load an additional css file.
In your web.config:
<appSettings>
<add key="IsTestSystem" value="False" />
</appSettings>
and in as transform:
<appSettings>
<add key="IsTestSystem" value="True" xdt:Locator="Match(key)" xdt:Transform="SetAttributes"/>
</appSettings>
In your view / layout:
if (Boolean.TryParse(WebConfigurationManager.AppSettings["IsTestSystem"] ?? "False", out run)) {
// include css file for test system or modify the title
}
And, if you want, you can just switch between the two bootstrap.css files.
The MvcReCaptcha library looks very solid, and appears to have some good developer adoption, but when I tried it for the first time today, using the supplied HTML helper, my app won't run. I have the helper in a partial view as follows:
<fieldset>
<legend>3. Verify that you are a human.</legend>
#Html.GenerateCaptcha()
</fieldset>
I have the namespace included in web.config as instructed:
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="MvcReCaptcha.Helpers"/>
</namespaces>
</pages>
(Other namespaces removed for brevity)
And I have my private and public keys defined in appSettings. I can see no way that I deviate from the examples on the CodePlex page except that I am using Razor. Can anyone offer some insight into what I may be doing wrong?
If you are using Razor you need to add the MvcReCaptcha.Helpers namespace to the <namespaces> section of ~/Views/web.config file and not the one in ~/web.config.
I've got a custom menu navigation built from a web.sitemap file, the first line of this would be something like:
SiteMapNodeCollection topLevelNodes = SiteMap.RootNode.ChildNodes;
This works - it gets all the top level nodes from the web.sitemap file, and allows me to look through each SiteMapNode and do stuff.
However, now I want to be able to create multiple web.sitemap files, and then programmatically determine which web.sitemap file to use, but I can't seem to find out how to do this. I'm assuming I could either create one custom SiteMapProvider that can perform the logic to determine which web.sitemap file to load, or I have multiple providers, each one with the SiteMapFile property set to a specific *.sitemap file, and then switch providers programmatically before I access SiteMap.RootNode.
I think it's probably easier to have one custom provider, and then override the part where it looks for the actual physical sitemap file location, but I'm unclear how I would do this
I've googled a lot, but most answers seem to be regarding the standard sitemappath controls and so on, and how to set a SiteMapDataSource, which I don't think is relevant to my approach.
First you need to specify all of your sitemap files in your web.config as such:
<siteMap defaultProvider="FNDSiteMap" enabled="true">
<providers>
<add name="FNDSiteMap" type="System.Web.XmlSiteMapProvider" siteMapFile="FND.sitemap" securityTrimmingEnabled="true"/>
<add name="STASiteMap" type="System.Web.XmlSiteMapProvider" siteMapFile="STA.sitemap" securityTrimmingEnabled="true"/>
<add name="TASiteMap" type="System.Web.XmlSiteMapProvider" siteMapFile="TA.sitemap" securityTrimmingEnabled="true"/>
</providers>
</siteMap>
Then in your code-behind you can dynamically assign your SiteMapDataSource (which is bound to your menu) to one of the providers you specified in your web.config:
.aspx
<asp:Menu ID="MenuLevel1" runat="server" Orientation="Horizontal" DataSourceID="SiteMapLevel1"
MaximumDynamicDisplayLevels="0" IncludeStyleBlock="false">
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapLevel1" runat="server" />
.cs
SiteMapLevel1.SiteMapProvider = "TASiteMap";
Pauli's comment was the answer to my particular requirement:
"You shouldn't switch/change anything... instead you need to access
the RootNode like this all the time
SiteMap.Providers[someProvider].RootNode and the someProvider should
then be resolved at runtime."
I hadn't realised this was possible, but was the correct solution for me.
is there a way to bind a asp.net tree view control to a data set?
i am having to build the nodes of the tree by looping through a data set and wanted to clean it up and make life better buy just doing a .databind()
also XML is always an option if its simpler than dataset here...
any ideas?
As Philb28 suggested, you can use a SiteMapProvider to handle this. I used that exact method on an old project. If you have a relatively static set of items for the TreeView, you can do the following:
Add a .sitemap file to your project.
Define <sitemap> and <provider> sections in your Web.config
Add sitemap elements to the provider section.
Here's what one of my Web.config sections looks like:
<siteMap>
<providers>
<add name="Administrators" description="Reads .sitemap XML files." type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile="Common/Sitemaps/Admins.sitemap"/>
<add name="Users" description="Reads .sitemap XML files." type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile="Common/Sitemaps/Users.sitemap"/>
</providers>
</siteMap>
From there, declare a SiteMapDataSource, set its SiteMapProvider property to the name property of one of your provider elements, and bind it. Finally, set your TreeView.DataSource to your SiteMapDataSource, and bind your TreeView as well.
You could look into implementing your own sitemapprovider. You could then build your site map based on your data set and bind this to your tree view.
How to import a namespace in Razor View Page?
Finally found the answer.
#using MyNamespace
For VB.Net:
#Imports Mynamespace
Take a look at #ravy amiry's answer if you want to include a namespace across the app.
The first way is that use #using statement in .cshtml files, that imports a namespace to current file only, and the second:
In the "web.config" file in "Views" directory of your project (notice it is not the main web.config in project's root), find this section:
<system.web.webPages.razor>
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
.
.
<!-- etc -->
</namespaces>
</pages>
</system.web.webPages.razor>
you can add your custom namespace like this:
<add namespace="My.Custom" />
that will add the namespace to all of .cshtml (and/or .vbhtml) files;
also you can change views inheritance from here, like:
<pages pageBaseType="My.Custom.MyWebViewPage">
Regards.
UPDATE: Thanks to #Nick Silberstein to his reminder about areas! He said:
If you're working within an area, you must add the namespace within the Web.config under /Areas/<AreaName>/Views/ rather than
/Views/
For Library
#using MyNamespace
For Model
#model MyModel
In ASP.NET MVC 3 Preview1 you can import a namespace on all your razor views with this code in Global.asax.cs
Microsoft.WebPages.Compilation.CodeGeneratorSettings.AddGlobalImport("Namespace.Namespace");
I hope in RTM this gets done through Web.config section.
I found this http://weblogs.asp.net/mikaelsoderstrom/archive/2010/07/30/add-namespaces-with-razor.aspx which explains how to add a custom namespace to all your razor pages.
Basically you can make this
using Microsoft.WebPages.Compilation;
public class PreApplicationStart
{
public static void InitializeApplication()
{
CodeGeneratorSettings.AddGlobalImport("Custom.Namespace");
}
}
and put the following code in your AssemblyInfo.cs
[assembly: PreApplicationStartMethod(typeof(PreApplicationStart), "InitializeApplication")]
the method InitializeApplication will be executed before Application_Start in global.asax
One issue that you must know is that when you import a namespace via web.config in Views folder, that namespace is imported JUST for views in that folder. Means if you want to import a namespace in an area views, you must also import that namespace, in that area's web.config file, located in area's Views folder;
For namespace and Library
#using NameSpace_Name
For Model
#model Application_Name.Models.Model_Name
For Iterate the list on Razor Page (You Have to use foreach loop for access the list items)
#model List<Application_Name.Models.Model_Name>
#foreach (var item in Model)
{
<tr>
<td>#item.srno</td>
<td>#item.name</td>
</tr>
}
You can try this
#using MyNamespace
"using MyNamespace" works in MVC3 RTM. Hope this helps.
I think in order import namespace in razor view, you just need to add below way:
#using XX.YY.ZZ
Depending on your need you can use one of following method:
In first line/s of view add "using your.domainName;" (if it is
required in specific view only)
if required in all subsequent views
then add "using your.domainName;" in _ViewStart.cshtml. You can find
more about this in: Where and how is the _ViewStart.cshtml layout file linked?
Or add Assembly reference in View web.config as described by others explained in: How do you implement a #using across all Views in Asp.Net MVC 3?