How to pass Bound properties as parameters without manual setup - c#

Here is my App.xaml.cs
protected override Task OnInitializeAsync(IActivatedEventArgs args) {
Container.RegisterInstance(SessionStateService);
Container.RegisterInstance(NavigationService);
Container.RegisterType<IUserRepository, UserRespository>(new ContainerControlledLifetimeManager());
Container.RegisterType<UserSettingsContext>(new ContainerControlledLifetimeManager());
Container.RegisterType<IUserSettings, UserSettings>(new ContainerControlledLifetimeManager());
var userSettings = this.Container.Resolve<UserSettingsContext>();
userSettings.Database.EnsureCreated();
return base.OnInitializeAsync(args);
}
This is my UserSettings
using using Prism.Windows.Validation;
public class UserSettings : ValidatableBindableBase, IUserSettings {
private string _firstName;
public string FirstName {
get { return _firstName; }
set { SetProperty(ref _firstName, value); }
}
private string _lastName;
public string LastName {
get { return _lastName; }
set { SetProperty(ref _lastName, value); }
}
private UserType _userType;
public UserType UserType {
get { return _userType; }
set { SetProperty(ref _userType, value); }
}
private string _username;
[Required(ErrorMessage = "Required.")]
public string Username {
get { return _username; }
set { SetProperty(ref _username, value); }
}
private string _password;
[Required(ErrorMessage = "Required.")]
public string Password {
get { return _password; }
set { SetProperty(ref _password, value); }
}
}
ViewModel:
public class TestViewModel : UserSettings {
private UserSettings user;
public UserSettings User => user;
public async void SaveSettings() {
//It will work with this line
// var user = new UserSettings() {
// Username= this.Username,
// Password= this.Password,
// UserType= this.UserType,
// FirstName= this.FirstName,
// LastName= this.LastName
// };
//null properties
await loginService.SaveUserSettings(user);
}
}
When I tried to pass the 'user' the properties are null ,even user input data from UI(View), It will work if I setup the UserSettings using the code above, but I want to simplify this without that, how can I do that?
Thanks

You want to write await loginService.SaveUserSettings(this); because this seems to be the target that's filled with data.

Related

update entity in DDD with EFCore 3

i have senario for change Active Status property use . IsActive .
i have problem with update entity in asp core and DomainDriven Desogn .
when i change the IsActive to True or False it create a new record inctance a update that recoed .
i put here my code :
Step One :
this is my controller , in this controller i call the Command :
public async Task<ApiReturn> ChangeUserActiveStatus(long id)
{
var result = await dispatchers.SendAsync(new UserActiveStateCommand { id = id });
if(result.Success)
{
return Ok();
}
return BadRequest(result.Exception);
}
step Two :
i send a request to the database and give The desired record :
public class UserActiveStateCommandHandler : ICommandHandler<UserActiveStateCommand, OperationResult<string>>, IScopedDepency
{
private readonly IDomainUnitOfWork unitOfWork;
private readonly IDispatchers dispatchers;
public UserActiveStateCommandHandler(IDomainUnitOfWork unitOfWork, IDispatchers dispatchers)
{
this.unitOfWork = unitOfWork;
this.dispatchers = dispatchers;
}
public async Task<OperationResult<string>> HandlerAsync(UserActiveStateCommand command)
{
var user = await dispatchers.QueryAsync(new GetUserByIdQuery { id = command.id });
if (user != null)
{
var u = new User();
var value = u.SetUser(user.Result.Id, user.Result.Email, user.Result.LastName, user.Result.Photo, user.Result.FirstName, user.Result.UserName, user.Result.PhoneNumber, !user.Result.IsActive);
await dispatchers.CallEvent(new UserActiveStateEvent { User = value });
return OperationResult<string>.BuildSuccessResult("success");
}
else
{
return OperationResult<string>.BuildFailure("fail");
}
}
}
}
this is that recoed and its correct :
"email": "kiadr9372#gmail.com",
"photo": null,
"lastName": "Dortaj",
"firstName": "Kianoush",
"userName": "kia9372",
"phoneNumber": "09159810616",
"securityStamp": "e7cd82a5-71f3-41a1-b239-4d705b6d5d35",
"isActive": false,
"phoneConfirm": false,
"emailConfirm": false,
"isLockOut": false,
"lockOutEnd": null,
"isFailurAccount": 0,
"userRoles": null,
"id": 1
step there :
i call Event for Update Record in database :
public class UserActiveStatusEventHandler : IEventHandler<UserActiveStateEvent> , IScopedDepency
{
private readonly IDomainUnitOfWork unitOfWork;
public UserActiveStatusEventHandler(IDomainUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
public async Task HandelEventAsync(UserActiveStateEvent #event)
{
var state = await unitOfWork.UserRepository.UpdateUser(#event.User);
if (state.Success)
{
unitOfWork.Commit();
}
}
}
this is the update code in repository :
public async Task<OperationResult<bool>> UpdateUser(User user)
{
if (user != null)
{
try
{
context.Update(user);
return OperationResult<bool>.BuildSuccessResult(true);
}
catch (Exception ex)
{
return OperationResult<bool>.BuildFailure(ex);
}
}
return OperationResult<bool>.BuildFailure("user Cannot be null");
}
and this is the commit code :
public void Commit()
{
context.SaveChanges();
}
this is User Aggregate :
public class User : AggregrateRoot, IAggregate
{
#region Backing Field
private string _email;
private string _photo;
private string _userName;
private string _phoneNumber;
private string _firstName;
private string _lastName;
private Guid _securityStamp;
private bool _isActive;
private bool _phoneConfirm;
private bool _emailConfirm;
private bool _isLockOut;
private DateTimeOffset? _lockOutEnd;
private int _isFailurAccount;
#endregion
#region Properies
public string Email
{
get
{
return _email;
}
private set
{
_email = value;
SetNotification();
}
}
public string Photo
{
get
{
return _photo;
}
set
{
_photo = value;
SetNotification();
}
}
public string LastName
{
get
{
return _lastName;
}
private set
{
_lastName = value;
SetNotification();
}
}
public string FirstName
{
get
{
return _firstName;
}
private set
{
_firstName = value;
SetNotification();
}
}
public string UserName
{
get
{
return _userName;
}
private set
{
_userName = value;
SetNotification();
}
}
public string PhoneNumber
{
get
{
return _phoneNumber;
}
private set
{
_phoneNumber = value;
SetNotification();
}
}
public Guid SecurityStamp
{
get
{
return _securityStamp;
}
private set
{
_securityStamp = value;
SetNotification();
}
}
public bool IsActive
{
get
{
return _isActive;
}
private set
{
_isActive = value;
SetNotification();
}
}
public bool PhoneConfirm
{
get
{
return _phoneConfirm;
}
private set
{
_phoneConfirm = value;
SetNotification();
}
}
public bool EmailConfirm
{
get
{
return _emailConfirm;
}
private set
{
_emailConfirm = value;
SetNotification();
}
}
public bool IsLockOut
{
get
{
return _isLockOut;
}
private set
{
_isLockOut = value;
SetNotification();
}
}
public DateTimeOffset? LockOutEnd
{
get
{
return _lockOutEnd;
}
private set
{
_lockOutEnd = value;
SetNotification();
}
}
public int IsFailurAccount
{
get
{
return _isFailurAccount;
}
private set
{
_isFailurAccount = value;
SetNotification();
}
}
public ICollection<UserRole> UserRoles { get; set; }
#endregion
public User()
{
}
#region Private Constructor
private User(long id,string Email, string LastName, string photo, string FirstName, string UserName, string PhoneNumber, bool isActive)
{
this.Email = Email;
this.Photo = photo;
this.LastName = LastName;
this.FirstName = FirstName;
this.UserName = UserName;
this.PhoneNumber = PhoneNumber;
this.SecurityStamp = Guid.NewGuid();
this.IsActive = isActive;
this.PhoneConfirm = false;
this.EmailConfirm = false;
this.IsLockOut = false;
this.LockOutEnd = null;
this.IsFailurAccount = 0;
}
#endregion
#region Methonds
public User SetUser(string email, string lastName, string photo, string firstName, string userName, string phoneNumber, bool isActive = false)
{
var user = new User(email, lastName, firstName, photo, userName, phoneNumber, isActive);
return user;
}
public UserRole AddUserRole(long userId, long roleId)
{
return new UserRole().AddUserRole(userId, roleId);
}
#endregion
}
but problem is here : i create a new recoed in datebase but i need update that recoed . how can i solve this problem ???
I guess your problem occurs in UserActiveStateCommandHandler class.
You're fetching User from DB which should be tracked by EF by default.
Later you're creating new User object instance and provide changes on new object which is not recognized by EF as existing one.
You should update data directly on object returned from your query...

c# error Inconsistent accessibility: parameter type 'HRDMSV1.User' is less accessible than method

I am having a problem with an error...
Error 1 Inconsistent accessibility: parameter type 'HRDMSV1.User' is less accessible than method 'HRDMSV1.FrmAddDoc.FrmAddDoc(HRDMSV1.User)'
All help appreciated?
namespace HRDMSV1
{
public partial class FrmAddDoc : Form
{
User _user;
private ConnStr connStr = new ConnStr();
public FrmAddDoc(User user) /* error here */
{
InitializeComponent();
_user = user;
}
/*...*/
}
class User
{
private String _userName;
private String _password;
private bool _readOnly;
private int _userID;
public String userName {
get { return _userName; }
set { _userName = value; }
}
public String password {
get { return _password; }
set { _password = value; }
}
public bool readOnly {
get { return _readOnly; }
set { _readOnly = value; }
}
public int userID {
get { return _userID; }
set { _userID = value; }
}
}
}
Your User class is less accesable than the public constructor FrmAddDoc which is not allowed. For more reference see CS0051

How do i get only one value from a parameter using x:bind

I am binding using x:bind which sends parameters as objects to the destination page. I want to retrieve just one value from the parameters. I am sending DetailItems as the parameter. how do i send just one item lets say firstName in DetailItems?
public void MediaPage() =>
NavigationService.Navigate(typeof(Views.MediaPage), DetailItems);
see the codes this one is from the viewModel and i am using template10
List<Details> _detail;
public List<Details> DetailItems { get { return _detail; } set { Set(ref _detail, value); } }
public class Details : BindableBase
{
string _Title = default(string);
public string Title { get { return _Title; } set { Set(ref _Title, value); } }
string _Image = default(string);
public string Image { get { return _Image; } set { Set(ref _Image, value); } }
string _Link = default(string);
public string Link { get { return _Link; } set { Set(ref _Link, value); } }
string _background = default(string);
public string Background { get { return _background; } set { Set(ref _background, value); } }
string _leftInfo = default(string);
public string LeftInfo { get { return _leftInfo; } set { Set(ref _leftInfo, value); } }
string _rightInfo = default(string);
public string RightInfo { get { return _rightInfo; } set { Set(ref _rightInfo, value); } }
string _description = default(string);
public string Description { get { return _description; } set { Set(ref _description, value); } }
}

MVVM: Raise PropertyChanged event for a DataContract class members

I want to raise PropertyChanged event for a model with DataContract.
Initially I did this
[DataContract]
public partial class User : INotifyPropertyChanged
{
[DataMember(Name="username")]
public string Username
{
get
{
return this.Username;
}
set
{
this.Username = value;
RaisePropertyChanged("Username");
}
}
}
which gave StackOverflow Exception beacause of Infinite Recursion.
So the solution I come up with is
[DataContract]
public partial class User : INotifyPropertyChanged
{
private string _Username { get; set; }
[DataMember(Name="username")]
public string Username
{
get
{
return this._Username;
}
set
{
this._Username = value;
RaisePropertyChanged("Username");
}
}
}
Although this reflects the Username value to the control binding to "Username", this doesn't look the best way to me. Something is wrong. Also my model has approx 30-40 fields. Is this the right approach or can someone please suggest me a better way.
Thanks
I'd be so tempted to use caller-member-name here (if it is in your target framework):
private string _username;
[DataMember(Name="username")]
public string Username
{
get { return _username; }
set { SetField(ref _username, value); }
}
private void SetField<T>(ref T field, T value,
[CallerMemberName] string memberName = null)
{
if(!EqualityComparer<T>.Default.Equals(field,value))
{
field = value;
RaisePropertyChanged(memberName);
}
}
If caller-member-name isn't supported:
[DataMember(Name="username")]
public string Username
{
get { return this._Username; }
set { SetField(ref _Username, value, "Username"); }
}
[DataContract]
public partial class User : INotifyPropertyChanged
{
private string _Username;
[DataMember(Name="username")]
public string Username
{
get
{
return this._Username;
}
set
{
if(this._Username != value)
{
this._Username = value;
RaisePropertyChanged("Username");
}
}
}
}

asp.net c# class properties stackoverflow exception

I have a very simple C# class:
namespace mybox
{
public class userAccount : IMyInterface
{
public userAccount()
{
}
private int _userId;
private string _userName;
public int userId
{
get { return _userId; }
set { userId = value; }
}
public string userName
{
get { return _userName; }
set { userName = value; }
}
public string list(int myUserId)
{
...
myOutPut = string.Format("{0} {1} {2}", u.userId, u.userName);
return myOutPut.ToString();
}
public void add()
{
pillboxDataContext db = new pillboxDataContext();
userAccount newUser = new userAccount();
newUser.userName = "test123";
db.SubmitChanges();
}
}
}
In my default.aspx.cs in the Page_Load event I'm trying to call the list method:
protected void Page_Load(object sender, EventArgs e)
{
pillbox.userAccount myUA = new pillbox.userAccount();
myUA.add();
// Console.WriteLine(myUA.list(1));
}
When I call the add method I can see that it is trying to assign the value test123 to the property but I get the following message:
An unhandled exception of type 'System.StackOverflowException' occurred in App_Code.1zm0trtk.dll
Any ideas of what I'm doing incorrectly?
The problem is with the way you defined your properties.
You are trying to refer to the property to which you are assigning the value in the setter
which is resulting in an infinte recursion (to be specific this line is triggering it newUser.userName = "test123";).
Change them to:
public int userId
{
get { return _userId; }
set { _userId = value; }
}
public string userName
{
get { return _userName; }
set { _userName = value; }
}
It is because userName calls itself. You probably meant to assign the field:
This line is wrong:
set { userName = value; }
You meant to write:
set { _userName = value; }
You need to set the private backing field, not the property. Otherwise you are just going into infinite recursion as you call set on yourself the entire time.
private int _userId;
private string _userName;
public int userId
{
get { return _userId; }
set { _userId = value; }
}
public string userName
{
get { return _userName; }
set { _userName = value; }
}
In your case, you could just use auto implemented properties (I changed the casing to match the guidelines):
public int UserId { get; set; }
public string UserName { get; set; }
If you re-write your setters a bit, it's easy to see what's happening. The get and set on a property are actually compiled down to methods (PropType get_PropName() and void set_PropName(PropType value)), and any references to the property are compiled to calls to the appropriate method. So this code:
int i = myObj.MyIntProp;
myObj.MyIntProp = 6;
compiles to
int i = myObj.get_MyIntProp();
myObj.set_MyIntProp(6);
So your setter
set
{
username = value;
}
actually compiles to
public void set_username(string value)
{
set_username(value);
}
And now the cause of the stack overflow is obvious.

Categories

Resources