Render enumeration value using code blocks - c#

I want the value of jsonStr to be
"{submitOfferResult: 0}"
instead though it is
"{submitOfferResult: OFFER_ACCEPTED}"
//javascript
var jsonStr = "{submitOfferResult: <%=SUBMIT_OFFER_RESULT.OFFER_ACCEPTED %>}";
//c#
public enum SUBMIT_OFFER_RESULT
{
OFFER_ACCEPTED = 0,
QUALIFYING_OFFER_NOT_MET = 1,
OFFER_ACCEPTED_NOT_HIGHEST_OFFER = 2,
OSP_CLOSED = 3,
AUTO_REJECTED = 4
}

Just cast to int:
var jsonStr = "{submitOfferResult: <%=(int) SUBMIT_OFFER_RESULT.OFFER_ACCEPTED %>}";
Otherwise it's calling ToString() on the enum value, which will use the name where possible.
Note that to follow .NET naming conventions, your enum would be:
public enum SubmitOfferResult
{
OfferAccepted = 0,
QualifyingOfferNotMet = 1,
OfferAcceptedNotHighestOffer = 2,
OspClosed = 3,
AutoRejected = 4
}
And then:
var jsonStr = "{submitOfferResult: <%=(int) SubmitOfferResult.OfferAccepted %>}";

You need to cast the enum to a numeric type:
(int)SUBMIT_OFFER_RESULT.OFFER_ACCEPTED

Related

Converting JSON to c# from the web

using (var webClient = new WebClient())
{
string rawJSON = webClient.DownloadString("http://data.nba.net/data/10s/prod/v1/calendar.json");
var jsonConverted = JsonConvert.DeserializeObject<NumGameByDate>(rawJSON);
}
Above is my code I am attempting to retrieve the date and number of games on that date. I have achieved this with the NBA's team json data but this one is formatted differently.
public class NumGameByDate
{
public _internal _internal { get; set; }
public string startDate { get; set; }
public string endDate { get; set; }
public string startDateCurrentSeason { get; set; }
}
This is my NumGameByDate class how would you suggest storing the dates and number of games. Below is an example of how the JSON looks.
{
"_internal": {
"pubDateTime": "2018-08-10 16:57:34.402",
"xslt": "xsl/league/schedule/marty_game_calendar.xsl",
"eventName": "_SPECIAL_ELA_EVENT_martyGameCalendar"
},
"startDate": "20171017",
"endDate": "20190410",
"startDateCurrentSeason": "20180702",
"20171017": 2,
"20171018": 11,
"20171019": 3,
"20171020": 10,
"20171021": 11,
"20171022": 3,
"20171023": 8,
"20171024": 6,
"20171025": 10,
I think you don't need the _internal part at all (if you do you could still parse with your rawJson and class). Then you could do something like this:
Dictionary<string,string> myData;
using (var webClient = new WebClient())
{
string rawJSON = webClient.DownloadString("http://data.nba.net/data/10s/prod/v1/calendar.json");
string myJSON = "{" + rawJSON.Substring(rawJSON.IndexOf(#"""startDate"));
myData = JsonConvert.DeserializeObject<Dictionary<string,string>>(myJSON);
}
This would skip the _internal part and parse the rest as a Dictionary (although you might get as Dictionary I prefer string, string).
Well, maybe javascript is better equipped if converting the file once by hand would suffice. Chances are you might need a more automatic approach.
// Load your JSON in variable x
var x = { "someOtherProperty": { etc:true }, "20171017": 2, "20171018": 11, "20171019": 3, "20171020": 10, "20171021": 11, "20171022": 3, "20171023": 8, "20171024": 6 }
x.games = [] // create an array that will hold the converted values.
for (key in x){
// Some regex testing if the current property is a date
if (/[2][0][01][0-9][0-1][0-9][0-3][0-9]/.test(key)){
x.games.push({ date: key, gameCount: x[key] }); // Put the new object in an actual array
delete x[key] // Delete the old value
}
}
This would result in the following JSON where the array is nicely populated:
x = {
"someOtherProperty": { etc:true },
"games":[{"date":"20171017","gameCount":2},{"date":"20171018","gameCount":11},{"date":"20171019","gameCount":3},{"date":"20171020","gameCount":10},{"date":"20171021","gameCount":11},{"date":"20171022","gameCount":3},{"date":"20171023","gameCount":8},{"date":"20171024","gameCount":6},{"date":"20171025","gameCount":10}]
}
Given all the comments, particularly one that skips deserializing to some POCO, you could do something like this:
//Dependency JSON.Net
var obj = JObject.Parse(your_sample_json_string);
foreach (var t in obj)
{
DateTime d;
if (DateTime.TryParseExact(t.Key, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out d))
{
Console.WriteLine("{0} = {1}", d.ToShortDateString(), t.Value);
}
}
Output:
10/17/2017 = 2
10/18/2017 = 11
10/19/2017 = 3
10/20/2017 = 10
10/21/2017 = 11
10/22/2017 = 3
10/23/2017 = 8
10/24/2017 = 6
10/25/2017 = 10
Improve as needed/necessary. Hth ~

C# using [Flags] with [Description]

I'm looking to combine the use of enumerations - with the bitwise [Flags] - as well as using a description of the combination of the results. I've looked into examples here using the Flags Attribute, and using the Description Attribute, but not both.
Something like:
[Flags]
public enum ReasonCode
{
[Description("Verified")]
None = 0,
[Description("Check A")]
Reason1 = 1,
[Description("Check B")]
Reason2 = 2,
[Description("Check C")]
Reason3 = 4,
[Description("Check D")]
Reason4 = 8,
[Description("Check E")]
Reason5 = 16,
[Description("Check F")]
Reason6 = 32,
[Description("Check G")]
Reason7 = 64
}
I need to specify all reasons why there was a failure. Using "Reason1", etc... isn't descriptive enough for what I am looking for. I would need a much more verbose description, like "Reason1 - Check A".
For Example:
A value of 5 would be Reason1 and Reason3.
The description would then be:
Failure:
Reason1 - Check A.
Reason3 - Check C.
Is is possible to do combine descriptions like flags?
Here's a more generic extension method that I have used which will deal with all enum values including flag combinations:
public static string GetDescription(this Enum value)
{
//pull out each value in case of flag enumeration
var values = value.ToString().Split(',').Select(s => s.Trim());
var type = value.GetType();
return string.Join(" | ", values.Select(enumValue => type.GetMember(enumValue)
.FirstOrDefault()
?.GetCustomAttribute<DescriptionAttribute>()
?.Description
?? enumValue.ToString()));
}
If a description attribute is not present then it will simply return the value itself.
In order to produce the result you are looking for, use the following code:
public static String GetDescription(ReasonCode reasonCode)
{
if (reasonCode == ReasonCode.None)
return "Verified";
StringBuilder sb = new StringBuilder();
sb.AppendLine("Failed:");
foreach (ReasonCode rc in Enum.GetValues(typeof(ReasonCode)).Cast<ReasonCode>())
{
if (rc == ReasonCode.None)
continue;
if (reasonCode.HasFlag(rc))
sb.AppendLine(rc.ToString() + " - " + GetEnumDescription(rc));
}
return sb.ToString();
}
The code used to retrieve the description value is based on this implementation:
public static String GetEnumDescription(Enum value)
{
String valueText = value.ToString();
Type type = value.GetType();
FieldInfo fi = type.GetField(valueText);
Object[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
{
DescriptionAttribute attribute = (DescriptionAttribute)attributes[0];
return attribute.Description;
}
return valueText;
}
You can find a working demo here.

Cast Int Array to Enum Flags

I have the following enum with flags:
[Flags]
public enum DataFiat {
Public = 1,
Listed = 2,
Client = 4
} // DataFiat
And I have an int array, for example:
int[] selected = new int[] { 1, 4 }
How can I convert this to my enum which would become:
DataFiat.Public | DataFiat.Client
Thank You,
Miguel
var f = (DataFiat)selected.Sum();
How about something like
var tt = (DataFiat)selected.Aggregate((i, t) => i | t);
this snippet:
var intArr = new[] { 1, 4 };
var sum = intArr.Sum(x => x);
var result = (Test)sum;
returns
DataFlat result = (DataFlat) 0;
foreach (var value in selected)
{
result |= (DataFlat)value;
}
Or if you want to use LINQ
DataFlat result = (DataFlat) selected.Aggregate(0, (old, current) => old | current);
You mean this?
IEnumerable<DataFiat> selectedDataFiats = selected.Cast<DataFiat>();
This sinmply casts each int to DataFiat.
You can't just cast the array, if it's really an object[]. You can create a new array pretty easily though:
var enumArray = originalArray.Cast<DataFiat>().ToArray();
If it were actually an int[] array to start with, you could cast - although you'd have to talk nicely to the C# compiler first:
using System;
class Program
{
enum Foo
{
Bar = 1,
Baz = 2
}
static void Main()
{
int[] ints = new int[] { 1, 2 };
Foo[] foos = (Foo[]) (object) ints;
foreach (var foo in foos)
{
Console.WriteLine(foo);
}
}
}
The C# compiler doesn't believe that there's a conversion from int[] to Foo[] (and there isn't, within the rules of C#)... but the CLR is fine with this conversion, so as long as you can persuade the C# compiler to play along (by casting to object first) it's fine.
This doesn't work when the original array is really an object[] though.
Hope this helps..

Refactoring code with the Extract method

In my application, we have a class which generates information within a database as static centralised data. This class is called 'GenerateOwner'. Within this class we are creating multiple entries of type 'FieldValidation'.
FieldValidation swedishFieldValidation1 = new FieldValidation
{
IsRequired = false,
DataType = "String",
Length = 0,
Min = 0,
Max = 255,
FieldValidationType = _bancPaydatabase.FieldValidationTypes.FirstOrDefault(o => o.FieldName == "InvoiceNumber"),
IsVisible = true,
Owner_Country = swedishOwnerCountry
};
FieldValidation swedishFieldValidation2 = new FieldValidation
{
IsRequired = false,
DataType = "String",
Length = 0,
Min = 0,
Max = 255,
FieldValidationType = _bancPaydatabase.FieldValidationTypes.FirstOrDefault(o => o.FieldName == "InvoiceTypeId"),
IsVisible = true,
Owner_Country = swedishOwnerCountry
};
And so on. There are about 20 or so entries all very much similar. My question is, how would I best refactor this code to prevent duplicating the same entries over and over? I have been pointed towards the Extract method, but I am unsure of how to implement this in my code. Thanks in advance.
Extract method is a refactoring method that extracts code into its own method. If the extracted part needs parameters they are passed as parameters to the method.
In your code the code is exactly the same except for the field name; The field name would be a parameter to your method.
The result would look like this:
private FieldValidation CreateFieldValidation(string fieldName)
{
return new FieldValidation
{
IsRequired = false,
DataType = "String",
Length = 0,
Min = 0,
Max = 255,
FieldValidationType =
_bancPaydatabase.FieldValidationTypes
.FirstOrDefault(o => o.FieldName == fieldName),
IsVisible = true,
Owner_Country = swedishOwnerCountry
};
}
Usage would be now like this:
FieldValidation swedishFieldValidation1 = CreateFieldValidation("InvoiceNumber");
FieldValidation swedishFieldValidation2 = CreateFieldValidation("InvoiceTypeId");
If owner country would need to change, too, you would also make it a parameter in the method.

Serialize C# Enum Definition to Json

Given the following in C#:
[Flags]
public enum MyFlags {
None = 0,
First = 1 << 0,
Second = 1 << 1,
Third = 1 << 2,
Fourth = 1 << 3
}
Are there any existing methods in ServiceStack.Text for serializing to the following JSON?
{
"MyFlags": {
"None": 0,
"First": 1,
"Second": 2,
"Third": 4,
"Fourth": 8
}
}
Currently I'm using the routine below, are there better ways to do this?
public static string ToJson(this Type type)
{
var stringBuilder = new StringBuilder();
Array values = Enum.GetValues(type);
stringBuilder.Append(string.Format(#"{{ ""{0}"": {{", type.Name));
foreach (Enum value in values)
{
stringBuilder.Append(
string.Format(
#"""{0}"": {1},",
Enum.GetName(typeof(Highlights), value),
Convert.ChangeType(value, value.GetTypeCode())));
}
stringBuilder.Remove(stringBuilder.Length - 1, 1);
stringBuilder.Append("}}");
return stringBuilder.ToString();
}
public static class EnumExtensions
{
public static string EnumToJson(this Type type)
{
if (!type.IsEnum)
throw new InvalidOperationException("enum expected");
var results =
Enum.GetValues(type).Cast<object>()
.ToDictionary(enumValue => enumValue.ToString(), enumValue => (int) enumValue);
return string.Format("{{ \"{0}\" : {1} }}", type.Name, Newtonsoft.Json.JsonConvert.SerializeObject(results));
}
}
Using a dictionary of to do the heavy lifting. Then using Newtonsoft's json convert to convert that to json. I just had to do a bit of wrapping to add the type name on.
You're better off populating a Dictionary<string,int> or a Typed DTO and serializing that.

Categories