How can I compare the value of this enum
public enum AccountType
{
Retailer = 1,
Customer = 2,
Manager = 3,
Employee = 4
}
I am trying to compare the value of this enum in an MVC4 controller like so:
if (userProfile.AccountType.ToString() == "Retailer")
{
return RedirectToAction("Create", "Retailer");
}
return RedirectToAction("Index", "Home");
I also tried this
if (userProfile.AccountType.Equals(1))
{
return RedirectToAction("Create", "Retailer");
}
return RedirectToAction("Index", "Home");
In each case I get an Object reference not set to an instance of an object.
use this
if (userProfile.AccountType == AccountType.Retailer)
{
...
}
If you want to get int from your AccountType enum and compare it (don't know why) do this:
if((int)userProfile.AccountType == 1)
{
...
}
Objet reference not set to an instance of an object exception is because your userProfile is null and you are getting property of null. Check in debug why it's not set.
EDIT (thanks to #Rik and #KonradMorawski) :
Maybe you can do some check before:
if(userProfile!=null)
{
}
or
if(userProfile==null)
{
throw new ArgumentNullException(nameof(userProfile)); // or any other exception
}
You can use Enum.Parse like, if it is string
AccountType account = (AccountType)Enum.Parse(typeof(AccountType), "Retailer")
Comparision:
if (userProfile.AccountType == AccountType.Retailer)
{
//your code
}
In case to prevent the NullPointerException you could add the following condition before comparing the AccountType:
if(userProfile != null)
{
if (userProfile.AccountType == AccountType.Retailer)
{
//your code
}
}
or shorter version:
if (userProfile !=null && userProfile.AccountType == AccountType.Retailer)
{
//your code
}
You can use extension methods to do the same thing with less code.
public enum AccountType
{
Retailer = 1,
Customer = 2,
Manager = 3,
Employee = 4
}
static class AccountTypeMethods
{
public static bool IsRetailer(this AccountType ac)
{
return ac == AccountType.Retailer;
}
}
And to use:
if (userProfile.AccountType.isRetailer())
{
//your code
}
I would recommend to rename the AccountType to Account. It's not a name convention.
You should convert the string to an enumeration value before comparing.
Enum.TryParse("Retailer", out AccountType accountType);
Then
if (userProfile?.AccountType == accountType)
{
//your code
}
Related
Imagine that I want to validate if the object is null and I have 3 methods that will help me, such:
GetCompanyBySystemId();
GetCompanyById();
GetCompanyByName();
So, first I'll try to get the Company by system Id, if it's null I'll try to get it by Id, and, last but not least, I'll try to get it by Name.
My question is, what is the best practice to validate the company without doing this:
var company = GetCompanyBySystemId(string);
if (company == null)
{
company = GetCompanyById(string);
}
if (company == null)
{
company = GetCompanyByName(string);
}
...
You may use the null-coalescing-operator:
var company = GetCompanyBySystemId(#string) ??
GetCompanyById(#string) ??
GetCompanyByName(#string) ??
throw new InvalidOperatonException($"No company found for { #string }");
Also notice I added # as string is a reserved keyword and therefor not allowed as variable-name.
I always like the Try* paradigm (like int.TryParse) when you are stating that something may or may not be available, and you won't know at runtime:
public static void Main()
{
string id = "test";
object company = null;
if(!TryGetCompanyBySystemId(id, out company)
&& !TryGetCompanyById(id, out company)
&& !TryGetCompanyByName(id, out company))
{
//we've failed entirely
}
else
{
//we got a company
}
}
public static bool TryGetCompanyBySystemId(string id, out object company)
{
company = null;
//locate company and return true if found
return false;
}
public static bool TryGetCompanyById(string id, out object company)
{
company = null;
//locate company and return true if found
return false;
}
public static bool TryGetCompanyByName(string id, out object company)
{
company = null;
//locate company and return true if found
return false;
}
If you often have to seach for Company in such a way, I suggest extrcating a method in which we can hide all the details:
public static Company GetCompany(string idOrName) {
if (value is null)
throw new ArgumentNullException(nameof(idOrName));
var result = GetCompanyBySystemId(idOrName) ??
GetCompanyById(idOrName) ??
GetCompanyByName(idOrName);
return result != null
? result
: throw new ArgumentException($"Company with id or name {idOrName} is not found.",
nameof(idOrName));
}
Then whenever you want a company just get it:
// Just find me the company by string and don't make we think
// names, ids etc. things
Company company = GetCompany(#string);
In case not finding company is normal situation, you can implement TryGetCompany:
public static bool TryGetCompany(string idOrName, Company company) {
// Still exceptional situaltion
if (value == null)
throw new ArgumentNullException(nameof(idOrName));
company = GetCompanyBySystemId(idOrName) ??
GetCompanyById(idOrName) ??
GetCompanyByName(idOrName);
return company != null;
}
usage
if (TryGetCompany(#string, out var company)) {
// company with id or name string has been found and put into company
}
else {
// company with id or name string has not been found
}
I want to post the following DTO to a .NET Core API:
{
"Name": "Foo",
"Street": "Bar",
"DynamicInfo": {
"MetadataAsString": "23423",
"MetadataAsInt": 2,
"MetadataAsBool": true,
"SomeOtherValues": "blub"
}
}
The class I want to map this in C# looks like this:
public class Foo
{
public string Name { get; set; }
public string Street { get; set; }
public Dictionary<string, object> DynamicInfo { get; set; }
}
You can see that I am using two static properties (Name and Street), but I also want to post some dynamic data.
I expect the dynamic data to be written in a dictionary, but unfortunately this does not work.
The result I am getting in my debugger is a little confusing:
So the values arrive successful, but are in a strange format... I dont know how to even access the values.
How can I convert this to just a normal dictionary, containing objects?
For a solution that would not depend on your use case, I would use 2 objects. 1 for client input and 1 that has validated input. The client input object would contain a Dictionary<string,string>. And the validated input can contain your Dictionary<string,object> if its still something you intend to use.
If you use this approach. During validation of the client input, you could use bool.TryParse(DynamicInfo["MetadataAsBool"], out YourBoolean). Then simply add the YourBoolean to your new Dictionary<string,object> objectDictionary like objectDictionary.Add("BoolMetadata", YourBoolean)
I found a solution. The resulting object (ValueKind=String: 23423) is nothing else than a JSONElement. I did not understand this before.
This JSONElement has an enum that tells me what datatype I have, so I can use this to map my Dictionary of JSONElements to another dictionary of "real" objects.
var newDic = new Dictionary<string, object>();
foreach (var d in obj.DynamicInfo)
{
object obt;
string key = d.Key;
var a = enterprise.BasicInformation.TryGetValue(key, out obt);
if (obt == null) continue;
var doc = (JsonElement)obt;
string myString = null;
bool? myBool = null;
int? myInteger = null;
double? myFloatNumber = null;
if (doc.ValueKind == JsonValueKind.String)
{
myString = doc.ToString();
}
if (doc.ValueKind == JsonValueKind.True)
{
myBool = true;
}
if (doc.ValueKind == JsonValueKind.False)
{
myBool = false;
}
if (doc.ValueKind == JsonValueKind.Number)
{
double floatNumber;
doc.TryGetDouble(out floatNumber);
if ((floatNumber % 1) == 0)
{
myInteger = (int)floatNumber;
}
else
{
myFloatNumber = floatNumber;
}
}
if (myString != null)
{
newDic.Add(key, myString);
}
if (myBool != null)
{
newDic.Add(key, myBool);
}
if (myInteger != null)
{
newDic.Add(key, myInteger);
}
if (myFloatNumber != null)
{
newDic.Add(key, myFloatNumber);
}
}
The code might not be perfect - I will try to optimize it. But it does what it should.
I am building a simple MVC CRUD without using a database, but just making methods in a Repository model class.
To make it easier to understand i have 2 model classes. MyNote in which i have some properties and NoteRepository in which i have a list with the properties.
Then I've made a NoteController and i have already made Get and Create methods, but i can't seem to figure out what to write to make an Edit and Delete method? Hope you guys can help.
Here you will see some of the code from my project:
[HttpPost]
public ActionResult Create(MyNote mn)
{
try
{
note.Create(mn);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
this is the create from the Controller.
public static List<MyNote> notes = new List<MyNote>();
public NoteRepository()
{
notes.Add(new MyNote() { ID = 1, Titel = "Morgenmad", OprettelsesDato = DateTime.Now, Note = "Spis morgenmad i dag" });
notes.Add(new MyNote() { ID = 2, Titel = "Frokost", OprettelsesDato = DateTime.Now, Note = "Spis frokost i dag" });
notes.Add(new MyNote() { ID = 3, Titel = "Aftensmad", OprettelsesDato = DateTime.Now, Note = "Spis aftensmad i dag" });
}
public void Create(MyNote mn)
{
notes.Add(mn);
}
here is the repository class with the list and the method for the create method.
and please, ask if i have missed something! Thank you :-)
It looks like you're using a List for your in-memory repository. For delete, you can implement something like this:
public bool Delete (MyNote noteToDelete) {
return notes.Remove(noteToDelete);
}
Edit: However, in this case, the list will check for reference equality. Since you have an ID, which I will assume is unique, you can instead do this:
public bool Delete(MyNote noteToDelete) {
var matchingNote = notes.FirstOrDefault(n => n.ID == noteToDelete.ID);
return notes.Remove(matchingNote);
}
You could also implement IEquatable on your MyNote class to change how your notes are compared with each other, and return a valid match when the IDs are the same.
For the IEquatable example, you would want to change the class definition for MyNote to look like:
public class MyNote : IEquatable<MyNote>
and add in the following code to the MyNote class:
public override bool Equals(object obj) {
if (obj == null) return false;
Part objAsNote = obj as MyNote;
if (objAsNote == null) return false;
else return Equals(objAsNote);
}
public bool Equals(MyNote otherNote) {
if(otherNote == null) return false;
return (this.ID.Equals(otherNote.ID));
}
public override int GetHashCode(){
return this.ID;
}
You can do something like this:
public ActionResult Edit(MyNote noteToEdit)
{
var oldNote = notes.FirstOrDefault(n => n.Id == noteToEdit.Id);
if(oldNote == null)
return View(); //With some error message;
oldNote.Title = noteToEdit.Title;
oldNote.OprettelsesDato = DateTime.Now;
oldNote.Note = noteToEdit.Note;
return RedirectToAction("Index", "Note");
}
public ActionResult Delete(int id)
{
var noteToRemove = notes.FirstOrDefault(x => x.Id == id);
if(noteToRemove == null)
return View(); //With some error message;
notes.Remove(noteToRemove);
return RedirectToAction("Index", "Note");
}
When you are editing your note, i recommend you to use AutoMapper to make your code more easy to maintain.
I have created a list which has soundfragments and contains different fragments with each a unique number.
I need to search for a unique number in the list I made (Soundfragment), if the number is found then I need to return the found number. If it isn't found then I have to return null.
How do I search for a unique number in my list?
class BGExperience
{
private List<Soundfragment> fragmenten; // = new List<Soundfragment>();
private String theme;
/******** constructoren ***************************************************/
public BGExperience(String theme)
{
fragmenten = new List<Soundfragment>();
this.theme = theme;
}
/******** properties ********************************************************/
public String Theme
{
get { return Theme; }
}
/******** methoden ********************************************************/
// returns Soundfragment with nummber nr
// if it is unkown return null
public Soundfragment GetFragment(int nr)
{
}
// returns list with all fragments
public List<Geluidsfragment> GetAlleFragmenten()
{
return fragmenten;
}
You can do the GetFragment method using linq...
var result = fragmenten.Where(s => s.NumberSoundFragment == nr).ToList();
Then you can check if result has no items, return null, and if not, just return the first item!
public Soundfragment GetFragment(int nr)
{
var sFragment = fragmenten.Where(f => f.Number == nr);
if(sFragment.Any()) return sFragment.First();
else return null;
}
I assumed your Soundfragment class has Number property.If it is different change it to your property name.
Or you can do it with one line:
public Soundfragment GetFragment(int nr)
{
return fragmenten.Where(f => f.Number == nr).FirstOrDefault();
}
Using the sample code at http://erikpool.blogspot.com/2011/03/filtering-generated-entities-with.html I have altered this so that GenerateEntity and GenerateOptionSet to have the code:
return optionSetMetadata.Name.ToLowerInvariant().StartsWith("myprefix");
This generates the types including some enumerations for the optionsets. The actual implementation of the optionset in the entity doesn't use this however, but I get the following:
[Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("myprefix_fieldname")]
public Microsoft.Xrm.Sdk.OptionSetValue myprefix_FieldName
{
get
{
Microsoft.Xrm.Sdk.OptionSetValue optionSet = this.GetAttributeValue<Microsoft.Xrm.Sdk.OptionSetValue>("myprefix_fieldname");
if ((optionSet != null))
{
return ((Microsoft.Xrm.Sdk.OptionSetValue)(System.Enum.ToObject(typeof(Microsoft.Xrm.Sdk.OptionSetValue), optionSet.Value)));
}
else
{
return null;
}
}
set
{
this.OnPropertyChanging("myprefix_FieldName");
if ((value == null))
{
this.SetAttributeValue("myprefix_fieldname", null);
}
else
{
this.SetAttributeValue("myprefix_fieldname", new Microsoft.Xrm.Sdk.OptionSetValue(((int)(value))));
}
this.OnPropertyChanged("myprefix_FieldName");
}
}
Obviously casting the OptionSetValue to an int in the setter does not compile, I assume that it should be generating the property with a type that matches the generated enum, but isn't. What do I need to do to correct this?
It looks like there was a bug in the crmsrvcutil that has since been fixed. My code for OptionSet properties now looks like this:
[Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("prioritycode")]
public Microsoft.Xrm.Sdk.OptionSetValue PriorityCode
{
get
{
return this.GetAttributeValue<Microsoft.Xrm.Sdk.OptionSetValue>("prioritycode");
}
set
{
this.OnPropertyChanging("PriorityCode");
this.SetAttributeValue("prioritycode", value);
this.OnPropertyChanged("PriorityCode");
}
}
And I get no error setting the OptionSetValue...