Set Properties within base function and call function in child function inheritance - c#

I am trying to refactor some old code and wanted to create more logical inheritance.
We have struct Custom Class which we have separated into (3) levels:
AccountView > Details > Full with inheritance. We set the properties of each one as needed.
After looking at the setters, we wanted to combine them into a single class 'SetAccountProp' with methods that set the properties.
We have the 'CustomerBaseView' where we pass in Models ACCOUNT data which works.
Now for the CustomerDetailView pass the same Model ACCOUNT data, but we would like to fill the properties of 'CustomerBaseView' use function 'CustomerBaseView' then fill the details.
Also, for CustomerFullView pass the Model ACCOUNT data, and fill the properties of 'CustomerBaseView' THEN 'CustomerBaseView' and then the remaining fields for CustomerFullView.
How can I call and fill the 'CustomerBaseView' within the 'CustomerDetailView' function? Do I initialize new AccountsView(); in each function?
Not sure how to finish up the refactor without repeating the:
// -- CustomView <--- replace with func?
view.Email = data.Email;
view.Active = data.Active;
view.FirstName = data.FirstName;
view.LastName = data.LastName;
in the Details and Full functions.
CODE
namespace BLL.Presenters
{
public class AccountsView
{
public string Email { get; set; }
public bool Active { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Details : AccountsView
{
public bool Administrator { get; set; }
public DateTime? LastLogin { get; set; }
}
public class Full : Details
{
public Guid ID { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public string FullName { get; set; }
}
public class SetAccountProp
{
public static AccountsView CustomerBaseView(Account data)
{
var view = new AccountsView();
view.Email = data.Email;
view.Active = data.Active;
view.FirstName = data.FirstName;
view.LastName = data.LastName;
return view;
}
public static Details CustomerDetailView(Account data)
{
var view = new Details();
// -- CustomView <--- replace with func?
view.Email = data.Email;
view.Active = data.Active;
view.FirstName = data.FirstName;
view.LastName = data.LastName;
// -- Details
view.Administrator = data.Administrator;
view.LastLogin = data.LastLogin;
return view;
}
public static Full CustomerFullView(Account data)
{
var view = new Full();
// -- CustomView <--- replace with func?
view.Email = data.Email;
view.Active = data.Active;
view.FirstName = data.FirstName;
view.LastName = data.LastName;
// -- Details <--- replace with func?
view.Administrator = data.Administrator;
view.LastLogin = data.LastLogin;
// -- Full
view.ID = data.ID;
view.Created = data.Created;
view.Modified = data.Modified;
view.FullName = data.LastName + ", " + data.FirstName;
return view;
}
}
}

Using constructor chaining, you could have something like this:
Each constructor calls it's base class' constructor first, so you don't have to repeat code.
namespace BLL.Presenters
{
using System;
public class Account // dummy to make it compile
{
public string Email;
public bool Active;
public string FirstName;
public string LastName;
public bool Administrator;
public DateTime? LastLogin;
public Guid ID;
public DateTime Created;
public DateTime Modified;
}
public class AccountsView
{
public string Email { get; set; }
public bool Active { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public AccountsView(Account data)
{
this.Email = data.Email;
this.Active = data.Active;
this.FirstName = data.FirstName;
this.LastName = data.LastName;
}
}
public class Details : AccountsView
{
public bool Administrator { get; set; }
public DateTime? LastLogin { get; set; }
public Details(Account data) : base(data)
{
this.Administrator = data.Administrator;
this.LastLogin = data.LastLogin;
}
}
public class Full : Details
{
public Guid ID { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public string FullName { get; set; }
public Full(Account data) : base(data)
{
this.ID = data.ID;
this.Created = data.Created;
this.Modified = data.Modified;
this.FullName = data.LastName + ", " + data.FirstName;
}
}
class Program
{
static void Main()
{
Console.WriteLine();
Console.ReadLine();
}
}
}

Why not something like this:
public class CustomerBase
{
public string Email { get; private set; }
public bool Active { get; private set; }
public string FirstName { get; private set; }
public string LastName { get; private set; }
protected void SetAccountInfo(Account account)
{
this.Email = account.Email;
this.Active = account.Active;
this.FirstName = account.FirstName;
this.LastName = account.LastName;
}
}
public class CustomerA : CustomerBase
{
public string IsAdmin { get; private set; }
public DateTime? LastLogin { get; private set; }
public void SetAccountInfo(Account account)
{
base.SetAccountInfo(account);
this.IsAdmin = account.IsAdmin;
this.LastLogin = account.LastLogin;
}
}
public class Account
{
//your properties
public string Email { get; set; }
public bool Active { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string IsAdmin { get; set; }
public DateTime? LastLogin { get; set; }
}
Or let the SetAccountInfo() return this
public CustomerA SetAccountInfo(Account account)
{
base.SetAccountInfo(account);
this.IsAdmin = account.IsAdmin;
this.LastLogin = account.LastLogin;
return this;
}

Related

ASP.Net Core 5.0 Binding model to action with [Bind] attribute for nested child collection

I am trying to bind a model in a post action method. i.e binding with the help of [Bind] attribute.
Where I post some fields for parent while a collection of child properties at the same time.
Supose I have parent as following
class Parent
{
int field0;
string field1;
string field2;
ICollection<Child> Children;
}
class Child
{
int field3;
string field4;
string field5;
}
at the time of binding I can choose fields to bind for simple binding like [Bind("field1, field2")] and to include children as well then [Bind("field1,field2,children")]
But I need to include some fields of children like children("field4", "field5")
Is there any possibility so that I can write like following
public IActionResult UTOneFlight([Bind("field1, field2, children(field4, field5)")] Parent p)
{
}
UPDATE
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UTOneFlight([Bind("FlightID, SrcAirportID, DestAirportID, FlightDate, Sector, RegistrationNo, FlightNo, CallSign, CrewMembers, EmbDetails, UpdateRemarks")] FlightViewModel f)
{
if (f != null && f.EmbDetails != null)
{
if (f.FlightID == 0)
{
var flight = new Flight()
{
EmbDetails = new List<EmbDetail>(),
FlightType = "emb",
AirlineOperatorID = _user.OperatorID,
SrcAirportID = f.SrcAirportID,
DestAirportID = f.DestAirportID,
FlightDate = f.FlightDate,
Sector = f.Sector.ToString().ToLower()[0],
FlightNo = f.FlightNo.Trim().ToLower(),
CallSign = f.CallSign.Trim().ToLower(),
RegistrationNo = f.RegistrationNo.Trim().ToLower(),
CrewMembers = f.CrewMembers,
UpdateRemarks = f.UpdateRemarks?? f.UpdateRemarks,
EmbDataStatus = 'u',
CreatedBy = _user.UserID
};
foreach (var e in f.EmbDetails)
{
flight.EmbDetails.Add(
new EmbDetail()
{
PaxType = e.PaxType,
PaxClass = e.PaxClass,
AdultPax = e.AdultPax,
Infants = e.Infants,
Dips = e.Dips,
FOC = e.FOC,
TransferPax = e.TransferPax,
CreatedBy = _user.UserID
}
);
}
await _db.AddAsync(flight);
return RedirectToAction("Index");
}
else
{
//var flight = await _db.SingleAsync<Flight>(x => x.FlightID == f.FlightID);
//return RedirectToAction("Index");
}
}
else
return NotFound();
}
and my models are
public class FlightViewModel
{
public long FlightID { get; set; }
public int SrcAirportID { get; set; }
public int DestAirportID { get; set; }
public string RegistrationNo { get; set; }
public string FlightNo { get; set; }
public string CallSign { get; set; }
public DateTime FlightDate { get; set; }
public int CrewMembers { get; set; }
public char Sector { get; set; }
public string UpdateRemarks { get; set; }
public ICollection<EmbDetViewModel> EmbDetails { get; set; }
}
and
public class EmbDetViewModel
{
public string PaxType { get; set; }
public char PaxClass { get; set; }
public int AdultPax { get; set; }
public int Infants { get; set; }
public int Dips { get; set; }
public int Crew { get; set; }
public int FOC { get; set; }
public int TransferPax { get; set; }
}
I need to write signature of the method like
public async Task<IActionResult> UTOneFlight([Bind("FlightID, SrcAirportID, DestAirportID, FlightDate, Sector, RegistrationNo, FlightNo, CallSign, CrewMembers, EmbDetails(PaxType, PaxClass), UpdateRemarks")] FlightViewModel f)
Please have a look at
EmbDetails(PaxType, PaxClass)
How do you send your request body? I test in my side and here's the result.
My model:
public class ParentTestModel
{
public int id { get; set; }
public ICollection<TestModel> testModels { get; set; }
}
public class TestModel
{
public string prefix { get; set; }
}
==============================Update=============================
I test in my side with [JsonIgnore] and the property which added this annotation will be ignored and this is suitable when the request body is a json object like the screenshot above. And if you are sending the request in form-data then you can use [Bind] annotation, I think you may have referred to this document.

Unable to set public properties on instance of C# Class

I'm trying try to write my first NSpec test in a Mobile Service application. I created an attribute in the spec. But when I try to access that element on the next line I can't access the public properties on the instance because Visual Studio is not recognizing the variable.
AppointmentSpec.cs
public class AppointmentSpec : nspec
{
private AppointmentDTO _dto = new AppointmentDTO();
_dto.PatientId = "124234"; // Visual Studio is not regonizing _dto
}
AppointmentDTO.cs
public class AppointmentDTO
{
public string PatientId { get; set; }
// public string PathwayId { get; set; }
public string ItemId { get; set; }
public string Subject { get; set; } //Dr. Visit, labtest, labtest name, follow up, other...
// public string ProviderName { get; set; }
public string Location { get; set; } //clinic, hsopital name, etc
public string Address { get; set; } //street address
public string PhoneNumber { get; set; }
//to automatically add a corresponding appointment to the provider's calendar
public bool SetProviderAppointment { get; set; }
public string ProviderItemId { get; set; }
public List<string> ProviderItemIds { get; set; }
public bool IsVideoCall { get; set; }
public TimeSpan StartTime { get; set; }
public TimeSpan EndTime { get; set; }
public DateScheduleInfo EventDateSchedule { get; set; }
//public TimeScheduleInfo EventTimeSchedule { get; set; }
//public void Send(object target, string methodName, params object[] args)
//{
// var properties = GetProperties(target.GetType());
// var property = properties.First(p => p.Name == methodName);
// if(property == null)
// throw new ArgumentException($"{target.GetType()} has no property or method ");
// property.SetValue(target, args.First());
//}
//private static IEnumerable<PropertyInfo> GetProperties(Type t)
//{
// return t == null ? Enumerable.Empty<PropertyInfo>() : t.GetProperties().Union(GetProperties(t.BaseType));
//}
}
Do the assignment inside the constructor of the class:
public class AppointmentSpec : nspec
{
private AppointmentDTO _dto = new AppointmentDTO();
public AppointmentSpec()
{
_dto.PatientId = "124234";
}
}
You're accessing _dto in an invalid context. If you meant to initialize PatientId with some data, try this:
private AppointmentDTO _dto = new AppointmentDTO
{
PatientId = "124234"
};
See MSDN

Is there any way to make enum display spaces and images?

I am using enum for my group description in listview and I am trying to make it display some more user friendly text but I getting an error which says cannot implicitly convert type string to Mærke
Enum
public enum Mærke {
Alfa_Romeo,
Audi,
Aston_Martin__________________________________________________________5x114,
BMW,
Chervolet,
Chrysler,
Citroën,
Daewoo,
Daihatsu,
Dodge,
Ferrari };
public Mærke mærke { get; set; }
Class
public class biler
{
public string billed { get; set; }
public string Model { get; set; }
public string Type { get; set; }
public string Årgang { get; set; }
public string Krydsmål { get; set; }
public double ET { get; set; }
public double centerhul { get; set; }
public string bolter { get; set; }
public string hjul { get; set; }
public Mærke mærke { get; set; }
}
List
items.Add(new biler() { billed = "img/Biler/aston martin.png", Model = "DB9", Årgang = "03-", Krydsmål = "5x114.3", ET = 62.5, centerhul = 68.1, bolter = "M14x2", mærke = Mærke.Aston_Martin__________________________________________________________________________________________________5x114 });
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView (hjuldata.ItemsSource);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("mærke");
view.GroupDescriptions.Add(groupDescription);
var mærke = Merke.Alfa_Romeo; // example
var withSpaces = mærke.ToString().Replace("_", " ");
This should solve it for you. There's nothing built-in to do that so you COULD write an extension method like such:
public static string WithSpaces(this enum theEnum){
return theEnum.ToString().Replace("_", " ");
}
and then just use that in your code:
var mærke = Mærke.Alfa_Romeo.WithSpaces();
this should do it if that is what you are looking for and as for the picture i dont think headers supports that
using System.Reflection;
public static class EnumExtensions
{
public static string DisplayName(this Enum value)
{
FieldInfo field = value.GetType().GetField(value.ToString());
EnumDisplayNameAttribute attribute
= Attribute.GetCustomAttribute(field, typeof(EnumDisplayNameAttribute))
as EnumDisplayNameAttribute;
return attribute == null ? value.ToString() : attribute.DisplayName;
}
}
public class EnumDisplayNameAttribute : Attribute
{
private string _displayName;
public string DisplayName
{
get { return _displayName; }
set { _displayName = value; }
}
}
public enum Mærke
{
[EnumDisplayName(DisplayName = "Alfa Romeo 5x114")]
Alfa_Romeo,
public string mærke { get; set; }
mærke = Mærke.Alfa_Romeo.DisplayName()

Entity Framework N- Layer no binding with datagridview

I have a layer of Data like this to bring me all Admins:
public List<Datos_Admin> SelectAllAdmin()
{
return (from u in contexto.Datos_Admin select u).ToList() ;
}
In my layer of Entities have this:
public class EDatos_Admin
{
public int Id_Admin { get; set; }
public string User_Name { get; set; }
public char Password { get; set; }
public string Nombre { get; set; }
public string Ap_Paterno { get; set; }
public string Ap_Materno { get; set; }
public DateTime Fecha_Alta { get; set; }
public DateTime Fecha_Modificacion { get; set; }
public int UserAdmin_Modificacion { get; set; }
public bool Activo { get; set; }
public EDatos_Admin(int Id_Admin, string User_Name, char Password, string Nombre, string Ap_Paterno, string Ap_Materno, DateTime Fecha_Alta, DateTime Fecha_Modificacion, int UserAdmin_Modificacion, bool Activo)
{
this.Id_Admin = Id_Admin;
this.User_Name = User_Name;
this.Password = Password;
this.Nombre = Nombre;
this.Ap_Paterno = Ap_Paterno;
this.Ap_Materno = Ap_Materno;
this.Fecha_Alta = Fecha_Alta;
this.Fecha_Modificacion = Fecha_Modificacion;
this.UserAdmin_Modificacion = UserAdmin_Modificacion;
this.Activo = Activo;
}
public EDatos_Admin()
{
// TODO: Complete member initialization
}
}
And in my Bussines layer have this:
public EDatos_Admin SeleccionaAllDatos_Admin()
{
foreach (var n in contexto.SelectAllAdmin())
{
listDatosAdmin = new EDatos_Admin()
{
Id_Admin = n.Id_Admin,
User_Name = n.User_Name,
};
}
return listDatosAdmin;
}
In the datagridview only I want show me Id_Admin and User_Name but it doesn't. And when I review in debugging I can see the data but the datagridview doesn't work.
And I call the method SeleccionaAllDatos_Admin in my Bussines layer like this in the load form
dataGridView1.DataSource = new NDatos_Admin().SeleccionaAllDatos_Admin();
How can fixed?
Thanks

Constructor with argument :Missing return int value

I have class which contains many properties:
public class Report
{
public int reportId { get; set; }
public string sentDate { get; set; }
public string photoName { get; set; }
public string state { get; set; }
public string patientName { get; set; }
public string doctorName { get; set; }
public string sex { get; set; }
public int isPregnant { get; set; }
public float weight { get; set; }
public float height { get; set; }
public int age { get; set; }
public string information { get; set; }
public string response { get; set; }
then I implement one constructor with argmuents :
public Report(int id, string photoName, string sentDate, string state,string response)
{
this.reportId = id;
this.photoName = photoName;
this.sentDate = sentDate;
this.state = state;
this.response = response;
}
finally I implement method which calls this constructor :
public static List<Report> GetListReportByEmail(string email)
{
DataTable dt = SqlHelper.ExecuteDataset(
new SqlConnection(Tls.ConnStr),
"spReportGetByEmail",
email).Tables[0];
List<Report> tempItems = new List<Report>();
if (dt.Rows.Count != 0)
{
foreach (DataRow rw in dt.Rows)
{
tempItems.Add(
new Report(
int.Parse(rw["ReportId"].ToString()),
Tls.GetBasicUrl() + "/Zdnn000kjUpload/__zd__MedicalConsultation/"
+ rw["PhotoName"].ToString(),
DateTime.Parse(rw["SentDate"].ToString()).ToString("dd/M/yyyy"),
rw["State"].ToString(),
rw["Response"].ToString()));
}
return tempItems;
}
else
{
return null;
}
}
but when I check the return, in addition of the properties mentionned in the constructor I found all properties which its type is int or float with the value 0.
I need this methods for a web services. when I test this web serives I found properties mentionned in the constructor ,but also int and float which are not populated:
<Report>
<reportId>4</reportId>
<sentDate>21/6/2014</sentDate>
<photoName>
http://localhost:2055/Zdnn000kjUpload/__zd__MedicalConsultation/
</photoName>
<state/>
<isPregnant>0</isPregnant>
<weight>0</weight>
<height>0</height>
<age>0</age>
<response/>
</Report>
Knowing that the stored procedure is ok.
So can any one help me to transmit only variables mentionned in the constructor : I don't need age,height,weight,isPregnant to be transmitted
Thanks.
Your constructor only assigns the following:
this.reportId = id;
this.photoName = photoName;
this.sentDate = sentDate;
this.state = state;
this.response = response;
Why would you expect the other properties (isPregnant, weight, height, age, etc.) to be populated as well? You are not assigning those properties value at any point.

Categories

Resources