I've moved the CS files out the App_Data folder because I get errors with duplicate builds, one builds at compile time one at run time so I was told to move them out that folder.
Two files, Default.aspx.cs
namespace CrystalTech
{
public partial class newVersion_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
LoginInitialiser loginData = new LoginInitialiser();
loginData.loadData();
}
}
}
And Security.cs
namespace CrystalTech
{
// Handles all our login logic
public class LoginInitialiser
{
public bool isLoggedIn { get; private set; }
public LoginInitialiser()
{
this.isLoggedIn = false;
}
// Fetches the users data
public void loadData()
{
if (HttpContext.Current.Session["loggedIn"] != null)
{
this.isLoggedIn = (bool)HttpContext.Current.Session["loggedIn"];
}
// Fetch the data if we are logged in
if (this.isLoggedIn)
{
}
// Otherwise redirect
else
{
HttpContext.Current.Response.Redirect("../logins/index.asp?action=dn&r=" + CommonFunctions.GetCurrentPageName());
}
}
}
// Holds users information
public class User
{
public int ID { get; private set; }
public string username { get; private set; }
public Company company { get; private set; }
public string title { get; private set; }
public string forenames { get; private set; }
public string surnames { get; private set; }
public string email { get; private set; }
}
// Holds company information
public class Company
{
public int ID { get; private set; }
public string name { get; private set; }
public string telephone { get; private set; }
}
}
Why does Default.aspx.cs throw:
The type or namespace name 'LoginInitialiser' could not be found (are you missing a using directive or an assembly reference?)
If you want your classes to live somewhere other than App_Code, add a "Class Library" project to your solution and put that class there. Don't forget to reference that project in your webproject.
Only code in the App_Code directory is compiled - So unless your files are in there (or a subdirectory), they won't be picked up
And what do you mean by duplicate builds? Depending on project settings, the actual build can be triggered either by the first visit to the site or by the compile itself. It's also possible to do half-and-half. with a little preparation beforehand on (build/publish) and the actual compile on the first site visit
The code files (except the ones related to aspx files) are put in the App_Code folder only to ensure their compilation (This is requirement imposed by ASP.net and now I know from comments it is only for web site projects and not web application projects). If they are anywhere else they are not compiled. Check and you will not find Build Action for the code files outside App_Code folder.
Related
I have a treelist that contains folders. Each folder can have files or other folders inside.
I need a function in C# that if I change the visibility of the folder, automatically they have to change the visibility of the folders and files under it.
Could you help me out?
Thanks in advance.
I'm not sure what you are rendering your list in and depending on the UI and/or framework you are using there may be other ways to achieve this but the simple approach to walking your folder structure would be using some simple recursion. An example:
public class Resource
{
public string Name { get; set; }
public string Type { get; set; }
public bool Visible { get; set; }
public List<Resource> Children { get; set; }
}
public class Form
{
public void ChangeVisibility(Resource resource)
{
if (resource.Type != "Folder") return;
resource.Visible = !resource.Visible;
if (resource.Children.Any())
{
resource.Children.ForEach(ChangeVisibility);
}
}
}
My application has a business logic layer, and a data access layer. I want to give only the data access layer access to the database model. Now, I can easily do this, but then my UI classes cannot access the database classes like Reminder:
namespace Database
{
using System;
using System.Collections.Generic;
public partial class Reminder
{
public long Id { get; set; }
public string Name { get; set; }
public string Date { get; set; }
public string RepeatType { get; set; }
public string Note { get; set; }
public long Enabled { get; set; }
public string SoundFilePath { get; set; }
public string PostponeDate { get; set; }
public Nullable<long> EveryXCustom { get; set; }
public string RepeatDays { get; set; }
public Nullable<long> DayOfMonth { get; set; }
}
}
which is inside the database class library
I use this reminder class to store reminders. In my UI classes I use this class for various reasons.
To make use of this Reminder class, I simply add a reference to the class library that needs to use it. This works fine, but the problem is that every class library that references this, can alter the database like this.
If I'm not using Entity Framework, I could simply have a Reminder class outside the model (because there is no model) and load reminders from the database into that and extract them without using Entity Framework.
Here's an example of why I need to use the Reminder class in my UI classes (this is just a small code sample of one UI class)
This code is inside a timer that ticks every 30 seconds
// We will check for reminders here every 30 seconds.
foreach (Reminder rem in BLReminder.GetReminders())
{
// Create the popup. Do the other stuff afterwards.
if(rem.PostponeDate != null && Convert.ToDateTime(rem.PostponeDate) <= DateTime.Now && rem.Enabled == 1)
{
allowRefreshListview = true;
// temporarily disable it. When the user postpones the reminder, it will be re-enabled.
rem.Enabled = 0;
BLReminder.EditReminder(rem);
MakePopup(rem);
}
else if(Convert.ToDateTime(rem.Date.Split(',')[0]) <= DateTime.Now && rem.PostponeDate == null && rem.Enabled == 1)
{
allowRefreshListview = true;
// temporarily disable it. When the user postpones the reminder, it will be re-enabled.
rem.Enabled = 0;
BLReminder.EditReminder(rem);
MakePopup(rem);
}
}
GetReminders will do get the reminders from the database and put them in reminder objects
using (RemindMeDbEntities db = new RemindMeDbEntities())
{
localReminders = (from g in db.Reminder select g).ToList();
db.Dispose();
}
You can create separate project called i.e. Shared and put there all classes which are used in many projects. Then you need to reference this project by UI project and data access project (and by others which use these classes).
Both will have access to shared classes and UI won't be able to call data access layer directly.
You can also create interface outside of data access layer but if your classes are DTOs (Data Transfer Object) first option will be better.
If im not using the entity framework, i could simply have a reminder
class outside the model
You could create an interface instead of a class outside of the model in a shared assembly:
public interface IReminder
{
public long Id { get; }
public string Name { get; }
public string Date { get; }
public string RepeatType { get; }
public string Note { get; }
public long Enabled { get; }
public string SoundFilePath { get; }
public string PostponeDate { get; }
public Nullable<long> EveryXCustom { get; }
public string RepeatDays { get; }
public Nullable<long> DayOfMonth { get; }
}
Your Entity can than implement the interface:
public partial class Reminder : IReminder
{
//...
}
Maybe you want to make your Entities only internal visible and expose public service methods like IEnumerable<IReminder> GetReminders()
I am currently developing a file indexing system. I have an interface IDiskDrive that can get immediate file items (files/folders). The interface definition is as follows...
public interface IDiskDrive
{
bool IsReady { get; }
string Name { get; }
string VolumeLabel { get; }
string VolumeLabelName { get; }
DiskDriveType Type { get; }
FolderPath RootFolder { get; }
DiskDriveUsage Usage { get; }
IEnumerable<IFileItem> GetImmediateFileItems(FolderPath path);
}
The ability to read all file/folders is complete and works correctly. Now, I need to actually index the file files and folders. Looking ahead I know I will need some reporting tools. This leads me to think I need another abstraction, based upon IDiskDrive that can read/populate. I also need the ability to select drives for indexing.
My question is should my new class inherit IDiskDrive or should I use composition (possibly a decorator)?
// inheritance
class IndexedDiskDrive : IDiskDrive
{
public IndexedDiskDrive(IDiskDrive drive)
{
...
}
public int Id {get; internal set; } // database id
public bool Selected { get; internal set; }
public DateTime? DateLastIndexed { get; internal set; }
// IDiskDrive implementation
public bool IsReady
{
get { return this.Drive.IsReady; }
}
}
or composition...
class IndexedDiskDrive
{
public IndexDiskDrive(IDiskDrive drive)
{
this.Value = drive;
}
public IDiskDrive Value
{
get;
private set;
}
// additional properties
public int Id { get; internal set; }
public bool Selected { get; internal set;}
public DateTime DateLastIndexed { get; internal set; }
}
Note:
I need access to the underlying IDiskDrive for the UI.
For example, I request user to select drives to index. I initially supply a list of local drives and the ability to add network drives. To try and keep code simple, I thought the idea of a new class with a selected property might help.
This allows the GUI to enumerate a list of IndexedDiskDrives and set/clear the select property.
In both examples you expose the IDiskDrive object from the other object. In the first case you inherit from the same inteface, which means you expose the same methods and in the other case you expose the object via a property.
I don't see a reason yet why you want to do this.
It sounds like a typical constructor DI case to me. Just have a new interface for your new class which is doing a different job and hence requires a different contract, and if it needs the IDiskDrive object as a dependency, then just inject it via the constructor and leave it as it is.
P.S.: I know this is not something you have asked, but you might be interested in Lucense.NET, which is a .NET library to index files. They might have already solved your problem for your:
http://lucenenet.apache.org/
EDIT:
From your current class design I would do the following:
void Main()
{
// Use IoC container in real app:
var diskDrive = new DiskDrive(...);
var fileIndexer = new FileIndexer();
var fileItems = diskDrive.GetImmediateFileItems(filePath);
fileIndexer.IndexFiles(fileItems);
}
// Define other methods and classes here
public interface IDiskDrive
{
bool IsReady { get; }
string Name { get; }
string VolumeLabel { get; }
string VolumeLabelName { get; }
DiskDriveType Type { get; }
FolderPath RootFolder { get; }
DiskDriveUsage Usage { get; }
IEnumerable<IFileItem> GetImmediateFileItems(FolderPath path);
}
public interface IFileIndexer
{
void IndexFiles(IEnumerable<IFileItem> files);
}
public class FileIndexer : IFileIndexer
{
public void IndexFiles(IEnumerable<IFileItem> files)
{
// do stuff
}
}
I have a DLL written in C#.NET which exposes a COM interface, so a vb6 application can call my DLL. This interface looks like:
[System.Runtime.InteropServices.Guid("3D2C106C-097F-4ED7-9E4F-CDBC6A43BDC4")]
public interface IZDPharmaManager {
[System.Runtime.InteropServices.DispId(2)]
SearchPatientEventArgs FoundPatient { get; set; }
[System.Runtime.InteropServices.DispId(3)]
IntPtr Start(string server, string database, string user, string password, bool integrated, int praktijkID, string userGUID, int userID, string userName, bool hasRightToSearchPatient);
[System.Runtime.InteropServices.DispId(4)]
void Stop();
[System.Runtime.InteropServices.DispId(5)]
void InitializeSkinner(System.Object skinnerFramework);
}
[System.Runtime.InteropServices.Guid("4438852E-CF2D-4DB0-8E6E-428F65A6B16C")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IZDPharmaManagerEvents {
[DispId(1)]
void SearchPatient(ZDPharmaManager sender, SearchPatientEventArgs e);
}
[System.Runtime.InteropServices.Guid("9297D43F-C581-3F0F-AA60-9506C6B77B5F")]
[ClassInterface(ClassInterfaceType.None)]
public class SearchPatientEventArgs : WebHIS.ZDPharmaceutisch.ISearchPatientEventArgs {
public SearchPatientEventArgs() {
//Nodig voor COM.
}
public int ID { get; set; }
public string FullName { get; set; }
public string OwnName { get; set; }
public string PartnerName { get; set; }
public string DateOfBirth { get; set; }
public string ZipCode { get; set; }
public string HouseNumber { get; set; }
public string BSN { get; set; }
}
public delegate void SearchPatientEventHandler(ZDPharmaManager sender, SearchPatientEventArgs e);
[System.Runtime.InteropServices.Guid("465AC7EC-27EF-3D95-AAA6-29D01FCF15A1")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IZDPharmaManagerEvents))]
public class ZDPharmaManager : WebHIS.ZDPharmaceutisch.IZDPharmaManager {
public event SearchPatientEventHandler SearchPatient = null;
public SearchPatientEventArgs FoundPatient { get; set; }
//private MainForm GraphicalInterface { get; set; }
private ChoosePatient GraphicalInterface { get; set; }
public ZDPharmaManager() {
//Nodig voor COM.
}
#region IZDPharmaManager Members
public IntPtr Start(string server,
string database,
string user,
string password,
bool integrated,
int praktijkID,
string userGUID,
int userID,
string userName,
bool hasRightToSearchPatient) {
//Zet connectiestring.
DAL.DAC.CnnInfo = new System.Data.SqlClient.SqlConnectionStringBuilder() {
DataSource = server,
InitialCatalog = database,
UserID = user,
Password = password,
IntegratedSecurity = integrated
};
DAL.DAC.PracticeID = praktijkID;
DAL.DAC.UserGUID = userGUID;
DAL.DAC.UserID = userID;
DAL.DAC.UserName = userName;
DAL.DAC.HasRightToSearchPatient = hasRightToSearchPatient;
//Apotheek IDs ophalen en bewaren.
DAL.DAC.PharmacyIDs = DAL.PracticeDAO.GetPharmacyByPracticeID(praktijkID);
//Initialiseer grafische interface.
//this.GraphicalInterface = new MainForm();
this.GraphicalInterface = new ChoosePatient();
//Haal ongekoppelde afhaalberichten op.
this.GraphicalInterface.Patients = new VML.PatientsVM(this);
//Toon grafische interface.
this.GraphicalInterface.Show();
return this.GraphicalInterface.Handle;
}
public void Stop() {
foreach (var item in this.SearchPatient.GetInvocationList()) {
this.SearchPatient -= (SearchPatientEventHandler)item;
}
this.GraphicalInterface.Close();
this.GraphicalInterface = null;
this.FoundPatient = null;
}
public void InitializeSkinner(System.Object skinnerFramework) {
WebHIS.ZDPharmaceutisch.SkinnerModule.SkinFramework = (XtremeSkinFramework.SkinFramework)skinnerFramework;
}
#endregion
internal virtual void OnSearchPatient(SearchPatientEventArgs e) {
if (this.SearchPatient != null) {
this.SearchPatient(this, e);
}
}
}
This works fine. But each time I build this DLL without changing the interface (because I had to fix something somewhere in the logic) the reference with the vb6 application is broken and we need to recompile the vb6 application.
Does anyone know what I am doing wrong? 'Cause we had vb.net DLL's which didn't break the reference after recompile due to fixed GUIDs. Any help would be much appreciated.
Update
Both vb6 app and DLL are operational. But when I recompile the DLL and test it on our testserver via the vb6 application I get an automation error (which usually means the reference is broken and you need to recompile the vb6 app aswell)
I don't see any strong leads that could explain this problem. The [Guid] attribute for the assembly matters, that sets the type library ID. And the [AssemblyVersion] matters, that sets the type library version number. The attributes are declared in the project's AssemblyInfo.cs file. Make sure your build system doesn't monkey with these attributes.
Best way to go about it is to find out what exactly changes. Run the OleView.exe utility from the Visual Studio Command Prompt. File + View Typelib and select the .tlb file. Copy/paste the content of the right panel into a text file.
Rebuild the project and repeat the OleView exercise. You can now simply use a diffing tool to see what exactly changed. Update your question with what you found out if you need more help.
I have always stored data for a user (after they logged in) in a Session variable, so I can use that data on any page.
I found out that another way to store information globally is to store it in a class, using { get; set;}, and then calling that from any page.
Right now, I've used both these methods as a test, and they both work really well:
Session["LoginId"] = rdr["uniqueIdentifier"].ToString();
And
Member.LoginId = rdr["uniqueIdentifier"].ToString();
Where (In Member.cs)
public class Member
{
public static int Challenges { get; set; }
public static int NicknameId { get; set; }
public static string LoginId { get; set; }
public static string FriendsListId { get; set; }
public static void ClearVariables()
{
Challenges = 0;
NicknameId = 0;
LoginId = null;
FriendsListId = null;
}
}
Global.asax
void Session_End(object sender, EventArgs e)
{
Member.ClearVariables();
}
My question is, is it safe enough to store user data in a class like this, or should I stick with Session objects?
Updated for Completeness
Will this post do something like above, but for multiple users?
How to access session variables from any class in ASP.NET?
I found this approach is one of the most easy to use and with least error of chances. I think this is called Facade Design Pattern.
public class SiteSession
{
#region Attributes
private static string _siteSession = "__SiteSession__";
#endregion
#region Constructor
private SiteSession()
{
}
#endregion
#region CurrentSession
public static SiteSession Current
{
get
{
SiteSession session = HttpContext.Current.Session[_siteSession ] as SiteSession;
if (session == null)
{
session = new SiteSession();
HttpContext.Current.Session[_siteSession ] = session;
}
return session;
}
}
#endregion
#region SessionProperties
public sherserve.CustomTypes.UserTypes UserType { get; set; }
public int UserID { get; set; }
public String StaffID { get; set; }
public String Position { get; set; }
public String StaffName { get; set; }
public int TimeZone { get; set; }
public String DealerId { get; set; }
public String DealerPosition { get; set; }
public String DealerName { get; set; }
public int DealerFirmId { get; set; }
public String ClientId { get; set; }
public String ClientName { get; set; }
public String ClientBusiness { get; set; }
public String CountryCode { get; set; }
public int ClientFirmId { get; set; }
#endregion
}
Values can be store in Session like this:
SiteSession.Current.UserType = user.UserType;
And Can be obtain like this :
int userId= SiteSession.Current.UserID;
It is type safe as well.
In your case it is not safe at all since static variables in asp.net are common to all users.
Using static variables is not safe. The values set for one user would overwrite the values for another user. Static variable would mean only one variable is created and used for all sessions.
The life time of static variables is the application life time.
If your variables are meant to be user-specific (which appear to be) you will need to stick with Session variables.
I am sure that it is not working for you. An instance of class exists only as long as the request is processed. Once the request is processed, you will not be able to get the instance of the class again. In case of static variables, it is application wide and not suitable to store the user specific information.
Session is designed to handle the state of application across the post back and it is the sole purpose of session, i.e. to maintain the state of application and it is ideal for your requirement.
disadvantage off second approach is when the application restarts the variable will lose their values.but with session your data will be stored in browser cookies.
EDIT:
only use static variables when you need a application level common - shared (between all users) variables.
Sessions are created per user, while classes, in production, are alive throughout the application's whole lifetime.
Though you may not experience issues in development with only one user, in production each request will override the previous data, and could therefore pose security risks.
Stick to sessions.