I have a control containing some text which I want to get from a resx file, I thought I could just create a file called ControlName.ascx.resx but that doesn't seem to be working.
I'm using
label1.InnerText = (string)GetLocalResourceObject("default");
To get the value from the resource file but it keeps throwing up an InvalidOperation Exception.
Am I right about how resx files work or does it only work for Pages?
I have the same code working on an aspx page.
When you call GetLocalResourceObject from within a user control, you are actually calling TemplateControl.GetLocalResourceObject, which will look in the wrong place for the resource file. You need to call HttpContext.GetLocalResourceObject instead.
protected string HttpContextGetLocalResourceObjectAsString(string message)
{
string path = HttpContext.Current.Request.Path;
return (HttpContext.GetLocalResourceObject(path, message) as string);
}
Now you can do
label1.InnerText = HttpContextGetLocalResourceObjectAsString("default");
Per the documentation:
Gets a page-level resource
http://msdn.microsoft.com/en-us/library/system.web.httpcontext.getlocalresourceobject.aspx
Edit- added
It may be less work to just add the string to the web.config and grab it from there.
<configuration>
<appSettings>
<add key="LoggingSystemId" value="B2F085A9-6EC1-4CBF-AF8B-B17BFA75AD81"/>
<appSettings>
...
referenced as follows:
logger.SystemId = System.Configuration.ConfigurationManager.AppSettings["LoggingSystemId"];
Of course, you'll need a reference to the System.Configuration dll.
A year or so later, but i think this is what you're after?
var resource = HttpContext.GetLocalResourceObject(TemplateControl.AppRelativeVirtualPath, termType.ToString());
Mark answer if that's the one!
Related
I have my appSettings defined in a separate config file called Appsettings.Dev.Config, and I include that file inside my web.config file like so
<appSettings configSource="ConfigFiles\AppSettings.Dev.config"/>
Lets say one of the settings in the file is
<add key="MailerEmailAccount" value="myemail#myserver.com" />
Can I access the value of the setting MailerEmailAccount elsewhere inside web.config? How?
Nope, the web configuration file cannot pull "settings" from itself; it's not dynamic at all. The only sort of dynamic functionality is the ability to include other .config, but that's just a "suck all these settings in as if they were part of me" kind of thing.
It might be possible if you create a custom ConfigurationSection that pulls the value from appSettings.
Here's an article that explain how to create a custom configuration section:
http://haacked.com/archive/2007/03/12/custom-configuration-sections-in-3-easy-steps.aspx
I don't know if this is what you're looking for, but it's the only way I can think of to read a web.config setting from within the web.config.
EDIT
I haven't tested this, but maybe something like this would work?:
[ConfigurationProperty("localName", IsRequired = true, IsKey = true)]
public string LocalName
{
get
{
return this["localName"] as string;
}
set
{
this["localName"] = WebConfigurationManager.AppSettings.Get(value);
}
}
I have an HTML home page. I want to be able to output to a text document on the server every time a person views the page.
I want to out put the IP addrs, Page and Date/Time anyone know an easy way of doing this?
If it has to be done other than html i would prefer to use ASP.
First, rename the page to have .aspx extension and add code behind file as well.
Second, add this method to the code behind:
private void WriteLog()
{
string currentFileName = Path.GetFileNameWithoutExtension(Request.FilePath);
string logFileName = string.Format("{0}_{1}.log.txt", currentFileName, DateTime.Now.ToString("ddMMyyyy"));
string logFilePath = Server.MapPath(logFileName);
string IP = Request.ServerVariables["REMOTE_ADDR"];
string logMessage = string.Format("[{0}] [IP: {1}] [Page: {2}]", DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss"), IP, Request.FilePath);
File.AppendAllLines(logFilePath, new string[] { logMessage });
}
And finally just call the above method from within the Page_Load event e.g.
protected void Page_Load(object sender, EventArgs e)
{
WriteLog();
}
This will create text file with the same name as the .aspx (in the same location) plus the current date to avoid clogging the same file with millions of lines, and append one line for each hit.
Edit: this is .NET 4.0 code so you'll have to define this as the target framework in both Visual Studio in case you're using it, and in the IIS configuration. The web.config should be updated by the Studio and in case you're not using it, here are the extra lines:
<system.web>
<httpRuntime requestValidationMode="2.0" />
<compilation debug="true" targetFramework="4.0" />
</system.web>
As #Alp said PHP would be the way to go:
$_SERVER['REMOTE_ADDR']; //gives you the visitor's IP address
basename($_SERVER["SCRIPT_NAME"]); //gives you the page name
date(); // gives you the current date
Then it would just be a case of running a little script that writes those to a file on each page.
Might be worth looking at Google Analytics - it gives lot's of useful stats about visitors (not 100% you can get individual IP addresses, can anyone clarify this?)
Edit:
ASP.NET
Request.ServerVariables["REMOTE_ADDR"]; // ip
Request.ServerVariables["HTTP_REFERER"]; // page
You can use PHP for that if your server supports it.
You can use an existing log framework like Log4Net.
Let's say we have such site structure:
App_LocalResources
|- A.aspx.resx
|- B.aspx.resx
A.aspx
B.aspx
Now I use HttpContext.GetLocalResourceObject("~/A.aspx", "Key1") in A.aspx.cs, and it works fine.
But if I use HttpContext.GetLocalResourceObject("~/A.aspx", "Key1") in B.aspx.cs, it throws an exception:
The resource class for this page was not found. Please check if the resource file exists and try again.
Exception Details: System.InvalidOperationException: The resource class for this page was not found. Please check if the resource file exists and try again.
How can I resolve this problem? I want to read the local resources from an external page, and I don't want to read the .resx file myself. Thanks :-)
UPDATE: In my case, there're some "data.xml" files(they are in different directories, and have elements like <key name='Key1' value='value1' />), and the contents of them will be rendered as html.
But the key names in the data.xml should be localized before rendering (different data.xml contain different keys).
For example, the data.xml has such an element:
<key name='CategoryId' value='3' />
In the result html page, I want to display "Category Id = 3" for en-US culture, and "类别=3" for zh-CN culture, etc.
So I think I can create some files following the pattern "data.xml.??-??.resx" in the App_LocalResources folder, then use the HttpContext.GetLocalResource() for each data.xml to retrieve the localized key names. That way I don't need to read the xml myself. Is it possible?
That's not the way that local resources are supposed to be used. Local resources are only valid for a page or control. You should use global resources in your case.
From MSDN
Global Resource Files
You create a global resource file by putting it in the reserved folder App_GlobalResources at the root of the application. Any .resx file that is in the App_GlobalResources folder has global scope. Additionally, ASP.NET generates a strongly typed object that gives you a simple way to programmatically access global resources.
Local Resource Files
A local resources file is one that applies to only one ASP.NET page or user control (an ASP.NET file that has a file-name extension of .aspx, .ascx, or .master). You put local resource files in folders that have the reserved name App_LocalResources. Unlike the root App_GlobalResources folder, App_LocalResources folders can be in any folder in the application. You associate a set of resources files with a specific Web page by using the name of the resource file.
And could be also useful for you to check how access resources programatically
Button1.Text =
GetLocalResourceObject("Button1.Text").ToString();
Image1.ImageUrl =
(String)GetGlobalResourceObject(
"WebResourcesGlobal", "LogoUrl");
Image1.Visible = true;
As Claudio Redi recommended, use Global Resource files.
I would create one per xml file in the format of "filename.resx", so in your example, you'd name it Data.resx.
Set the "Name" in the resource to your "name" attribute and the Value equal to the translated "name".
For example, in Data.resx, you'd have Name=CategoryId, Value=Category Id. In Data.zh-CN.resx, you'd have Name=CategoryId, Value=类别.
One you have the data in the resource files, you'd probably want to create a class wraps the functionality of the XML lookup and localization for your in your application. Something like this should work:
public class Data
{
private const string fileLocation = "TODO";
public string Name{ get; set; }
public string Value{ get; set; }
private Data()
{
}
public Data( string Name )
{
// TODO: Look up the single key from XML
}
public string GetLocalizedName( CultureInfo cultureInfo )
{
return Resources.Data.ResourceManager.GetString(Name, cultureInfo);
}
public static List<Data> LoadData()
{
List<Data> dataList = new List<Data>();
// TODO: Load XML and create a list of Data objects.
return dataList;
}
}
Try the following steps:
Step 1 - Delete the temp files of your web site from
C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files
Step 2 - Clean and Rebuild your Solution.
Step 3 - Make sure that your Resource file in the App_LocalResources folder has the same name as the page that has this issue (and both App_LocalResources and the page are in the same folder).
Your App should be OK then.
http://iymbas.blogspot.com
Is there any way to access the <compilation /> tag in a web.config file?
I want to check if the "debug" attribute is set to "true" in the file, but I can't seem to figure out how to do it. I've tried using the WebConfigurationManager, but that doesn't seem to allow me to get to the <compilation /> section.
Update:
I know I could easily just load the file like an XML Document and use XPath, but I was hoping there was already something in the framework that would do this for me. It seems like there would be something since there are already ways to get App Settings and Connection Strings.
I've also tried using the WebConfigurationManager.GetSection() method in a few ways:
WebConfigurationManager.GetSection("compilation")// Name of the tag in the file
WebConfigurationManager.GetSection("CompilationSection") // Name of the class that I'd expect would be returned by this method
WebConfigurationManager.GetSection("system.web") // Parent tag of the 'compilation' tag
All of the above methods return null. I'm assuming there is a way to get to this configuration section since there is a class that already exists ('CompilationSection'), I just can't figure out how to get it.
Use:
using System.Configuration;
using System.Web.Configuration;
...
CompilationSection configSection =
(CompilationSection) ConfigurationManager.GetSection( "system.web/compilation" );
You can then check the configSection.Debug property.
TIP: if you need to know how to get a value from a config file, check the machine.config file in your \Windows\Microsoft.net\Framework\<version>\CONFIG folder. In there you can see how all the configuration section handlers are defined. Once you know the name of the config handler (in this case, CompilationSection), you can look it up in the .Net docs.
The easy way to check if you're running in debug mode is to use the HttpContext.IsDebuggingEnabled property. It gets its answer from the compilation element's debug attribute which is the same thing you're trying to do.
After all, you can always load up the Web.config file into an XmlDocument and use an XPath query to find out!
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("~/Web.config"));
doc.SelectSingleNode("/configuration/system.web/compilation/#debug");
However, I suggest you use the Configuration.GetSection method for solution.
CompilationSection section =
Configuration.GetSection("system.web/compilation") as CompilationSection;
bool debug = section != null && section.Debug;
You can always check debug option on the compiler level by enclosing your code with
#if (DEBUG)
#endif
in case that was the idea...
Try using:
HttpContext.Current.IsDebuggingEnabled
Cant you just load the file up as a regular XML File and use XPath to get the nodes?
Try using the ConfigurationManager.GetSection method.
OK so I one page I find this line:
objDsCourse = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings("connstr").ConnectionString, CommandType.StoredProcedure, "Course_NewReportGet_Get_Sav", objPAra)
And I copied it to another page to start modifying it to work there:
getData = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings("connstr").ConnectionString, CommandType.StoredProcedure, "Course_NewReportGet_Get_Sav", objPAra)
However on the new page it underlines .ConnectionStrings saying that Non-invocable member 'System.Configuration.ConfigurationManager.ConnectionStrings' cannot be used like a method'... then why did it work in the other page??
EDIT: OK so I found in web.config what I think it is referencing because it says
<add name="ConnStr" connectionString="data source=..." />
Why would one page have access to this and the other not?
Is there any chance one page is using VB.NET, while the other is using C#?
I would agree with Daniel. In Visual Basic, both dictionary objects and methods are referenced by using parentheses. This can cause some confusion.
So in VB, ConfigurationManager.ConnectionStrings("connstr") would point to the ConnectionString object with the key "connstr" in the dictionary.
In C#, dictionary objects are referenced by square brackets [] so ConfigurationManager.ConnectionStrings("connstr") would literally mean "invoke the method ConnectionStrings of ConfigurationManager object using "connstr" as a parameter."
Long story short, check the <%# Page %> declaration at the top to make sure both pages are the same language. ... or, on the page with the error, change the line to use the ConfigurationManager.ConnectionStrings["connstr"] syntax.