not sure whether the subject is the best description for this problem but I am getting an unusual problem where I have a single Web API operation and a single field on a request and for some odd reason the value gets manipulated. Depending on the input this gets converted / translated by Web API or even by something else such as JSON.NET?
Should mention that this a brand new project with no additional references apart from what gets added by default when creating a new Web API project in Visual Studio.
public class TestController : ApiController
{
public void Post(Foo request)
{
}
}
public class Foo
{
public string Blah { get; set; }
}
Using a rest client I hit the operation using the following request:
{
"Blah": 43443333222211111117
}
When debugging the value of Blah gets converted to "6549845074792007885". I don't understand how and why its doing this? Any other value it respects. For example:
{
"Blah": 53443333222211111117
}
This is absolutely fine but is a bigger number.
Thanks, DS.
Update
This bug has been fixed and is scheduled to be included in the next release.
Original Answer
This is a bug in JSON.NET as hinted at, but it's not as simple as it first seems.
Versions prior to 5.0.4 work for both of these test cases. Anything after seems to fail but only for the first test case which is odd. I've gone through some of the JSON.NET code to try and see where this confusion occurs but at present cannot work out the why this is the case, I need to do more digging.
2147483647 Int Max
4444333322221111 Valid Credit Card Number Format
9223372036854775807 Int 64 Max
43443333222211111117 Dodgy Number greater than Int 64 hence overflow
53443333222211111117 Larger than above and Int 64, but works oddly.
1.7976931348623157E+308. Decimal max
Why 53443333222211111117 works is very odd. JSON.NET seems to have a 1025 character buffer set aside that contains a load of jibberish for my test cases, eventually the number is read incorrectly. I'll check this out further and raise an issue with JSON.NET.
If you use a decimal for the property this will work in all cases where the leading number is not zero, but this isn't a solution. For the short term, use version 5.0.3.
Take this example program to demonstrate the problem.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Sending in: \n43443333222211111117");
var largeBrokenNumber = JsonConvert.DeserializeObject<Foo>("{\"Blah\": 43443333222211111117 }");
Console.WriteLine(largeBrokenNumber.Blah);
Console.WriteLine();
Console.WriteLine("Sending in: \n53443333222211111117");
var largeOddWorkingNumber = JsonConvert.DeserializeObject<Foo>("{\"Blah\": 53443333222211111117 }");
Console.WriteLine(largeOddWorkingNumber.Blah);
}
}
public class Foo
{
public string Blah { get; set; }
}
Related
Summary
Need to be able to tell if a work request has one or more statuses currently applied to it, and be able to remove statuses without affecting other statuses applied. Currently, the work request can only have one status at a time, and the code for determining what the 'most important' status is keeps growing.
SQL server back end, C# with EF (mostly) for data access
Background
I'm working on an application where we have a work request where the status changes as people do specific activities until the request is finished. There are close to 30 statuses that the request can have, and there are many instances where we need to know if one or more statuses have been applied to the work request (to determine what happens next).
Currently the request has a single status that reflects the most current status, and when we change the status it has to go through code that looks at other associated data to determine what the 'most important' status is and change the request to that one.
This business problem seems to be perfect for using bitwise calculations, but I don't want to resort to an obsolete practice. The other possibility is to just have a collection of statuses and add/remove from the list.
Thanks
X DO NOT use an enum for open sets (such as the operating system
version, names of your friends, etc.).
[Microsoft Framework Design Guidelines].
Your use case sounds like an open set that will be added to over time. So based on that alone I'd say enum's are not right for this use case.
X AVOID creating flag enums where certain combinations of values are invalid.
Additionally it doesn't sound like all the values from your enum can be combined and still be valid.
Lastly here's a comment from Steven Clarke from the published copy of the Microsoft Framework Design Guidelines about the complexity in your proposed use of enums:
I'm sure that less experienced developers will be able to understand
bitwise operation on flags. The real question, though, is whether they
would expect to have to do this. Most of the APIs that I have run
through the labs don't require them to perform such operations so I
have a feeling that they would have the same experience that we
observed during a recent study - it's just not something that they are
used to doing so they might not even think about it. Where it could get
worse, I think, is that if less advanced developers don't realize they
are working with a set of flags that can be combined with one another,
they might just look at the list available and think that is all the
functionality they can access. As we've seen in other studies, if an
API makes it look to them as though a specific scenario or requirement
isn't immediately possible, it's likely that they will change the
requirement and do what does appear to be possible, rather than being
motivated to spend time investigating what they need to do to achieve
the original goal.
What follows are just some thoughts about enums should you go this route:
DO name flag enums with plural nouns or noun phrases and simple enums with singular nouns or noun phrases.
DO use powers of two for the flag enum values so they can be freely combined using the bitwise OR operation.
I don't think there is anything necessarily wrong with using a flagged enum for your status. To clarify, I think there are two things you are talking about. The set of actions that have been done for a request, and then some sort of derived value that you want to communicate to the user as being the most important value. Think this could be handled by doing a flagged enum, and then a property that is derived from your status enum (you might already be doing this). I would also recommend keeping a log of when each status was applied to a request in a separate entity.
As far as enforcing your statuses goes, one thing you could try is to represent your process as a directed graph of each of the steps. Then that data structure can be used to determine if all the conditions are met to move to the next step in your process.
[Flags]
public enum Status
{
Unknown = 0,
Completed = 1,
Blocked = 2,
Phase1 = 4,
Phase2 = 8,
Phase3 = 16,
Closed = 32
}
public class Request
{
public string Name { get; set; }
public string StatusText { get { return GetStatusText(); } }
public Status Status { get; set; }
public Request()
{
this.Status = Status.Unknown;
}
private string GetStatusText()
{
string statusText = "Created";
if (AnyStatus(Status.Closed | Status.Completed))
{
statusText = IsStatus(Status.Closed) ? "Closed" : "Completed";
}
else
{
if (IsStatus(Status.Blocked))
{
statusText = "Blocked";
}
else
{
if(IsStatus(Status.Phase3)) {
statusText = "Phase 3";
}
else if(IsStatus(Status.Phase2)) {
statusText = "Phase 2";
}
else if (IsStatus(Status.Phase1))
{
statusText = "Phase 1";
}
}
}
return statusText;
}
private bool IsStatus(Status checkStatus)
{
return ((this.Status & checkStatus) == checkStatus);
}
private bool AnyStatus(Status checkStatus)
{
return ((this.Status & checkStatus) > 0);
}
}
Possible class for logging status changes
public class StatusLog
{
public int RequestId { get; set; }
public int UserId { get; set; }
public DateTime Date { get; set; }
public Status Status { get; set; }
}
Greeting fellow programmers!
I am currently studying software development (I started not a month ago) and I have a problem that needs a solution. Underneath you can find the code and as you can see, the method WriteNumber needs help. I need to write the code in a way that when I run the program, on the console screen the following two lines will be shown:
Hello World!
81
The Main method code cannot be changed and also I cannot add more methods to the class Calculator so the code needs to be done only within the WriteNumbers method. I have tried a lot of things but I am still grasping how everything works so any help is welcome! Thank you in advance for your time.
Namespace CalculatorTest
{
class Calculator
{
public static string WriteText (string input)
{
return "" + input;
}
public static string WriteNumber()
{
}
}
class Program
{
static void Main(string[] args)
{
string s = Calculator.WriteText("Hello World!");
Console.WriteLine(s);
string n = Calculator.WriteNumber(53 + 28);
Console.WriteLine(n);
Console.Read();
}
}
Not to do your homework for you to just be copied/pasted, hopefully I can give you some hints...
Notice how the method is being invoked:
Calculator.WriteNumber(53 + 28)
The 53 + 28 part happens first, then the result of that operation is passed to the method. That result, naturally, is 81. What's important about that is its type, which is an integer.
So, reasonably, the method signature needs to accept an int as a parameter. This would be done very similarly to how the other method accepts a string as a parameter:
public static string WriteText(string input)
What, then, does that method need to do with that input? Well, it's only a single value, so there aren't any calculations to be performed on it. It would appear that the method simply needs to return the value as a string. (It's your homework so you tell me, is that correct?)
This can be done with exactly two things:
Calling .ToString() on the value
Using the return keyword to return the result of that operation
(Note: The .ToString() operation does something very intuitive on value types, such as int or double or bool. As you progress into using reference types, you're going to find that it does something very different. Any time you have a custom class on which you want to call .ToString(), you'll need to override the .ToString() method on that class first.)
Please read David's answer, it's important that you make the effort to understand why this works the way it does. That being said:
public static string WriteNumber(int number)
{
return number.ToString();
}
Thank you all for your valuable input but special thanks to David because he showed where I made my error. I forgot that the two numbers in the main function will be summed up FIRST and THEN forwarded to the method in the class Calculator. After that got cleared up, it was easy to understand what to do (basically adjust the type of the input parameter to int).
namespace CalculatorTest
{
class Calculator
{
public static string WriteText (string input)
{
return "" + input;
}
public static string WriteNumber(int sumOfNumbers)
{
return "" + sumOfNumbers;
}
}
class Program
{
static void Main(string[] args)
{
string s = Calculator.WriteText("Hello World!");
Console.WriteLine(s);
string n = Calculator.WriteNumber(53 + 28);
Console.WriteLine(n);
Console.Read();
}
}
}
Put simply, I'm having trouble writing a binary file, then reading back that same file. This is a settings file, which contains a few strings and an int. I have no problem with writing the strings, but when I get to the int I just can't get a value back when the settings are read.
A little back story: I'm more of a c/c++ programmer, c# isn't totally foreign, but it's not my forte. For instance, I had no idea if I wrote a string, it takes care of the length and reads for you.. just. x.ReadString(). Neat.
Here's some rough code to give you an idea of what I'm doing. Note this is stripped of error checking, and most of the superfluous reads/writes. Just kept it to bare minimal:
public static int LDAPport;
public static string Username;
public static char Ver;
public static int LoadSettings()
{
using (BinaryReader r = new BinaryReader(File.Open("data\\Settings.cfg", FileMode.Open)))
{
char cin = r.ReadChar();
if (cin != Ver)
{
// Corrupted or older style settings
return 1;
}
Username = r.ReadString();
LDAPport = r.ReadInt32();
r.Close();
}
return 0;
}
public static bool SaveSettings()
using (BinaryWriter w = new BinaryWriter(File.Open("data\\Settings.cfg", FileMode.Create)))
{
w.Write(Ver);
w.Write(Username);
w.Write(LDAPport);
w.Close();
}
}
return true;
}
So when it writes 389 (I've verified it is getting the proper value when it goes to write) When read back, LDAPport gets -65145. Which tells me it's either not reading all 4 bytes for an int (it's 4 isn't it?), or it's reading a number that's unsigned (since I'm expecting signed). Casting seemed to do nothing for me.
I've also tried other read methods. .Read() does the same thing, I've tried changing the data type for the number, including UInt32 to no avail. Everything I've read just says simply .Write(389) then .Read()! that simple!.. well no. There doesn't seem to be a method for just int.. I assume it's got those smarts in .Read() yes?
Can someone with a c# brain greater than mine shed some light as to what's going on here? Or has my brain officially turned to jelly at this point? :)
This question is related to another question with which I have been struggling:
How to access CORBA interface without IDL or late-bound invoke remoting methods
I'm really stumped on how to get past this error about the CodeSet not being specified. I have been tracing into the IIOP code trying to figure out how the CodeSet can be specified, and it looks like it could be specified with a tagged component associated with the profile. Being unfamiliar with CORBA, I don't know what a tagged component is or what a profile is or how to control them, but I suspect that it may be influenced by creating a portable object interceptor, at which point I could add a tagged CodeSet component to the profile, if that means anything. I'm just going by what I can learn from the IIOP.NET code and Google.
Could someone please help me understand and hopefully control this? If the server is a black box and I need to write a client to call a method that outputs a string, how do I tell IIOP.NET what WChar CodeSet to use so it doesn't give me an error about it being unspecified. I tried OverrideDefaultCharSets from the client, but that didn't seem to have any effect. The IIOP sample code for that function shows it being used on the server side.
This was a real pain to work out, but I got it:
class MyOrbInitializer : omg.org.PortableInterceptor.ORBInitializer
{
public void post_init(omg.org.PortableInterceptor.ORBInitInfo info)
{
// Nothing to do
}
public void pre_init(omg.org.PortableInterceptor.ORBInitInfo info)
{
omg.org.IOP.Codec codec = info.codec_factory.create_codec(
new omg.org.IOP.Encoding(omg.org.IOP.ENCODING_CDR_ENCAPS.ConstVal, 1, 2));
Program.m_codec = codec;
}
}
class Program
{
public static omg.org.IOP.Codec m_codec;
static void Main(string[] args)
{
IOrbServices orb = OrbServices.GetSingleton();
orb.OverrideDefaultCharSets(CharSet.UTF8, WCharSet.UTF16);
orb.RegisterPortableInterceptorInitalizer(new MyOrbInitializer());
orb.CompleteInterceptorRegistration();
...
MarshalByRefObject objRef = context.resolve(names);
string origObjData = orb.object_to_string(objRef);
Ch.Elca.Iiop.CorbaObjRef.Ior iorObj = new Ch.Elca.Iiop.CorbaObjRef.Ior(origObjData);
CodeSetComponentData cscd = new CodeSetComponentData(
(int)Ch.Elca.Iiop.Services.CharSet.UTF8,
new int[] { (int)Ch.Elca.Iiop.Services.CharSet.UTF8 },
(int)Ch.Elca.Iiop.Services.WCharSet.UTF16,
new int[] { (int)Ch.Elca.Iiop.Services.WCharSet.UTF16 });
omg.org.IOP.TaggedComponent codesetcomp = new omg.org.IOP.TaggedComponent(
omg.org.IOP.TAG_CODE_SETS.ConstVal, m_codec.encode_value(cscd));
iorObj.Profiles[0].TaggedComponents.AddComponent(codesetcomp);
string newObjData = iorObj.ToString();
MarshalByRefObject newObj = (MarshalByRefObject)orb.string_to_object(newObjData);
ILicenseInfo li = (ILicenseInfo)newObj;
...
}
Unfortunately in my case the problem remained that the byte ordering was backwards too, so I had to go with an entirely different solution based on just getting bytes back and manually converting them to a string instead of getting string directly.
Maybe this is dreaming, but is it possible to create an attribute that caches the output of a function (say, in HttpRuntime.Cache) and returns the value from the cache instead of actually executing the function when the parameters to the function are the same?
When I say function, I'm talking about any function, whether it fetches data from a DB, whether it adds two integers, or whether it spits out the content of a file. Any function.
Your best bet is Postsharp. I have no idea if they have what you need, but that's certainly worth checking. By the way, make sure to publish the answer here if you find one.
EDIT: also, googling "postsharp caching" gives some links, like this one: Caching with C#, AOP and PostSharp
UPDATE: I recently stumbled upon this article: Introducing Attribute Based Caching. It describes a postsharp-based library on http://cache.codeplex.com/ if you are still looking for a solution.
I have just the same problem - I have multiply expensive methods in my app and it is necessary for me to cache those results. Some time ago I just copy-pasted similar code but then I decided to factor this logic out of my domain.
This is how I did it before:
static List<News> _topNews = null;
static DateTime _topNewsLastUpdateTime = DateTime.MinValue;
const int CacheTime = 5; // In minutes
public IList<News> GetTopNews()
{
if (_topNewsLastUpdateTime.AddMinutes(CacheTime) < DateTime.Now)
{
_topNews = GetList(TopNewsCount);
}
return _topNews;
}
And that is how I can write it now:
public IList<News> GetTopNews()
{
return Cacher.GetFromCache(() => GetList(TopNewsCount));
}
Cacher - is a simple helper class, here it is:
public static class Cacher
{
const int CacheTime = 5; // In minutes
static Dictionary<long, CacheItem> _cachedResults = new Dictionary<long, CacheItem>();
public static T GetFromCache<T>(Func<T> action)
{
long code = action.GetHashCode();
if (!_cachedResults.ContainsKey(code))
{
lock (_cachedResults)
{
if (!_cachedResults.ContainsKey(code))
{
_cachedResults.Add(code, new CacheItem { LastUpdateTime = DateTime.MinValue });
}
}
}
CacheItem item = _cachedResults[code];
if (item.LastUpdateTime.AddMinutes(CacheTime) >= DateTime.Now)
{
return (T)item.Result;
}
T result = action();
_cachedResults[code] = new CacheItem
{
LastUpdateTime = DateTime.Now,
Result = result
};
return result;
}
}
class CacheItem
{
public DateTime LastUpdateTime { get; set; }
public object Result { get; set; }
}
A few words about Cacher. You might notice that I don't use Monitor.Enter() ( lock(...) ) while computing results. It's because copying CacheItem pointer ( return (T)_cachedResults[code].Result; line) is thread safe operation - it is performed by only one stroke. Also it is ok if more than one thread will change this pointer at the same time - they all will be valid.
You could add a dictionary to your class using a comma separated string including the function name as the key, and the result as the value. Then when your functions can check the dictionary for the existence of that value. Save the dictionary in the cache so that it exists for all users.
PostSharp is your one stop shop for this if you want to create a [Cache] attribute (or similar) that you can stick on any method anywhere. Previously when I used PostSharp I could never get past how slow it made my builds (this was back in 2007ish, so this might not be relevant anymore).
An alternate solution is to look into using Render.Partial with ASP.NET MVC in combination with OutputCaching. This is a great solution for serving html for widgets / page regions.
Another solution that would be with MVC would be to implement your [Cache] attribute as an ActionFilterAttribute. This would allow you to take a controller method and tag it to be cached. It would only work for controller methods since the AOP magic only can occur with the ActionFilterAttributes during the MVC pipeline.
Implementing AOP through ActionFilterAttribute has evolved to be the goto solution for my shop.
AFAIK, frankly, no.
But this would be quite an undertaking to implement within the framework in order for it to work generically for everybody in all circumstances, anyway - you could, however, tailor something quite sufficient to needs by simply (where simplicity is relative to needs, obviously) using abstraction, inheritance and the existing ASP.NET Cache.
If you don't need attribute configuration but accept code configuration, maybe MbCache is what you're looking for?