c# WebApi serialization of decimal - c#

I have a WebApi Controller which returns a List. My problem is, that I do not want xxxx.0 in the resulting JSON as this makes serious problems in my javascript. Is there a way to prevent .net serialization with .0 values so that they get truncated?
Current output:
{"Temperature":[[1465434000.0,4.00],[1465437600.0,15.40],[1465441200.0,15.26],
Wanted:
{"Temperature":[[1465434000,4.00],[1465437600,15.40],[1465441200,15.26],
Object which is serialized:
public class ChartDataMonthly
{
public List<decimal[]> Temperature { get; set; }

public class ChartDataMonthly
{
public List<decimal[]> Temperature { get; set; }
public List<decimal[]> Round()
{
List<decimal[]> NewTemp = new List<decimal[]>();
foreach(var t in Temperature)
{
t[0] = Math.Round(t[0], 0);
NewTemp.Add(t)
}
return NewTemp;
}
}
I saw a new answer similar to this one get posted about two minutes before mine, but this is roughly how I would start. You can either use the return List or Json.SerializeObject and return the string by modifying the method slightly to return a string similar to #dckuehn's answer.

I guess where I would start is to create a new property on your object for your javascript model:
public class ChartDataMonthly
{
public List<decimal[]> Temperature { get; set; }
// This can be "unmapped" to ignore object mappers
public List<string> RoundedTemperature
{
get
{
return Temperature.Select(t => Math.Round(t).ToString()).ToList();
}
}
// rest of model
}

public class ChartDataMonthly
{
public List<decimal[]> _temperature;
public List<decimal[]> Temperature
{
get { return _temperature; }
set
{
_temperature = value;
//edit each value by reference
_temperature.ForEach(x => x.ToList().ForEach(y =>y= Convert.ToDecimal(Math.Round(Convert.ToDouble(y)))));
}
}
}
Untested but i think it should do the work automatically
You just round every field of each array in your list.
If you do it inside a setter/getter it will automatically do it when the .net binder bind the JavaScript to your object

Related

Converting list of one class to list of another class?

I am calling a stored procedure from Entity Framework and trying to get result of stored procedure in a model-view class but I am getting error while casting list of Result class I got from entity framework -
Below code I tried, but I am getting error while trying to cast, I tried other way also like ConvertAll<> but didn't work -
public List<DepartmentModelView> GetDepartmentData()
{
using (Model1Container obj = new Model1Container())
{
return obj.usp_getDepartment().ToList<usp_getDepartment_Result>().Cast<DepartmentModelView>.ToList();
}
}
This is the auto generated result class in Model.tt
namespace MvcApplication4.Models
{
using System;
public partial class usp_getDepartment_Result
{
public Nullable<int> Depid { get; set; }
public string DepName { get; set; }
}
}
But I want it to be returned in DepartmentModelView class-
public class DepartmentModelView
{
public Nullable<int> Depid { get; set; }
public string DepName { get; set; }
}
Please suggest how could I do this ?
If the rest of your Code works, you can use the Linq-Select-Projection:
public List<DepartmentModelView> GetDepartmentData()
{
using (Model1Container obj = new Model1Container())
{
return obj.usp_getDepartment().ToList<usp_getDepartment_Result>().Select(m=>new DepartmentModelView{Depid=m.Depid, DepName=m.DepName}).ToList();
}
}
You could implement implicit cast in another partial file for usp_getDepartment_Result:
namespace MvcApplication4.Models
{
public partial class usp_getDepartment_Result
{
static public implicit operator DepartmentModelView(usp_getDepartment_Result input)
{
return new DepartmentModelView
{
Depid = input.Depid,
DepName = input.DepName
};
}
}
}
Then your existing code ought to work.
Use AutoMapper (from Nuget). You can create a map from one class to another and you can do all kinds of manipulation during the mapping operation for cases where it isn't a straightforward copy of properties like this one.
And for simple cases like this one, Automapper will autowire up the conversion when it finds properties with the same names and types.

Runtime property override in order to fetch historical data

I'm currently finishing work on object change log functionality and would like to polish few things. Since we have a lot of web forms/reports where historical data should appear, I'm wondering if there is a way to implement that without changing controls/reports.
Currently, I have this situation:
public class Foo {
public string Property1 { get; set; }
public DateTime CreatedDate { get; set;}
public string GetHistoricalValue(string propertyName)
{
HistoryHelper historyHelper = CreateHistoryHelper(this);
return historyHelper.GetHistoricalValue(propertyName, CreatedDate);
}
...
public class HistoryHelper {
public string GetHistoricalValue(string propertyName, DateTime date) {
...
So, when someone wants to fetch historical data for Property1:
string historicalValue = fooInstance.GetHistoricalValue("Property1");
It's obvious that this approach requires a lot of changes in current application.
Is there a way to make Foo class returns historical value when I access Property1 in regular way:
string historicalValue = fooInstance.Property1;
Something like dynamically generating subclass with overriden properties or some other solution?
Is this possible?
INITIAL ANSWER
Something like this:
public class Foo {
public bool HistoricalMode { get; set; }
private string _property1;
public string Property1 {
get {
if (HistoricalMode) {
return GetHistoricalValue("Property1");
} else {
return _property1;
}
set {
if (HistoricalMode){
throw new NotSupportedException("Updates not possible in historical mode.");
} else {
_property1 = value;
}
}
}
public DateTime CreatedDate {
get {
// Similar pattern as above
}
set {
// Similar pattern as above
}
}
public string GetHistoricalValue(string propertyName) {
HistoryHelper historyHelper = CreateHistoryHelper(this);
return historyHelper.GetHistoricalValue(propertyName, CreatedDate);
}
}
Basically the idea is to keep a boolean in your objects which indicates in the object is in 'history mode'. If so, use your helper method. If not, normal properties getters/setters apply.
UPDATE
The solution to this question I think would require a change in your framework (if you have a single framework for all your applications). I would seek the solution in the way you are loading your objects. Hopefully you can detect when an object is required in 'historical mode' and when in 'normale mode'. Where you now 'just read' the object (record) from the database, in historical mode you need to compose the original object (from when the change happened) from your change log functionality. That way, all your current application can (hopefully) stay the way they are. The 'only' change you need to do is at the repository class.
This is all just speculation btw.
Can you easily affect how Foo instances are created? If so, you can for example create derived class HistoricalFoo : Foo, make Property1 virtual and use its getter to change its behaviour. Then use HistoricalFoo whenever you need historical data. It is not a very clean object model, but can get the job done.
public class Foo
{
protected string _property1;
public virtual string Property1
{
get { return _property1; }
set { _property1 = value; }
}
public DateTime CreatedDate { get; set;}
/* ... */
}
public class HistoricalFoo : Foo
{
public override string Property1
{
get
{
return GetHistoricalValue("Property1");
}
}
}
If this is not applicable, it's possible to embed some decision logic into the Property1 getter. In this scenario, you would have to change the internal state of the Foo instance - for example by setting a boolean flag IsInHistoryMode. Changing object states can be very tricky though, expecially in multithreaded environment.
public class Foo
{
public bool IsInHistoryMode { get; set; }
protected string _property1;
public virtual string Property1
{
get
{
if(IsInHistoryMode)
{
return GetHistoricalValue("Property1");
}
return _property1;
}
set
{
_property1 = value;
}
}
public DateTime CreatedDate { get; set;}
/* ... */
}

Differences with BinaryFormatter

I am trying to change the serializer in an existing WCF net.tcp project that uses shared entities on client & server. I am having a hard time figuring out protobuf-net(V2480)
The chart here says I can serialize private members but cannot find documentation to do that, is it possible without attributes? How do I enable graph mode(As Reference) as explained here
Will that solve the issue of protobuf triggering my changed items flag? For example I have a class
public enum FirstEnum
{
First = 0,
Second,
Third
}
public enum AnotherEnum
{
AE1 = 0,
AE2,
AE3
}
[Serializable()]
public class SomeClass
{
public int SomeClassId { get; set; }
public FirstEnum FEnum { get; set; }
public AnotherEnum AEnum { get; set; }
string thing;
public string Thing
{
get{return thing;}
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException("Thing");
thing = value;
}
}
private decimal firstAmount;
public decimal FirstAmount
{
get{return firstAmount;}
set
{
if (value != firstAmount)
{
firstAmount = value;
changedItems.Add("FirstAmount changed");
}
}
}
private decimal secondAmount;
public decimal SecondAmount
{
get { return secondAmount; }
set
{
if (value != secondAmount)
{
secondAmount = value;
changedItems.Add("SecondAmount changed");
}
}
}
public decimal ThirdAmount { get { return SecondAmount - FirstAmount; } }
public DateTime? SomeDate { get; set; }
private List<string> changedItems = new List<string>();
public List<string> ChangedItems
{
get { return changedItems; }
}
public int PrivateSet { get; private set; }
public SomeClass() { }
public SomeClass(decimal first, decimal second)
{
FirstAmount = first;
SecondAmount = second;
}
public void ClearChangedItems()
{
changedItems.Clear();
}
When I deserialize it with (1000 items)
var model = CreateModel();
items = (List<SomeClass>)model.Deserialize(returnStream, null, typeof(List<SomeClass>));
2012-04-06 09:14:28.1222|DEBUG|ProtobufTEsts.Form1|ProtoBuf Number of changed items : 1000
With BinaryForrmatter
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
items = (List<SomeClass>)binaryFormatter.Deserialize(returnStream);
2012-04-06 09:14:28.1662|DEBUG|ProtobufTEsts.Form1|BinaryFormatter Number of changed items : 0
Is there a way to get protobuf to behave like the binaryFormatter but preserve the performance of protobuf?
How to allow for private serialization, this fails
public static TypeModel CreateModel()
{
RuntimeTypeModel model = TypeModel.Create();
///var metaType = RuntimeTypeModel.Default.Add(typeof(SomeClass), false);
model.Add(typeof(SomeClass), false)
.Add(1, "SomeClassId")
.Add(2, "FEnum")
.Add(3, "AEnum")
.Add(4, "Thing")
.Add(5, "FirstAmount")
.Add(6, "SecondAmount")
.Add(7, "SomeDate")
.Add(8, "PrivateSet");
TypeModel compiled = model.Compile();
return compiled;
}
Ah, I understand the issue now; this line is problematic:
TypeModel compiled = model.Compile();
return compiled;
If you use Compile(), it creates a formal assembly (in memory) that has to obey the usual rules of assemblies, and in particular: member accessibility. This means it can't access your private sertter.
Instead, use:
model.CompileInPlace();
return model;
This performs a partial compilation, but continues using DynamicMethod. This cheeky little critter has options to spoof its way past accessibility rules (much like reflection can), so it can continue to use the private setter.
Note that the model is also compiled-in-place (at a more granular level) on as as-needed basis, so this call to CompileInPlace is not strictly necessary, but helps do everything up-front an in advance.
For completeness, there is an additional Compile(string,string) overload that can be used to produce a separate serialization dll on disk, that can be referenced and used without any meta-programming at runtime.
Yes protobuf-net can serialize private fields, and do so without attributes. I'm not at a PC, so this may need tweaking:
var metaType = RuntimeTypeModel.Default.Add(typeof(SomeClass), false);
// for each field in a known order
metaType.Add(fieldName, someUniqueTag);
In attribute-driven usage, there is also ImplicitFields.AllFields which would automatically configure it for the usage you intend, but I haven't yet added an ImplicitFields helper method to MetaType. I will add that to my list!
Note: tag (=field) numbers are important to protobuf and it must be possible to reproduce the same number mappings when you deserialize.
Another option you might want to consider is (de)serialization callbacks, which allow you to know that it is currently serializing/deserializing (via before/after method invokes). This can be another way of disabling side-effects for an interval such as deserialization.

How to create a property for a List<T>

private List<T> newList;
public List<T> NewList
{
get{return newList;}
set{newList = value;}
}
I want to create something like this, but this is won't work. it's just an example to demonstrate my goal as it's pretty common creating proprties for string and int and even T but I've never seen a List property
Is it even possible do such a thing, creating a property for type List ?
EDIT
I have a normal class that has normal properties (string properties, int properties, etc) but I have this property that stores user options, So on the presentation layer I had to convert them into a string so I could be able to store them in the Object. Now is it possible to have a property of type List to store the multivalues in a better and clean way, instead of converting information into one string and then split it and again join it! Thanks Again =D
EDIT2
private List<KeyValuePair<string, string>> _settings;
public List<KeyValuePair<string, string>> MySettings
{
get { return _settings; }
set { _settings = value; }
}
I used the exact code you posted but the property still won't appear in the object's instance, so I tried adding code in the get and set (I wonder why you left them empty or does it means something?) and also added a private variable in the class but still it doesn't appear in the properties of the object's instance!
I hope you could provide the exact code to implement this property and a simple code that assigns or retrieves from/to an instance of this class object
It's the first time to even hear about this KeyValuePair and all the tutorials are pretty simple and not for my case, sorry!
The Last Edit: After a lot of researching and the help of Mark Avenius I found the perfect answer. hope everyone can benefit from this.
NOW! HOW TO CREATE A PROPERTY FOR A LIST :
The Options Class
Public Class Options
{
private string id;
private int option;
public int ID
{
get { return id; }
set { id= value; }
}
public string Option
{
get { return option; }
set { option = value; }
}
}
The Users Class
public class Users
{
private int userId;
private string pass;
private List<Options> userOptions = new List<Options>();
public int ID
{
get { return userId; }
set { user = userId; }
}
public string Pass
{
get { return pass; }
set { pass = value; }
}
public List<Options> OptionsList
{
get { return userOptions; }
set { userOptions = value; }
}
}
The Presentation Layer
Users newUser = new Users ();
Options userOption = new Options ();
userOption.ID = int.Parse(txtBxID.Text);
userOption.Option = txtBxOption.Text;
Item.Options.Add(userOption);
T must be defined within the scope in which you are working. Therefore, what you have posted will work if your class is generic on T:
public class MyClass<T>
{
private List<T> newList;
public List<T> NewList
{
get{return newList;}
set{newList = value;}
}
}
Otherwise, you have to use a defined type.
EDIT: Per #lKashef's request, following is how to have a List property:
private List<int> newList;
public List<int> NewList
{
get{return newList;}
set{newList = value;}
}
This can go within a non-generic class.
Edit 2:
In response to your second question (in your edit), I would not recommend using a list for this type of data handling (if I am understanding you correctly). I would put the user settings in their own class (or struct, if you wish) and have a property of this type on your original class:
public class UserSettings
{
string FirstName { get; set; }
string LastName { get; set; }
// etc.
}
public class MyClass
{
string MyClassProperty1 { get; set; }
// etc.
UserSettings MySettings { get; set; }
}
This way, you have named properties that you can reference instead of an arbitrary index in a list. For example, you can reference MySettings.FirstName as opposed to MySettingsList[0].
Let me know if you have any further questions.
EDIT 3:
For the question in the comments, your property would be like this:
public class MyClass
{
public List<KeyValuePair<string, string>> MySettings { get; set; }
}
EDIT 4: Based on the question's edit 2, following is how I would use this:
public class MyClass
{
// note that this type of property declaration is called an "Automatic Property" and
// it means the same thing as you had written (the private backing variable is used behind the scenes, but you don't see it)
public List<KeyValuePair<string, string> MySettings { get; set; }
}
public class MyConsumingClass
{
public void MyMethod
{
MyClass myClass = new MyClass();
myClass.MySettings = new List<KeyValuePair<string, string>>();
myClass.MySettings.Add(new KeyValuePair<string, string>("SomeKeyValue", "SomeValue"));
// etc.
}
}
You mentioned that "the property still won't appear in the object's instance," and I am not sure what you mean. Does this property not appear in IntelliSense? Are you sure that you have created an instance of MyClass (like myClass.MySettings above), or are you trying to access it like a static property (like MyClass.MySettings)?
Simple and effective alternative:
public class ClassName
{
public List<dynamic> MyProperty { get; set; }
}
or
public class ClassName
{
public List<object> MyProperty { get; set; }
}
For differences see this post: List<Object> vs List<dynamic>
public class MyClass<T>
{
private List<T> list;
public List<T> MyList { get { return list; } set { list = value; } }
}
Then you can do something like
MyClass<int> instance1 = new MyClass<int>();
List<int> integers = instance1.MyList;
MyClass<Person> instance2 = new MyClass<Person>();
IEnumerable<Person> persons = instance2.MyList;
You could do this but the T generic parameter needs to be declared at the containing class:
public class Foo<T>
{
public List<T> NewList { get; set; }
}
It's possible to have a property of type List<T> but your class needs to be passed the T too.
public class ClassName<T>
{
public List<T> MyProperty { get; set; }
}
Either specify the type of T, or if you want to make it generic, you'll need to make the parent class generic.
public class MyClass<T>
{
etc

C# Setting Properties using Index

I have a business class that contains many properties for various stock-exchange price types. This is a sample of the class:
public class Prices
{
public decimal Today {get; set;}
public decimal OneDay {get; set;}
public decimal SixDay {get; set;}
public decimal TenDay {get; set;}
public decimal TwelveDay {get; set;}
public decimal OneDayAdjusted {get; set;}
public decimal SixDayAdjusted {get; set;}
public decimal TenDayAdjusted {get; set;}
public decimal OneHundredDayAdjusted {get; set;}
}
I have a legacy system that supplies the prices using string ids to identify the price type.
E.g.
Today = "0D"
OneDay = "1D"
SixDay = "6D"
//..., etc.
Firstly, I load all the values to an IDictionary() collection so we have:
[KEY] VALUE
[0D] => 1.23456
[1D] => 1.23456
[6D] => 1.23456
...., etc.
Secondly, I set the properties of the Prices class using a method that takes the above collection as a parameter like so:
SetPricesValues(IDictionary<string, decimal> pricesDictionary)
{
// TODAY'S PRICE
string TODAY = "D0";
if (true == pricesDictionary.ContainsKey(TODAY))
{
this.Today = pricesDictionary[TODAY];
}
// OneDay PRICE
string ONE_DAY = "D1";
if (true == pricesDictionary.ContainsKey(ONE_DAY))
{
this.OneDay = pricesDictionary[ONE_DAY];
}
//..., ..., etc., for each other property
}
Is there a more elegant technique to set a large amount of properties?
Thanks,
j
Instead of using a string-to-decimal mapping and checking the dictionary repeatedly, use a delegate mapping/extension method:
public static class PriceConverter
{
private static readonly Dictionary<string, Action<Prices, decimal>> setters =
CreateSetterDictionary();
public static void SetPrice(this Prices p, string id, decimal newPrice)
{
Action<Prices, decimal> setter;
if (setters.TryGetValue(id, out setter))
setter(p, newPrice);
}
private static Dictionary<string, Action<Prices, decimal>>
CreateSetterDictionary()
{
var dic = new Dictionary<string, Action<Prices, decimal>>();
dic.Add("0D", (p, d) => p.Today = d);
dic.Add("1D", (p, d) => p.OneDay = d);
// etc.
return dic;
}
}
Then you can write prices.SetPrice("0D", 1.23456).
If you like, add a throw statement at the end of the SetPrice method to handle cases where the id doesn't match anything.
I would put the string variables into constants, rather than declare them every time you run the method:
private const string ONE_DAY = "D1";
If you expect the collection parameter to contain all or most of the possible values, then your code is probably cool. If you expect that the dictionary will have a small subset of the possible values, it might be more efficient to use a foreach loop and a switch statement to set values, rather then do a lookup for every possible value every time. It just depends on how many values you need to deal with and how many you get in each method call.
Define a dictionary of properties in the constructor e.g.
private Dictionary<int, PropertyInfo> propertyDictionary = new ...
MyClass()
{
this.propertyDictionary.Add(0, this.GetType().GetProperty("FirstProperty");
...
}
then access using an indexed property
decimal this[int index]
{
get
{
PropertyInfo property;
if (this.propertyDictionary.TryGetValue(index, out property))
{
// Not sure I remember the arguments right here:
property.SetValue(this, new object[] { value });
}
set
{
// Similar code
}
}
You could later on improve this code by automatically parsing the properties in the constructor using reflection,
adding all properties with an attribute that tells you what the id is.
(Instead of adding them manually in the constructor).
Just an idea:
interface IPrices_As_String{
string OD { get; set; }
// other properties here...
}
interface IPrices{
decimal Today{get; set;}
}
class Prices : IPrices, IPrices_As_String{
public decimal Today { get; set; }
public string IPrices_As_String.OD {
get { return this.Today.ToString(); }
set {
if(!String.IsNullOrEmpty(value)){
this.Today = decimal.Parse(value);
}
}
}
}
Then when I am setting the values from the legacy system, I will use the Prices class on the interface as IPrices_As_String like:
IPrices_As_String obj = new Prices();
// set values from the legacy system
IPrices obj2 = obj as IPrices; // will give me the correct object..
.
HTH.
The way I see it, you have a few options, depending on your skills, the way you are allowed to change the current POCO's or other classes:
If you must use a dictionary, create a similar dictionary which maps the "0D" etc to the OneDay names. Loop through the dictionary and assign using simple reflection.
If you can change the way the data is read, have the dictionary read with OneDay etc, instead of the "0D", which is only applicable to the external application.
Create an attribute, LegacyKeyAttribute, augment your POCO gettors/settors with this attribute. Now it becomes trivial: loop through the properties of the POCO to find the correct property for your current legacy key.
The last option requires a bit more understanding of C# than many average programmers know: writing and using attributes and reflection. However, in the end it's the cleanest and easiest solution (I'll try to come up with an example).
UPDATE: here's a little example. Meanwhile, many improvement suggestions have been posted, but none still uses attributes, while your case seems ideal. Why? It poses the least burden on existing code, I believe, and it makes reading and understanding your code even easier.
Usage:
// any price:
Prices prices = new Prices();
prices.SetPriceByLegacyName("0D", 1.2345M);
// or, your loop becomes a bit easier:
SetPricesValues(IDictionary<string, decimal> pricesDictionary)
{
foreach(string key in pricesDictionary.Keys)
{
// assuming "this" is of type Prices (you didn't specify)
this.SetPriceByLegacyName(key, pricesDictionary[key]);
}
}
The implementation:
// the simplest attribute class is enough for you:
[AttributeUsage(AttributeTargets.Property)]
public class LegacyNameAttribute : Attribute
{
public string Name { get; set; }
public LegacyNameAttribute(string name)
{
this.Name = name;
}
}
// your Prices POCO class becomes easier to read
public class Prices
{
[LegacyName("0D")] public decimal Today { get; set; }
[LegacyName("1D")] public decimal OneDay { get; set; }
[LegacyName("6D")] public decimal SixDay { get; set; }
[LegacyName("10D")] public decimal TenDay { get; set; }
[LegacyName("12D")] public decimal TwelveDay { get; set; }
[LegacyName("1DA")] public decimal OneDayAdjusted { get; set; }
[LegacyName("6DA")] public decimal SixDayAdjusted { get; set; }
[LegacyName("10DA")] public decimal TenDayAdjusted { get; set; }
[LegacyName("100DA")] public decimal OneHundredDayAdjusted { get; set; }
}
// an extension method to ease the implementation:
public static class PricesExtensions
{
public static void SetPriceByLegacyName(this Prices price, string name, decimal value)
{
if (price == null)
throw new ArgumentException("Price cannot be null");
foreach (PropertyInfo prop in price.GetType().GetProperties())
{
LegacyNameAttribute legNameAttribute = (LegacyNameAttribute)
Attribute.GetCustomAttribute(prop, typeof(LegacyNameAttribute));
// set the property if the attribute matches
if (legNameAttribute != null && legNameAttribute.Name == name)
{
prop.SetValue(price, value, null);
break; // nothing more to do
}
}
}
}
That's all there is to it. Even with all the added lines, it may well be that your total line count becomes less. But more importantly, it becomes easier to maintain and use.

Categories