Is there a way to import a dll from a class project (or maybe another web application project) into a web application project and reuse a #helper? The reusability for web applications with Razor seems pretty much zero if that cannot be achieved.
You can do it, but you have to jump through several hoops.
You need to obtain RazorGenerator: "This is a Custom Tool for Visual Studio that allows processing Razor files at design time instead of runtime, allowing them to be built into an assembly for simpler reuse and distribution. "
Using RazorGenerator, you can create .cshtml files in your class library project that declare helper functions. For example, in a file called Foo.cshtml:
#helper MyHelper(string parameter) {<text>#parameter</text>}
These helpers will exist as static methods in the static class representing your .cshtml file. In the above example, that would translate to Foo.MyHelper.
You can invoke these static methods from your web application's .cshtml file just like any other static method. (assuming you've added the correct using directives to point to the namespace containing your helper.) For example:
<div>#Foo.MyHelper("hello world")</div>
Related
I'm trying to make an ASP.NET Core 2.0 application multi-language. I created a resource file under a folder "Resources" called "Resource.it.resx". I set its access modifier to Public and its Namespace to Resources.
After (re)building the solution I cannot see this namespace in the C# code now in the cshtml code.
Is there some other steps to do?
There are two things you need to take into account:
Only a Resource.resx generates a namespace, culture-specific resources such as Resource.it.resx does not generate a namespace. This is the intended behavior.
ASP.NET Core's localization practices suggest not to use resources directly, but rather find the localized strings using IStringLocalizer.
I suggest you to read the fundamentals of ASP.NET Core localization in the official MSDN guide. There you will find examples for localizing strings in Controllers, Views and wherever you need them.
First thing check if your resource namespace is visible in controller,
like Resources.Resource.
I had not and in this situation I have created emtpy resource class, ex. my resources name is ServiceResources.en-US.resx, in same folder I have ServiceResources.cs empty class too.
Check if you have imported your namespace in _ViewImports.cshtml correctly, with IStringLocalizer class.
1) for asp.net (web forms), where do the extensions methods in c# go? in the web folder?
2) If the method is meant to be used in both a library and the web code behind pages, what is the correct way to allow the extensions to be used in both projects (the asp.net solution references the library project)?
3) For extensions pertaining to different types (ie. extensions for datatable, and extensions for strings), is it the standard practice to put all of them in one Extensions.cs file?
2) I'd normally place the extensions in the library project. You can use extensions from other libraries provided that the namespace of the extension class is in a using declaration for the code you're currently writing (indeed, that's how LINQ works)
3) I'd normally place extensions for different types into different files. In much the same way that you can have multiple top-level types in the same file, but the general convention is to place them in separate files. It just feels cleaner, and gives you less code to look through. It doesn't affect the experience of the code that consumes the extensions though.
I have an HtmlHelper extension method in an assembly separate from my MVC application assembly. Within the extension method I would like to get the version number of the MVC application assembly. Is this possible?
The calling assembly is the razor view dynamic assembly so that doesn't help. Is there some object nested within the HtmlHelper that can provide me with the version number of the MVC application assembly? I've been exploring the HtmlHelper class documentation but so far haven't found a solution to my problem.
Thanks!
This is a notoriously evil thing - because unfortunately there's no one specific reliable way to do it.
Since it's an MVC application, however, the chances are that it has a Global.asax.cs - therefore it has a locally defined HttpApplication class.
From within an html helper you can get to this:
public static string AppVersion(this HtmlHelper html)
{
var appInstance = html.ViewContext.HttpContext.ApplicationInstance;
//given that you should then be able to do
var assemblyVersion = appInstance.GetType().BaseType.Assembly.GetName().Version;
//note the use of the BaseType - see note below
return assemblyVersion.ToString();
}
Note
You might wonder why the code uses the BaseType of the application instance, and not simply the type. That's because the Global.asax.cs file is the primary type of the MVC application, but then Asp.Net dynamically compiles another HttpApplication type that inherits from that via the Global.asax.
As I said earlier; this works in most MVC sites because they should all have an application class defined in a Global.asax.cs file by convention (because that's the way the project is set up).
Just in case anyone comes across this, here is what worked for me (MVC5 VS2013). Enter straight into the view:
#ViewContext.HttpContext.ApplicationInstance.GetType().BaseType.Assembly.GetName().Version.ToString();
Just search for the assembly which should be the source for your version number
AppDomain.CurrentDomain.GetAssemblies().Where(a => a.GetName().Name.Equals("MyDll")).First().GetName().Version.ToString();
As the Title says, I've got a multi-project solution.
I've got a "core" project that is loaded with most of the other projects.
So my question is this, I have a few utility functions such as FormatPhoneNumber(..) that I would like to be able to access in the following manner from anywhere.
(in Project_B which depends on Core)
string str = FormatPhoneNumber(inputString);
At worst, I suppose I could live with a qualifier of some sort:
string str = util.FormatPhoneNumber(inputString);
The best way of doing this is to create a dll project (maybe called something like "CommonCode"?), that you can then reference this dll from all of your other projects and access the classes and methods therein.
You will have to have some sort of "qualifier" (as you call it) somewhere, but to reduce the impact use the using statement at the top of each file, e.g.
using util;
If you really must have such utility functions (you know, you shouldn't, but sometimes it's the best/easiest solution), I suggest having them either in the Core (assuming that every single project is dependent on the Core anyway), or in a separate utility assembly. If you don't want to have a separate assembly lying around, consider using ILMerge.
The qualifier should be no problem at all. I suggest not putting unrelated function into an Utils class, but rather use e.g. a Formatting class for all formatting functions. On the other hand, as s_ruchit in the meantime suggested, extension methods (e.g. for the string class) might come in handy as well.
(Did I mention that this ยง%$& MarkDown editor does not allow typing an [at] symbol on a German keyboard layout, because it instead creates a blockquote? Sigh.)
Try creating your own util library.
Create a Class Library project and put your util classes in there.
I myself try to adhere a naming convention like [companyName].Util.[subdomain]
Your example would probably fit in my [CompanyName].Utils.StringHelpers
You would then create a static class StringHelper with a static method FormatPhoneNumber.
You will see that these personal libraries quickly grow bigger. By grouping them you don't have to load all your code if you only need a subset of functions.
Use an extension method to make it easier to call the method without using the class name.
public static class Util {
public static string FormatPhoneNumber(this string input) {
:
}
}
The method will now appear on every string object. You do not need to know which class it comes from. However, if the extension class is declared in another namespace, you must still import the namespace.
string formattedString = inputString.FormatPhoneNumber();
If you are using C# 3.0, you can bind them all into one single static class use them as Extension Methods.
There are no global functions in .NET, so you will have to put your utility functions into a class. You can make the methods static, so you can call them without having to instantiate the utility class:
public class Utility
{
public static string FormatPhoneNumber(string input)
{
...
}
}
// usage:
string output = Utility.FormatPhoneNumber(input);
Put these methods into your core library or a separate utility library that can be used (referenced) by all other libraries and applications.
You need to put the functions in static classes. You cannot avoid the qualification (there are no global functions in C#):
<%= Formatters.PhoneNumber(rawData) %>
The utility functions should be grouped as per normal methods: similar methods go together, unrelated methods should go into different classes (event with static classes aim for low coupling and high cohesion).
The assembly each belongs in should be obvious: formatting functions only used by the presentation layer (ASP.NET project itself) belong there. Truly common functions could go into core.
If the function you are implementing can only be used in context of your application, i would recommend you to place it into the Core assembly (under a separate namespace like "Utils" for example) or a new DLL library of your application solution.
Only if the function can be used across multiple projects it makes sense to create a utility library. But always keep in mind that a utility library only make sense if it's maintained regularly.
If you want all code to access these methods then go with extension methods, otherwise I would go with Util class in core assembly.
FWIW, if you follow a more formalised namespace as boris sugguests (recommended to avoid conflicts) you can abbreviate with the using keyword:
using Util = [CompanyName].Utils.StringHelpers;
I tend to follow the DRY principle and create an alias as soon as I need it more than once.
I sometimes define Business Logic classes to "help" my ASPX code-behind classes. It makes the most sense to me to include them both in the code-behind file since they work together. However, I'd occasionally like to access the Business Logic classes from higher level classes defined in App_Code but they aren't automatically accessible outside of the file.
Thus, the question: it is easy to access classes defined in App_Code but how do I access classes defined elsewhere?
UPDATE: One other thing, the ASPX page class and the App_Code class are in the same namespace - that isn't the issue.
NOTE: I have taken the advice of those who have responded (thanks guys) and am refactoring to make class access easier. However, I don't think the question is actually answered yet (in the case of an ASP.NET Website project). I don't need the answer any more but, if someone could clarify what makes classes visible when they are outside of App_Code, it may well help someone else (or even me, down the road).
Make sure you place your classes in a sensible namespace.
Place 'using' keyword in code behind files you would like to access them.
Or <%# import if you are using them in inline code.
Put the dll that contains your classes in the /bin folder.
TBH I prefer to keep the separate library project in the same solution and have project reference in the Web probject. VS handles building and placing the dll for you.
Some time while you create or add any file it has been create as the content file while it has to be compile file.
Please follow the process how to resolve this issue.
1) Right click on your class file in App_Code folder.
2) Click on properties.
3) Change Build Action from "" to Compile
4) Rebuild your Application.
This will work definitely
Tushar Tyagi
I assume you mean you are defining a separate class inside the codebehind .cs file? What access modifiers are you giving them?
As above though, I'd generally have a separate project in the solution for this kind of thing (usually in a different namespace like MyApp.Web and MyApp.), and just reference it from there.
You can also just create a standard folder in your project to access classes, and move them there, but you have to do some additional things to make it accessible to your project:
Ensure you don't name the folder any of the reserved terms (i.e. call it "AppCode", instead of "App_Code") if you are running into issues with the "App_Code" folder, after going through the rest of these bullets.
The classes should all have the same namespace as your code-behind.
Ensure the classes are made public, with public methods, if they are being called from other classes.
Include "using MyClass;" statements at the top of the code-behind/class files.
Make sure the class' Build Action property is set to Compile.
You can not access a class from another class in same code behind file as .net dsnt support multiple inheritance. but you can create you business logic class as inner class in main class and make its all functions public so that they can be call in main class.