Trouble populating a model with a dictionary item - c#

I have a couple of classes I'm having difficulty populating:
public class ta_Room
{
public string url { get; set; }
public double price { get; set; }
public string room_code { get; set; }
}
public class ta_Hotel2
{
public int hotel_id { get; set; }
public Dictionary<string, ta_Room> room_types { get; set; }
}
In my controller I have:
[HttpGet]
public ta_Hotel2 hotel_inventory() //int api_version, string lang)
{
{
ta_Room room = new ta_Room();
room.price = 23;
room.room_code = "1";
room.url = "http://www.nme.com";
ta_Hotel2 hotel = new ta_Hotel2();
hotel.room_types.Add("Single", room);
However I get a NullReferenceException on the last line above.
In the screenshot below, it shows both the hotel and room object have been created - can anyone please advise what I've done wrong please?
Thank you,
Mark

The error is due to the fact you are not building the instance of room_types inside ta_Hotel2. You should add a constructor as follows or just instantiate it within hotel_inventory():
public class ta_Hotel2
{
public int hotel_id { get; set; }
public Dictionary<string, ta_Room> room_types { get; set; }
public ta_Hotel2()
{
room_types = new Dictionary<string, ta_Room>();
}
}
Also note that, from an encapsulation point of view, I would also make the setter of room_types private after that. And, as a side note, I would also rename your classes and members as suggested here.

You cannot assign a value to hotel.room_types before you initialize. Like the way Efran suggest, use a public constructor in ta_Hotel2 class will solve your issue.

Related

Is is good practice to have same type of list in a class?

I have created a class and I'm putting a list of same type as a property of that class.
Is it good or bad practice?
I am putting the same type of list because of I want to manage everything by only one object.
I don't want to create a single object and a list of object of the same type.
Any help is highly appreciated!
class AssetSection
{
public string Code { get; set; }
public string Description { get; set; }
public string SITEID { get; set; }
public string PlantID { get; set; }
public string User { get; set; }
public string UpDateTime { get; set; }
public List<AssetSection> AssetSections { get; set; }
public AssetSection(string des, string code)
{
Description = des;
Code = code;
}
}
That's ok. If you can imagine, you can design and use it.
Let's talk about entity framework. We create 2 entities like this:
public class User : IdentityUser
{
[Key]
public string Id { get; set; }
public UserProfile Profile { get; set; }
}
public class UserProfile
{
[Key]
public string UserId { get; set; }
public User User { get; set; }
}
Now, when we try to get current user:
User user = await _userManager.GetUserAsync(User);
user becomes an instance of User class now. This instance has a property name Profile, and this property has another property name User which has a type User.
It's called mapping. So, to answer your question: You can use it. But I'm not saying it's good or not based on the way to design the model.
As a general observation, such a structure is known as a rose tree, or just a tree. It enables you to write code like this:
var t = new AssetSection("foo", "bar")
{
AssetSections = new List<AssetSection>
{
new AssetSection("baz", "qux")
{
new AssetSection("corge", "garply"),
new AssetSection("fred", "plugh")
{
AssetSections = new List<AssetSection>
{
new AssetSection("xyzzy", "thud")
}
}
},
new AssetSection("quux", "quuz")
{
new AssetSection("grault", "waldo")
}
}
};
If what you want to model is a tree-like structure like that, then it's fine. On the other hand, if such a hierarchy is not what you're trying to model, then it's likely to be confusing.
By the way, the code as proposed violates the .NET framework design guidelines:
DO NOT provide settable collection properties.
DO NOT use ArrayList or List<T> in public APIs

Overriding a base virtual property with a derived type is null when passing to JsonResult

I have 2 base classes which 1 for search criteria and other 1 for search results.
I also have 2 derived classes for User object versions of both of those.
When I put a breakpoint in the controller action I can see all properties are populated as I've hardcoded.
When I call this action directly in the browser, each of my derived object properties is null.
I'm guessing the JSON serialization is not able to tell the difference from the base class to the derived one.
Is there a way to solve this?
public class BaseSearchCriteria
{
public int Page { get; set; }
public int RecordsPerPage { get; set; }
}
public class BaseSearchResults
{
public int TotalResults { get; set; }
public virtual BaseSearchCriteria SearchCriteria { get; set; }
}
public class UserSearchCriteria : BaseSearchCriteria
{
public string Username { get; set; }
}
public class UserSearchResults : BaseSearchResults
{
public new UserSearchCriteria SearchCriteria { get; set; }
}
public JsonResult Search(UserSearchCriteria model)
{
var viewModel = new UserSearchResults
{
SearchCriteria = new UserSearchCriteria
{
Page = 1,
RecordsPerPage = 15
}
};
viewModel.TotalResults = 100;
return Json(viewModel, JsonRequestBehavior.AllowGet);
}
Maybe good way to deal with it is to use generics as Daniel A. White propose.
Sample gist here.

Facade a class without writing lots of boilerplate code?

Let's say I have a class from a 3rd-party, which is a data-model. It has perhaps 100 properties (some with public setters and getters, others with public getters but private setters). Let's call this class ContosoEmployeeModel
I want to facade this class with an interface (INavigationItem, which has Name and DBID properties) to allow it to be used in my application (it's a PowerShell provider, but that's not important right now). However, it also needs to be usable as a ContosoEmployeeModel.
My initial implementation looked like this:
public class ContosoEmployeeModel
{
// Note this class is not under my control. I'm supplied
// an instance of it that I have to work with.
public DateTime EmployeeDateOfBirth { get; set; }
// and 99 other properties.
}
public class FacadedEmployeeModel : ContosoEmployeeModel, INavigationItem
{
private ContosoEmployeeModel model;
public FacadedEmployeeModel(ContosoEmployeeModel model)
{
this.model = model;
}
// INavigationItem properties
string INavigationItem.Name { get; set;}
int INavigationItem.DBID { get; set;}
// ContosoEmployeeModel properties
public DateTime EmployeeDateOfBirth
{
get { return this.model.EmployeeDateOfBirth; }
set { this.model.EmployeeDateOfBirth = value; }
}
// And now write 99 more properties that look like this :-(
}
However, it's clear that this will involve writing a huge amount of boilerplate code to expose all the properties , and I'd rather avoid this if I can. I can T4 code-generate this code in a partial class, and will do if there aren't any better ideas, but I though I'd ask here to see if anyone had any better ideas using some super wizzy bit of C# magic
Please note - the API I use to obtain the ContosoEmployeeModel can only return a ContosoEmployeeModel - I can't extend it to return a FacededEmployeeModel, so wrapping the model is the only solution I can think of - I'm happy to be corrected though :)
The other approach may be suitable for you is to use AutoMapper to map base class to your facade here is sample code:
class Program
{
static void Main(string[] args)
{
var model = new Model { Count = 123, Date = DateTime.Now, Name = "Some name" };
Mapper.CreateMap<Model, FacadeForModel>();
var mappedObject = AutoMapper.Mapper.Map<FacadeForModel>(model);
Console.WriteLine(mappedObject);
Console.ReadLine();
}
class Model
{
public string Name { get; set; }
public DateTime Date { get; set; }
public int Count { get; set; }
}
interface INavigationItem
{
int Id { get; set; }
string OtherProp { get; set; }
}
class FacadeForModel : Model, INavigationItem
{
public int Id { get; set; }
public string OtherProp { get; set; }
}
}
Resharper allows the creation of "delegating members", which copies the interface of a contained object onto the containing object and tunnels the method calls/property access through to the contained object.
http://www.jetbrains.com/resharper/webhelp/Code_Generation__Delegating_Members.html
Once you've done that, you can then extract an interface on your proxy class.

Cloning A Class

I have two classes which contain the same fields, however one inherits some properties from somewhere else and the other does not.
I have created a generic list using the class "ZEUS_ResearchStocksHistory" , but then I need to clone all of the fields over to the other list "ZEUS_ResearchStocksHistoryWithExcel". I don't want to have to loop through each field in one list and populate the other, or write some sort of linq join, there must be a faster way?
The reason I can't use the same class in both instances is that when inheriting the ExcelReport function it adds additional fields which I do not want when I display this list in a data grid.
internal class ZEUS_ResearchStocksHistory
{
public String Amendment { get; set; }
public String AmendedBy { get; set; }
public String Sedol { get; set; }
public String Date { get; set; }
}
internal class ZEUS_ResearchStocksHistoryWithExcel : ExcelReport
{
public String Amendment { get; set; }
public String AmendedBy { get; set; }
public String Sedol { get; set; }
public String Date { get; set; }
}
Is this possible?
Thanks
Did you have a look at automapper?
example from codeproject:
CustomerViewItem customerViewItem =
Mapper.Map<Customer, CustomerViewItem>(customer);
Check out Automapper, which is designed to do exactly this. Automapper is up on NuGet.
http://lostechies.com/jimmybogard/2009/01/23/automapper-the-object-object-mapper/
You could do something as simple as:
Mapper.CreateMap<ZEUS_ResearchStocksHistory, ZEUS_ResearchStocksHistoryWithExcel>();
var newObject = Mapper.Map<ZEUS_ResearchStocksHistory, ZEUS_ResearchStocksHistoryWithExcel>(oldObject);
Or, since you said you have a list, you could do:
var newList = oldList.Select(x => Mapper.Map<ZEUS_ResearchStocksHistory, ZEUS_ResearchStocksHistoryWithExcel>(x));

C# nested class/struct visibility

I'm trying to figure out what the proper syntax is to achieve a certain API goal, however I am struggling with visibility.
I want to be able to access a Messenger instance's member like msgr.Title.ForSuccesses.
However, I do not want to be able to instantiate Messenger.Titles from outside my Messenger class.
I'm also open to making Messenger.Titles a struct.
I'm guessing I need some sort of factory pattern or something, but I really have no idea how I'd go about doing that.
See below:
class Program {
static void Main(string[] args) {
var m = new Messenger { Title = { ForErrors = "An unexpected error occurred ..." } }; // this should be allowed
var t = new Messenger.Titles(); // this should NOT be allowed
}
}
public class Messenger {
// I've tried making this private/protected/internal...
public class Titles {
public string ForSuccesses { get; set; }
public string ForNotifications { get; set; }
public string ForWarnings { get; set; }
public string ForErrors { get; set; }
// I've tried making this private/protected/internal as well...
public Titles() {}
}
public Titles Title { get; private set; }
public Messenger() {
Title = new Titles();
}
}
You just need to make Titles private and expose an interface instead of it.
class Program {
static void Main(string[] args) {
var m = new Messenger { Title = { ForErrors = "An unexpected error occurred ..." } }; // this is allowed
var t = new Messenger.Titles(); // this is NOT allowed
}
}
public class Messenger {
public interface ITitles {
string ForSuccesses { get; set; }
string ForNotifications { get; set; }
string ForWarnings { get; set; }
string ForErrors { get; set; }
}
private class Titles : ITitles {
public string ForSuccesses { get; set; }
public string ForNotifications { get; set; }
public string ForWarnings { get; set; }
public string ForErrors { get; set; }
}
public ITitles Title { get; private set; }
public Messenger() {
Title = new Titles();
}
}
If you make the Titles constructor internal you will be able to create instances of it within your assembly only. If it is an API, perhaps that will be protected enough? You can see this pattern within the BCL (such as HttpWebRequest that can be created only through calls to WebRequest.Create).
Why Would I Ever Need to Use C# Nested Classes Nested type is never intended to be initialized from external type.
Well, you could make Titles a struct and make the constructor either public or internal. In that way, every time a client gets a copy of the Titles instance through the Title property, they will be getting the value, not the reference. They could modify that value, but to apply that change to the internal state of your object, they would need to be able to set the value back again through the Title property. They can't, because you have the Title setter marked private.
You will have to do the same when you change a value internally. For example:
// Your constructor...
public Messenger()
{
Titles t = new Titles();
t.ForSuccesses = "blah";
Title = t;
}
You can do this internally because you have access to the private setter for the Title property.
The main downside is that it might confuse the clients of your framework a bit because it looks like you can set the values of the Titles instance, but there is no real way for them to commit that change back to the Messenger class.

Categories

Resources