Accessing Global Session Key in Umbraco - c#

I have a group of session keys which I declare in a Global class file, these get set properly upon login.
public static class SessionKeys
{
public static string memberToken = "token";
public static string memberFirstName = "first_name";
public static string role_pmn = "PMNInstructor";
public static string role_superUser = "";
public static string role_chapterAdmin = "ChapterMember";
public static string role_registeredUser = "RegisteredUser";
}
I have a need to later access some of these session vars in an XSLT Macro for navigation. I'm having trouble finding the correct syntax for accessing these variables in the XSLT Macro.
This syntax works in my .NET Macros:
Session[Globals.SessionKeys.role_pmn]

The correct syntax should be
umbraco.library:Session
This link should provide more information.
Alternatively, you could create an extension library, get the reference in .net, and then just reference your library in the xslt (umbraco.tv video for reference, or text-only instructions)

Syntax for accessing the global session keys in XSLT is different than what is used to access them in C#. You merely have to use the string value you set the key to.
umbraco.library:Session(PMNInstructor)

Related

C# Value Cannot be null using Path.Combine

I'm attempting to construct a database using the C# Console, but I'm getting an error thrown that I can't seem to find the problem with. The problem is in my Query function, when I attempt to define the path based off of user input. Essentially, it looks into a given folder in the user folder, and within it another subfolder containing the files wherein is the database information. Im using the Path.Combine function to dynamically define the path throughout my code, but I'm getting the following error;
ArgumentNullException: Value cannot be null. (Parameter 'path3')
Even though all strings are defined and not null.
this is what the line of code looks like:
path = Path.Combine(Info.path, "infolder", classrooms.inventory, classrooms.geninv, userinput)
And here is all of the code that the strings in the path arguement are referencing:
class classrooms
{
public static string Teacher;
public static string Roomnumber;
public static string Changes;
public static string inventory = "inventory";
public static string geninv = "GenInv";
public static string classinv = "ClassInv";
}
and
class Info
{
public static string path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
}
if necessary I can attach my full code.
Screenshot of Error
I figured it out.
It was an improperly defined string that the pathcombine function was using in another instance of the code, and it was just getting caught up once i reused the path.combine function. Thanks for all the answers, I wouldn't have thought to look at that without all the input.

Retaining a value obtained from file within the return value of a method

Assuming I will need to access the values contained within a given file a small number of times, from different methods, can I include some sort of boolean value within a method to determine whether or not it is appropriate to call the file?
Lets say I have the file config.cfg. In that file, there are three values:
string/name>max|
bool/adult>yes|
int/age>20|
The method getUserName() returns the value of "max". It does this by calling the file:
using (StreamReader reader = new StreamReader(path))
{
//get line beginning with string/name here
return //string value containing name
}
Let's assume I need to use the value of name several times, as well as the values isAdult and clientAge. Rather than accessing the file over and over again, it could be much easier to save the requested value in some form of static variable. However, this variable still needs to be changed in value at least once, when the method is first called.
Can I do this inside the method getUserName()?
Furthermore, is this idea even possible within the bounds of OOP? Is it a similar concept to Prefetch?
It really looks to me that you need to access a field in a lazy way (i.e. only if needed, when needed). If so .NET has Lazy class for such cases which also provides thread safety out of the box:
public static Lazy<string> Name { get; } = new Lazy<string>(() => ReadNameFromFile());
Lazy will also ensure that you only create value once (i.e. call initiailization method) and on later calls it will simply return already retrieved value.
Create a static class. Something like this:
public static class ClientConfig{
public static string Name{get;set;}
public static bool IsAdult{get;set;}
public static int Age{get;set;}
public static void Load(){
// load your values
// ClientConfig.Name = name from file etc.
}
public static void Save(string newName, int age, bool value){
// save your values to the config file
}
}
And call ClientConfig.Load() first time when your app starts, for example (or whenever you need to retrieve config data)

Where to define constants and use them anywhere?

In Java I would write something like
public interface ICar {
static String RED_CAR = "/res/vehicles/car_red.png";
static String BLUE_CAR = "/res/vehicles/car_blue.png";
static String GREEN_CAR = "/res/vehicles/car_green.png";
}
Because C# doesn't allow using fields in interface, where do I define this constants in C#, when I wish to use them more than once?
You can define a static class to contain your constants (which need to be public as by default fields without modifier are private):
public static class Car
{
public const string RED_CAR = "/res/vehicles/car_red.png";
public const string BLUE_CAR = "/res/vehicles/car_blue.png";
public const string GREEN_CAR = "/res/vehicles/car_green.png";
}
After this you can use constants like Car.RED_CAR.
If all your constants are files it's better to include them in your resources.
In your project properties there's a resource section, vs can create a Resources.resx if you need one.
In there you can add all sorts of files or strings (for translations mostly).
You can then access them through Properties.Resources.RED_CAR
I would not name them like that though. It's from the time when all variables where globals and naming conventions like that where needed to know what was stored in the variable. But when accessing your data like this it's always clear what's going on.

Best way to display Global Resource Value

I've got a Global Resource file with many values
Currently in code I call the value like this
TxtSuccess.Text = (string) GetGlobalResourceObject("GlobalResource", "msgSuccess");
But if later in the design we needed to rename variables then maintaining will be a pain.
would it be better to do something like this?
public class AppGlobalConstants
{
public string MsgSuccess{ get; private set; }
public AppGlobalConstants()
{
MsgSuccess= (string) GetGlobalResourceObject("GlobalResource", "msgSuccess");
}
}
Then if later on the team wanted to change the name of some of these global resources they could do so without having to modify any pages which used these resources.
We want to use globals as there are plans for our web application (asp.net web forms 4.5) to be available to additional countries and languages in the future.
I would rather do something like this:
public static class AppGlobalConstants
{
public static string MsgSuccess
{
get
{
return (string) GetGlobalResourceObject("GlobalResource", "msgSuccess");
}
}
}
This way, the values are static. In case the name changes, you simply modify the strings in this class. Because everything is static in this class, you could do something like this:
Console.WriteLine(AppGlobalConstants.MsgSuccess);
If you want, you could also add a set accessor to the properties. Because everything is static, there's no need to create instances of this class.

C# - Re-initialize static class?

I have a class in a web application I am working on that holds client settings. For some background, I do not own this class, and changing it is not an option. We recently added some logic to store the settings in a database, and I was tasked with creating a page to edit them, fair enough.
Here is my issue; the settings are held in a static class, and are themselves static, read-only properties. For example
public static class Settings
{
public static readonly setting1 = SettingmanagerClass.GetSetting("setting1");
public static readonly setting2 = SettingmanagerClass.GetSetting("setting2");
public static readonly setting3 = SettingmanagerClass.GetSetting("setting3");
}
Now, for example, through the page I wrote, we change the value for setting2 to "Happy Variable"; it saves to the DB just fine, but now I need it to be reflected in the web app as the new value. Since it is a static readonly property of a static class, it only ever gets called when the app first wires up and can't be set manually.
Just to reiterate, I don't own the original class, so "just make the properties writeable" is not (currently) a valid option. Normally I would just talk this over with my boss and he would make a judgement call and possibly allow me to modify the other class, but I am not in a position to make that call and he is out of the office for the week.
So basically; is there any way to re-initialize a static class once a web application has started running? I just need for it to reload all of its properties as if the app was just rebuilt and started up again.
ConstructorInfo constructor = typeof(Settings).GetConstructor(BindingFlags.Static | BindingFlags.NonPublic,null, new Type[0], null);
constructor.Invoke(null, null);
You could use reflection:
var prop = typeof(Settings).GetField("setting1", BindingFlags.Static |
BindingFlags.Public);
prop.SetValue(null, "Bar");
string currentValue = Settings.setting1; //Bar
If the above code is representative of the situation you're in, you won't be able to reinitialize the code unless you do something particularly hacky with reflection (this is not recommended by the way).
Edit: Oh wait - I didn't realize this was a web app. You could programmatically bounce the application:
System.Web.HttpRuntime.UnloadAppDomain
The only option comes to my mind which is requires a lot of work:
Create another AppDomain
Load assembly in the other domain
Use Remoting to get the data
If settings changed, unload the AppDomain and do steps 1 to 3 again
I would use reflection
var info = typeof(Settings)
.GetField("Settings",BindingFlags.Static|BindingFlags.Public);
info.SetValue(null, "setting4");
public static class Settings
{
public static name = "";
static Settings()
{
ReInitialize();
}
public static void ReInitialize()
{
name = "My name is re-initialized";
}
}
Settings.name = "My name has changed";
// Console.WriteLine(Settings.name);
Settings.ReInitialize(); //name is "My name is re-initialized"
// Console.WriteLine(Settings.name);
Hmm, you want to find a way to hack the class? even if it exists with reflection and something like that, it is not good way to solve this
Fast workaround I can suggest to create you own not readonly static properties, initialize with that static variables and use them everywhere
But it will be better to use Cache or Application stores instead of static variables
Hope this helps
Old thread I know, but one thing I have done is to create an Initialize method (public static void) that sets all of the variables (they're all public static). In that method, the database calls are made and the variables of the class are set. Then in code, anytime you want to refresh the variables (i.e. anytime you call SaveChanges()), you can call Class.Initialize() and you're done.
I use this for caching common lists of lookup information that can change, and we need to keep that in sync for when the database is updated from the application.
Change your values to properties:
public static class Settings
{
public static setting1
{
get { return SettingmanagerClass.GetSetting("setting1"); }
}
public static setting2
{
get { return SettingmanagerClass.GetSetting("setting2");
}
public static setting3
{
get { return SettingmanagerClass.GetSetting("setting3");
}
}
Also, this does not change the signature of your code.

Categories