EDIT: Question Reconstructed.
OK, I have revisited my get and set methods, but I am still very unclear on how it all works.
What I want to achieve is the Model is populated by the Controller, from the values that it takes form the form. This is then sent to the Db_Facade, which compares the uName and uPwd, and if they are equal returns the ACCESS, which will be set for the entire scope of the program.
I don't know if the get and set declarations are done correctly, or if they can be bunched together (If this is possible it would be great because I will be using this for much larger collections of data), and I'm pretty sure I'm implementing them wrong as well.
If you can help, my knowledge of Accessors is incredibly limited.
Here is my Compare Login method in my Controller:
public static void Compare_Login(User_Login_View Login_View)
{
User_Model getACCESS = new User_Model(); // Creates a new oject of User_Model
getACCESS.Name = Login_View.txtUsername.Text; //Populates the Model from the Login View
getACCESS.Pwd = Login_View.txtPassword.Text;
if (getACCESS.ACCESSLEVEL > 0)
{
Login_View.Close();
}
else
{
Login_View.lblError.Visible = true;
}
Login_View.Menu.SetMenuView();
}
Here is my Model:
public class User_Model
{
public string Name
{
get
{
return Db_Facade.uName;
}
set
{
Db_Facade.uName = value;
}
}
public string Pwd
{
get
{
return Db_Facade.uPwd;
}
set
{
Db_Facade.uPwd = value;
}
}
public int ACCESSLEVEL
{
get
{
return Db_Facade.ACCESS;
}
set
{
Db_Facade.ACCESS = value;
}
}
}
Here is the dummy database comparison:
class Db_Facade
{
public static string uName;
public static string uPwd;
public static string cPwd;
public static int ACCESS;
public static void getLoginACCESS()
{
uName = "paul";
uPwd = "pwd";
ACCESS = 1;
/* I get a "getACCESS does not exist" error here
if (uName == getACCESS.Name && uPwd == getACCESS.Pwd)
{
getACCESS.ACCESSLEVEL = ACCESS;
}
else
{
getACCESS.ACCESSLEVEL = 0;
}
*/
}
}
I don't know if it's needed, but here is my View
public partial class User_Login_View : Form
{
public Menu_View Menu { get; set; }
public User_Login_View()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
User_Controller.Compare_Login(this);
}
}
2 Questions / Hints
1.) Where do you call your getLoginACCESS() ?
2.) Why do you think Db_Facade is able to access getACCESSfrom your class User_Controller?
a solution would be to modyfie your getLoginACCESS() to getLoginACCESS(User_Model getACCESS) and than call it in your Compare_Login(User_Login_View Login_View) befor your if like Db_Facade.etLoginACCESS(getACCESS);
Related
I have 2 classes Folder and File. They have a property NumberFiles. For File, it's of course only 1 at all case, for Folder, it depends how many files in the folder. This property must implement RaisePropertyChanged to bind.
I don't allow a set NumberFiles in FileRecord. But I can't find a solution, so this is my hack. With this code, I can set NumberFiles, but it doesn't have any effect.
public abstract class Record : ViewModelBase
{
private int _numberFiles;
public virtual int NumberFiles
{
get
{
return _numberFiles;
}
set
{
_numberFiles= value;
RaisePropertyChanged(nameof(NumberFiles));
}
}
//and a lot of properties
}
public class FolderRecord : Record
{
//and a lot of properties
}
public class FileRecord : Record
{
public override int NumberFiles
{
get
{
return 1;
}
set
{
//HACK : let empty SET
}
}
//and a lot of properties
}
public Main()
{
var list = new List<Record>(); // this list used to bind to the DataGrid
Record rc;
for (some condition)
{
if (folder)
{
rc = new RecordFolder();
rc.NumberFiles = 10; // OK
}
else if (file)
{
rc = new FileRecord();
rc.NumberFiles = 10; // the property NumberFiles can't allow a set, should compile error here
}
list.Add(rc);
}
}
I already have tried like put protected set in the base class but I can't set the value later.
public abstract class Record
{
public abstract int GetNumberFiles();
}
public class FolderRecord : Record
{
private int _numberOfFiles;
public void SetNumberOfFiles(int numberOfFiles)
{
_numberOfFiles = numberOfFiles;
}
public override int GetNumberFiles()
{
return _numberOfFiles;
}
}
public class FileRecord : Record
{
public override int GetNumberFiles()
{
return 1;
}
}
We are using HttpSessionStateBase to store messages in a set up similar to this working example:
public class HttpSessionMessageDisplayFetch : IMessageDisplayFetch
{
protected HttpSessionStateBase _session;
private IList<ICoreMessage> messages
{
get
{
if (_session[EchoCoreConstants.MESSAGE_KEY] == null)
_session[EchoCoreConstants.MESSAGE_KEY] = new List<ICoreMessage>();
return _session[EchoCoreConstants.MESSAGE_KEY] as IList<ICoreMessage>;
}
}
public HttpSessionMessageDisplayFetch()
{
if (HttpContext.Current != null)
_session = new HttpSessionStateWrapper(HttpContext.Current.Session);
}
public void AddMessage(ICoreMessage message)
{
if (message != null)
messages.Add(message);
}
public IEnumerable<IResultPresentation> FlushMessagesAsPresentations(IResultFormatter formatter)
{
var mToReturn = messages.Select(m => m.GetPresentation(formatter)).ToList();
messages.Clear();
return mToReturn;
}
}
When we pass in a QualityExplicitlySetMessage (which inherits from ICoreMessage, see below) it is saved correctly to messages.
This is how the object looks after being inserted into the messages list, at the end of AddMessage(ICoreMessage message) above.
But when we come to access it after changing controllers the inherited member's properties are null, which causes a variety of null reference exceptions.
This is how the object now looks after we call FlushMessagesAsPresentations. I've commented out var mToReturn... as this tries to access one of these null ref properties.
I'd like to ask the following:
Why is the HttpSessionStateBase failing to capture these values taken
by the inherited type?
Is this an issue in saving to the HttpSession or in retrieving?
Is this anything to do with, as I suspect, inheritance?
Or is the fact I'm potentially calling a new controller that dependency injects the HttpSessionMessageDisplayFetch causing an issue?
I'm a first-time poster so please let me know if I'm making any kind of faux pas - Super keen to learn! Any input is very welcome.
Some potentially useful code snippets:
QualityExplicitlySetMessage
public class QualityExplicitlySetMessage : QualityChangeMessage
{
public QualityExplicitlySetMessage(IQPossession before, IQPossession after, IQEffect qEffect)
: base(before, after, qEffect)
{
IsSetToExactly = true;
}
}
QualityChangeMessage - Working example
public abstract class QualityChangeMessage : CoreMessage, IQualityChangeMessage
{
protected PossessionChange Change;
public PossessionChange GetPossessionChange()
{
return Change;
}
protected QualityChangeMessage(IQPossession before, IQPossession after, IQEffect qEffect)
{
Change = new PossessionChange(before, after, qEffect);
StoreQualityInfo(qEffect.AssociatedQuality);
}
public override IResultPresentation GetPresentation(IResultFormatter formatter)
{
return formatter.GetQualityResult(this);
}
#region IQualityChangeMessage implementation
public int LevelBefore
{
get { return Change.Before.Level; }
}
//... And so on with values dependent on the Change property.
}
CoreMessage - Working example
public abstract class CoreMessage : ICoreMessage
{
public string MessageType
{
get { return GetType().ToString(); }
}
public string ImageTooltip
{
get { return _imagetooltip; }
set { _imagetooltip = value; }
}
public string Image
{
get { return _image; }
set { _image = value; }
}
public int? RelevantQualityId { get; set; }
protected void StoreQualityInfo(Quality q)
{
PyramidNumberIncreaseLimit = q.PyramidNumberIncreaseLimit;
RelevantQualityId = q.Id;
RelevantQualityName = q.Name;
ImageTooltip = "<strong>" + q.Name + "</strong><br/>" + q.Description + "<br>" +
q.EnhancementsDescription;
Image = q.Image;
}
public virtual IResultPresentation GetPresentation(IResultFormatter formatter)
{
return formatter.GetResult(this);
}
}
UserController - Working example.
public partial class UserController : Controller
{
private readonly IMessageDisplayFetch _messageDisplayFetch;
public UserController(IMessageDisplayFetch messageDisplayFetch)
{
_messageDisplayFetch = messageDisplayFetch;
}
public virtual ActionResult MessagesForStoryletWindow()
{
var activeChar = _us.CurrentCharacter();
IEnumerable<IResultPresentation> messages;
messages = _messageDisplayFetch.FlushMessagesAsPresentations(_storyFormatter);
var vd = new MessagesViewData(messages)
{
Character = new CharacterViewData(activeChar),
};
return View(Views.Messages, vd);
}
}
I'm trying to implement a PATCH on Web API for an object that will be stored in a DB. The input object from the controller has all of the properties that can be modified but we allow the client to choose which fields to send back. We only want to update the MongoDB representation if some of the fields have changed or been set. We started using a Dirty object pattern (not sure this is a pattern) whereby when you set a property you also record that it is dirty. for instance
public class Example
{
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
TitleWasSet = true;
}
}
public bool TitleWasSet {get;set;}
}
This could work but is kind of tedious and I feel it exposes lots of logic that could be contained.
So a solution I came up with was to store the update Actions in the inbound object then reapply them to the Mongo Object in a Try Update fashion.
like this:
public class Data
{
public string Header { get; set; }
public int Rating { get; set; }
}
public class EditDataRequest
{
private readonly List<Action<Data>> _updates;
public EditDataRequest()
{
_updates = new List<Action<Data>>();
}
public string Header
{
set
{
_updates.Add(data => {data.Header = value;});
}
}
public int Rating
{
set
{
_updates.Add(data => {data.Rating = value;});
}
}
public bool TryUpdateFromMe(Data original)
{
if (_updates.Count == 0)
return false;
foreach (var update in _updates)
{
update.Invoke(original);
}
return true;
}
}
Now this would work great but it doesn't take account of the values being the same. So i then looked at changing the list of actions to a list of functions that would return a bool if there was a difference in the value.
private readonly List<Func<Data, bool>> _updates;
And then the properties would look like this:
public int Rating
{
set
{
_updates.Add(data => {
if (data.Rating != value)
{
data.Rating = value;
return true;
}
return false;
});
}
}
And the try update method...
public bool TryUpdateFromMe(Data original)
{
if (_updates.Count == 0)
return false;
bool changesRequired = false;
foreach (var update in _updates)
{
changesRequired |= update.Invoke(original);
}
return changesRequired;
}
As you can see that property set implementation is rather clunky and would make the code nasty to read.
I'd like a way of extracting the check this property value then update it to another method that I can reuse in each property - I assume this is possibly somehow but it might not be.
Of course, if you have better suggestions for how to handle the PATCH situation then I'd be happy to hear them as well.
Thanks for reading this far.
I have a class that contains the following method (The Class name is ZipLoad):
private string DOit(string uName, string pWord)
{
DOSTUFF.....
return "Successfull";
}
Now I want pass parameters to the class using my program but there are two parameters. If there was one parameter i would simply do this:
private string testUser;
public string getSetUser
{
get { return testUser; }
set { testUser= DOit(value); }
}
And then use my Windows Forms Application to pass the parameters.
ZipLoad myZipLoad = new ZipLoad();
string report;
myZipLoad.testUser = "userName";
report= myZipLoad.getSetUser;
My Question is that how do I pass parameters to the DOit method using public properties in the class. One way is to make the method public but for some reason people say that is bad.
Any help would be appreciated ...
Thank You
maybe i'm wrong but set { testUser= DOit(value); } doesn't looks very useful what you are trying because if you get this to work and you are doing
myZipLoad.testUser = "userName";
report= myZipLoad.getSetUser;
string user = myZipLoad.testUser; //<- user == "Successfull"
so i build you this construct
class Program
{
static void Main(string[] args)
{
ZipLoad myZipLoad = new ZipLoad();
string report;
myZipLoad.TestUser = "userName";
report = myZipLoad.Stat; //<- modified
}
}
class ZipLoad
{
#region private Values
private string testUser;
private string pWord;
#endregion
#region Properties
public string TestUser
{
get { return testUser; }
set { testUser = value; }
}
public string PWord
{
private get { return pWord; }
set { pWord = value; }
}
// ADDED
public string Stat
{
get { return DOit_aka_Login(testUser, pWord); }
}
#endregion
private string DOit_aka_Login(string uName, string pWord) //<- modified
{
// now you may need to check the input if(uName =="" && pWord==""){...}
//DOSTUFF.....
return "Successfull";
}
}
if it doesn't fit your needs please add more information's
Typically, if I want to pass an object to an instance of something I would do it like so...
Listing 1
File 1:
public class SomeClass
{
// Some Properties
public SomeClass()
{
public int ID
{
get { return mID; }
set { mID = value; }
}
public string Name
{
set { mName = value; }
get { return mName; }
}
}
}
public class SomeOtherClass
{
// Method 1
private void Method1(int one, int two)
{
SomeClass USER; // Create an instance
Squid RsP = new Squid();
RsP.sqdReadUserConf(USER); // Able to pass 'USER' to class method in different file.
}
}
Similar approach to listing 1 but I was unable to get it to work. What am I doing wrong here?
Listing 2 (this does not work, why?)
File 1:
private void SomeClass1
{
[snip]
TCOpt_fM.AutoUpdate = optAutoUpdate.Checked;
TCOpt_fM.WhiteList = optWhiteList.Checked;
TCOpt_fM.BlackList = optBlackList.Checked;
[snip]
private TCOpt TCOpt_fM;
TCOpt_fM.SaveOptions(TCOpt_fM);
}
File 2:
public class TCOpt:
{
public TCOpt OPTIONS;
[snip]
private bool mAutoUpdate = true;
private bool mWhiteList = true;
private bool mBlackList = true;
[snip]
public bool AutoUpdate
{
get { return mAutoUpdate; }
set { mAutoUpdate = value; }
}
public bool WhiteList
{
get { return mWhiteList; }
set { mWhiteList = value; }
}
public bool BlackList
{
get { return mBlackList; }
set { mBlackList = value; }
}
[snip]
public bool SaveOptions(TCOpt OPTIONS)
{
[snip]
Some things being written out to a file here
[snip]
Squid soSwGP = new Squid();
soSgP.sqdWriteGlobalConf(OPTIONS);
}
}
File 3:
public class SomeClass2
{
public bool sqdWriteGlobalConf(TCOpt OPTIONS)
{
Console.WriteLine(OPTIONS.WhiteSites); // Nothing prints here
Console.WriteLine(OPTIONS.BlackSites); // Or here
}
}
In this example, I was not able to use approach in Listing 1. Probably because Listing 1 passes an object between classes. Whereas, below, things are defined in a single class. I had to use some extra steps (trial & error) to get things to work. I am not sure what I did here or what its called. Is it good programming practice? Or is there is an easier way to do this (like in Listing 1).
Listing 3 (this works)
File 1:
private void SomeClass1
{
private TCOpt TCOpt_fM;
[snip]
TCOpt_fM.AutoUpdate = optAutoUpdate.Checked;
TCOpt_fM.WhiteList = optWhiteList.Checked;
TCOpt_fM.BlackList = optBlackList.Checked;
[snip]
TCOpt_fM.SaveOptions(TCOpt_fM);
}
File 2:
public class TCOpt:
{
public TCOpt OPTIONS;
[snip]
private bool mAutoUpdate = true;
private bool mWhiteList = true;
private bool mBlackList = true;
public bool AutoUpdate
{
get { return mAutoUpdate; }
set { mAutoUpdate = value; }
}
public bool WhiteList
{
get { return mWhiteList; }
set { mWhiteList = value; }
}
public bool BlackList
{
get { return mBlackList; }
set { mBlackList = value; }
}
[snip]
public bool SaveOptions(TCOpt OPTIONS)
{
[snip]
Some things being written out to a file here
[snip]
Squid soSwGP = new Squid();
soSwGP.OPTIONS = OPTIONS;
}
}
File 3:
[snip]
private TCOptions TCOpt_TCS;
public TCOpt OPTIONS
{
get { return TCOpt_TCS; }
set
{
TCOpt_TCS = value;
sqdWriteGlobalConf();
}
[snip]
public class SomeClass2
{
public bool sqdWriteGlobalConf()
{
Console.WriteLine(OPTIONS.WhiteSites);
Console.WriteLine(OPTIONS.BlackSites);
}
}
Thanks in advance,
XO
At first it seems that you have a completely false picture on how OOP works (or hopefully just the wrong words).
You don't pass object between files. You pass them between classes. Normally you would put one class into one file and in that case your description would be right. But nevertheless you can put multiple classes into one file and you can also spawn one class over multiple files (by using the partial keyword).
So to be completely correct, you also don't pass classes. You pass instances of classes. And the problem in your example is that you declare an object of a specific class, but you don't instantiate it:
private void Method1(int one, int two)
{
SomeClass USER; // This doesn't create an instance!
USER = new SomeClass(); //This creates an instance.
//SomeClass USER = new SomeClass(); //Can also be written as one-liner.
Squid RsP = new Squid();
RsP.sqdReadUserConf(USER); // Able to pass 'USER' to class method in different file.
}
Update
After reading your comment i looked into your second and third example. Maybe it is just a typo again in Listing 2 File 1, but cause you changed it in Listing 3 File 1 i think there must somewhere your problem:
private void SomeClass1
{
[snip]
TCOpt_fM.AutoUpdate = optAutoUpdate.Checked;
TCOpt_fM.WhiteList = optWhiteList.Checked;
TCOpt_fM.BlackList = optBlackList.Checked;
[snip]
//It is impossible to declare here a variable name that is already used
//above.
//But it looks like you just declared here a variable (without instantiation)
//and trying to use it as parameter for the SaveOptions() function.
private TCOpt TCOpt_fM;
TCOpt_fM.SaveOptions(TCOpt_fM);
}
Normally this will lead to a couple of error messages.
declaring a variable name that is already used in the same scope
trying to pass an object that is not initialized
(If you like to pass a not initialized object you have to initialize it with null or use the out keyword