Calling a Library Function from a View (MVC C#) - c#

I have a function in my Misc library in App_Code called EncodePicture which encodes a picture. However when I try to call the code, I get the function exists in both. I've looked at other answer such as clearing down the temporary files, I did that but it didn't work. The Misc Library has No namespace, does it need it?
I'm calling the function as :-
<img id="imgTitle" src="data:image/png;base64,#Misc.EncodePicture("/aPic/banner.jpg")" alt="" width="468" height="60" />
I get it Misc exists in both Universe and App_Code.....
How can I get round this problem? The function is :-
using System.Security.Cryptography;
namespace Universe
{
public class Misc
{
public static string EncodePicture(string sFilename)
{
string sEncode = "";
using (FileStream fs = new FileStream(HttpContext.Current.Server.MapPath("~" + sFilename), FileMode.Open))
{
System.IO.BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
sEncode = Convert.ToBase64String(bytes, 0, bytes.Length);
}
return sEncode;
}
Please don't say hard code the value because I'm going to be using this style in other places and can't hard code all the images. C# or VB.NET pls.
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS0433: The type 'Misc' exists in both 'App_Code.keoe0a1i, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'Universe, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'

Qualify via Namespace
Depending on where your EncodePicture() method is defined, you can import the appropriate namespace so that it could be called within your View :
namespace YourProject
{
public static class Misc
{
public static string EncodePicture(string file)
{
// Build a URL for the requested path
return file;
}
}
}
and then simply add a using statement within your View :
#using YourProject;
And you should then be able to call it as expected via :
#Misc.EncodePicture(...)
Or without the using statement in a fully qualified manner :
#YourProject.Misc.EncodePicture(...)
Reference it anywhere via the web.config
If this was a method you would expect to use throughout various different Views, then you might consider adding the namespaces in your web.config so that it would be accessibly more easily :
<system.web.webPages.razor>
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<!-- Add your namespace here -->
<add namespace="YourProject" />
</namespaces>
</pages>
</system.web.webPages.razor>

Related

Why is Extension Method Not Found in MVC4 Razor View?

Given the following string extension method
namespace JHS.ExtensionMethods
{
public static class StringExtensions
{
public static string ToUSAPhone(this String str)
{
return String.Format("{0:(###) ###-####}", Double.Parse(str));
}
}
}
A #using statement was added to the MVC4 Razor view
#using JHS.ExtensionMethods;
and the following string value calls the extension method
#Model.producer.phone.ToUSAPhone()
which results in the following error
'string' does not contain a definition for 'ToUSAPhone'
I also tried putting the namespace in the web.config of the /Views folder and receive the same error.
<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="JHS.ExtensionMethods"/>
</namespaces>
</pages>
I have verified the extension method works by putting the same call in a C# class
string test=producer.phone.ToUSAPhone();
It seems the reference to the extension method is not available in the MVC4 Razor view but I can't figure out why?
This happens if the type you are trying to use the extension method on is actually a dynamic. Check to see if the exception is being generated by the CSharp RuntimeBinder. If so, you can either use the method as a common or garden static method:
#StringExtensions.ToUSAPhone(Model.producer.phone)
Or you can cast the value to a string:
#(((string)Model.producer.phone).ToUSAPhone())
According to Eric Lippert (formerly of MSFT):
The reason behind the fact that dynamics do not support extension
types is because in regular, non-dynamic code extension methods work
by doing a full search of all the classes known to the compiler for a
static class that has an extension method that match. The search goes
in order based on the namespace nesting and available "using"
directives in each namespace.
That means that in order to get a dynamic extension method invocation
resolved correctly, somehow the DLR has to know at runtime what all
the namespace nestings and "using" directives were in your source
code. There is no mechanism handy for encoding all that information
into the call site.
It's not just if the type you're calling the extension method on is dynamic, but if anything in the expression is dynamic and not cast.
eg this is clearly dynamic:
#ViewBag.ToJSON()
But I first thought Mike's answer did not apply to me because I was doing this :
#(ViewBag.UserProfile.GetJSONProfile().ToJSON())
where ToJSON() is my extension method and GetJSONProfile() just returns object.
I was just spacing out and being stupid but wanted to mention this.
Build your project before adding your custom namespace for the extentions to your View.
There may be yet another trivial reason for this and it happened to me.
The file that I created my extension in had "Content" as value for Build Action property on VS file properties pane.
Switching it to "Compile" immediately fixed the issue, naturally...
i had the exact same problem with the same error message, but in my case in some weird way, i fixed it by putting the ";"
so what was
#{var subti = item.subtitle.Truncate(18)}
was fixed with the ;
#{var subti = item.subtitle.Truncate(18);}
this maybe could help someone

C# Can I make a namespace accessible everywhere in my dot net web site for code-behind and classes

I have an extension method for String that I want to be available on every code behind and class in my solution. The method is sitting in a particular namespace. I'd like everywhere to have access to that namespace without me having to include it in every class.
I've used the "namespaces" tag in the web config to successfully include it on every aspx page, but this does not make it accessible on code behind or elsewhere.
So, is there a similar way to include a namespace everywhere?
So, is there a similar way to include a namespace everywhere?
No, I am afraid that there isn't. If you place the extension method in some of the root namespaces then it will be in scope for the child namespaces. For example:
namespace Foo
{
public static class Extensions
{
public static void Go(this string value)
{
...
}
}
}
will be in scope inside all classes declared in Foo.* namespaces. So you might put the extension method in a root namespace which has the same name as your project and then it will be available everywhere because all classes are automatically generated in child namespaces (unless you change that).
Just put you extensions class into System namespace and it will be available for every String object.
namespace System
{
public static class Extensions
{
public static void M1(this string value)
{
...
}
}
}
No, you cannot.
The namespace section of web.config only provides those namespaces to the markup, but not code-behind.
<configuration>
<system.web>
<pages>
<namespaces>
<add namespace="System.Data" />
<add namespace="System.Text"/>
</namespaces>
</pages>
</system.web>
</configuration>
You must explicitly add namespaces via the using statement in code-behind or add to one of the already included namespaces like System, but that is not recommended.
You'll have put a using statement on every code file that intends to have access to the namespace, you can't "gloabally include."
Usually, it's good form to put your various utilities, static classes, and extension classes in a "Common" project that your other projects all have a dependency on. I've seen this pattern re-used a lot:
Using YourNameSpace.Common.Utilities;

ASP.NET 3.5 Url Routing Not Working

I am a newbie to asp.net field and having some problem in implementing url routing in asp.net 3.5 (I know it can be easily implemented in asp.net 4.0).
Here is what I have done.....
a) I am using .NET Framework 3.5 SP1.
b) Added System.Web.Routing assembly reference in web.config
<assemblies>
<add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
c) Add the UrlRoutingModule HTTP Module
<httpModules>
<add name="RoutingModule"
type="System.Web.Routing.UrlRoutingModule, System.Web.Routing,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</httpModules>
d) Code in Global.asax
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}
private static void RegisterRoutes()
{
System.Web.Routing.RouteTable.Routes.Add(
"SaveUser", new System.Web.Routing.Route("SaveUser",
new RouteHandler("~/Register.aspx")));
}
e) RouteHandler.cs Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;
using System.Web.Compilation;
using System.Web.UI;
public class RouteHandler : IRouteHandler
{
public RouteHandler()
{
}
public RouteHandler(string virtualPath)
{
_virtualPath = virtualPath;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
//var display = BuildManager.CreateInstanceFromVirtualPath(
// _virtualPath, typeof(Page)) as IDisplay;
var abc = BuildManager.CreateInstanceFromVirtualPath(_virtualPath, typeof(Page)) as IDisplay;
return abc;
}
string _virtualPath;
}
f) Code in Default.aspx.cs
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Redirect("~/SaveUser");
}
}
and I am getting the following error
The route handler 'RouteHandler' did not return an IHttpHandler
from its GetHttpHandler() method.
I tried 100 of links but could not make out what is wrong.
If anyone have experience in url routing in asp.net 3.5.....pls help.... I need to implement it very urgently....
Thanks in advance....
System.Web.Routing
only available on .net framework version 4
This is probably too little, too late, but I recently upgraded a .NET 3.5 ASP.NET site to use routing and I see your issue.
The problem is that when you configure the routing module, it creates a 2nd context for the routing module that is completely separate from HttpContext.Current in the ASP.NET page. So, you need to set up your handler so that you can access this other context instance (which happens to be a RequestContext).
public class RouteHandler : IRouteHandler
{
public RouteHandler()
{
}
public RouteHandler(string virtualPath)
{
_virtualPath = virtualPath;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
//Record the request context of the routing module in HttpContext.Current, so we can use it in pages.
HttpContext.Current.Items("requestContext") = requestContext
return BuildManager.CreateInstanceFromVirtualPath(_virtualPath, typeof(Page)) as IDisplay;
}
string _virtualPath;
}
Now, in the page, you need to access the context from HttpContext.Current.Items.
public partial class _Default : System.Web.UI.Page
{
private readonly RequestContext RequestContext
{
get { return (RequestContext)HttpContext.Current.Items("requestContext"); }
}
protected void Page_Load(object sender, EventArgs e)
{
RequestContext.HttpContext.Response.Redirect("~/SaveUser");
}
}
I've been struggling with this same problem, and here's one thing I've learned. On the page referenced by Rick Schott, it says that what you put in web.config depends on what version of IIS you're deploying to. Use this for IIS 6, or IIS 7 in "classic mode":
<httpModules>
<add name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule,
System.Web.Routing,
Version=3.5.0.0,
Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
...but in IIS 7+ "integrated mode", add this instead:
<system.webServer>
<modules>
<remove name="UrlRoutingModule" />
<add name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule,
System.Web.Routing,
Version=3.5.0.0,
Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</modules>
</system.webServer>
One important thing I've discovered is that though the latter may be what's correct for your IIS, the former is what works inside Visual Studio 2008. So you may have to deploy a different web.config from the one you develop with.
Another useful fact I've found which isn't well documented is that the path pattern you feed to the Route constructor is app-relative, not host-relative, and it should not start with a leading "/" or "~/". Just start with the first subfolder name, or page name if at app root level.
You have to get all that right just to enable it to invoke your IRouteHandler. Then you can worry about the two-contexts issue, if any. I had no trouble writing to requestContext.HttpContext.Items in the handler class and then reading from Context.Items in the target page.
But since you got the error message "did not return an IHttpHandler from its GetHttpHandler()", it sounds like you've got that working at least on your desktop. So the question then is... why are you casting your page instance as IDisplay instead of as IHttpHandler? That seems like the obvious first thing to change. I tried casting the return as Page and it seems to just want a direct cast to IHttpHandler instead.

How to get resource strings from ASP.NET markup?

Hi
I have an assembly called like X.Common.DLL. There is some resources files for multilanguage app. Let's say it Language.resx Language.en-US.resx....etc....
I have a web application which contains this above dll as reference...
So how can I use this resources file in my web applications markup side?
Text="<%$ Resources:Class, ResourceKey %>" is not valid because of "Class" name is in another assembly...
You can easily create a wrapper class that does something like this
public class ResourceWrapper
{
private ResourceManager resourceManager;
public ResourceWrapper()
{
resourceManager = new ResourceManager("Namespace.Common", Assembly.Load("x.common"))
}
public string String(string resourceKey)
{
return ResourceManager.GetString(resourceKey);
}
}
Finding the correct name for the first param to new ResourceManager(...) can be a bit tricky sometimes.
To make it easier for yourself you can call like this:
Assembly.Load("x.common").GetManifestResourceNames() and check the returned results.
If you create a static wrapper, you can make the resource calling code as simple as this:
<%= Resource.String("MyResourceKey") %>
You should reference the other assembly in web.config to expose its content in web forms.
http://msdn.microsoft.com/en-us/library/ms164642.aspx
Edit : more detailed answer due to comments under :
You should complete the pages/namespaces section of the webconfig like this :
<pages>
<namespaces>
...
<add namespace="My.Fully.Qualified.Namespace"/>
</namespaces>
</pages>
Of course the assembly which provides the namespaces should also be referenced (project references, web.config's section)
Then you should be able to write things like "<%= MyResx.MyEntry %>

Custom ConfigurationSection type not loading correctly

Every time I do a ConfigurationManager.GetSection("registeredPlugIns") for this custom section I receive this error:
An error occurred creating the configuration section handler for registeredPlugIns:
Could not load type 'Engine.PlugInArch.PlugInConfigurationSection'
from assembly 'System.Configuration, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a'.
Why is it trying to load the type from System.Configuration and not the assembly that I ask it to?
Here is my Section code:
namespace Engine.PlugInArch
{
public class PlugInConfigurationSection : ConfigurationSection
{
[ConfigurationProperty("plugIns", IsDefaultCollection = false),
ConfigurationCollection(typeof(PlugInCollection), AddItemName = "addPlugin")]
public PlugInCollection PlugIns
{
get { return this["plugIns"] as PlugInCollection; }
}
}
}
And here is my app.config
<configuration>
<configSections>
<section name="registeredPlugIns" type="Engine.PlugInArch.PlugInConfigurationSection, Engine"/>
</configSections>
...
<registeredPlugIns>
<plugIns>
<addPlugIn DllName="ProcessorPlugin.dll"/>
</plugIns>
</registeredPlugIns>
</configuration>
Is your dll called Engine.dll? I think not and that is where the problem is.
OK, run procmon from sysinternals. Set the filter to your process name and also filter for result="NAME NOT FOUND". You will see entries where it is looking for Engine.dll or Engine.exe. See where it is looking for it and it is likely the file needs to be copied to the running folder.

Categories