I am stuck with the following problem: I am communicating with another application using TcpClients/Streams.
This application needs input parameters passed to it, encoded in a special way (something along first byte: parameter type identifier, next 4 bytes: content length; next length bytes: content).
The application processes the input and gives me the output back in the same format. My problem is that I usually don't know the exact order of different return values. The application could return nothing, one int, 5 ints, 2ints and an IntArray...
EDIT: To clarify this, I can not change the underlying protocol or the source code of the application I am communicating with!
The problem is that I want to be able to use the params as if they were "native" C# objects.
What I tried achieving is the following approach:
https://dotnetfiddle.net/ZjbUix
I am not really sure whether this is a good idea. Maybe it would be a better alternative to have a EncodingStream(NetworkStream) with Write() methods for all possible parameter types, and a DecodingStream(NetworkStream) with GetInt(), GetIntArray() etc. methods. This would, however, more or less disregard the type identifier and could only be prevented with throwing an Exception along "Attempted to read an Int value but found Int Array parameter type".
EDIT: I implemented this version here: https://dotnetfiddle.net/8WVXPz
Another requirement is that it should be possible to easily add new parameter types while at best detecting errors at compile-time. Additionally, I'd prefer a non-reflection solution.
Maybe someone can make up an even better architecture to support this?
Related
I'm struggling to understand something in order to use a specific method in a library that was sent to me in order to control a device on Modbus RTU.
My question has nothing to do with the actual Modbus though. I'm pretty sure I'm just missing some basic info on C#.NET as I don't have too much experience. I don't really know what to look for either.
The library is from Orientalmotor and called omrlib. It includes some specific functions for their motors. Some of them I can use without any issue, for example I can get the speed of a stepper motor like this:
modbus.ReadParameter(1, 0x480, out operatingSpeed);
In this particular example I'm reading from driverID 1 and the speed happens to be located in register 0x480.
The problem I'm having arrises when I'm expecting some (custom) data to return, for example using the method SendDiagnosis would return 2 bytes that I need to read. The syntax for this is
modbus.SendDiagnosis(response, slvadd, data)
slvadd is a byte that corresponds with the ID of the driver. data is a ushort where I would have to send 0x1234, but I can't figure out what to use for response. Intellisense lists the type as ref Omrlib.Communication.ModbusInfo.SendReceiveData
I suppose I have to declare a variable with this type but I can't for the life of me figure out how I have to do that, and how I can read the reply that will be stored in this response (the driver should reply with the same message 0x1234).
Could anyone offer some insight please?
Thanks!
Jens
I am trying to use request elements from an ASP application in a .NET class library that is used in the application. I came across a head scratcher that I can't wrap my head around:
//Context is an ASPTypeLibrary.ScriptingContext
dynamic req = System.EnterpriseServices.ContextUtil.GetNamedProperty("Request");
Context.Response.Write(req.Form("mykey")); //this writes the value I expected
Context.Response.Write(String.Format("{0}", req.Form("mykey"))); //this writes 'System.__ComObject'
Am I going about this all wrong? I was using info I gleaned from this question.
You should note that Request.Form("someKey") is not a string. The source of your confusion, however, originates not in Request.Form("someKey") but on the other side, in Response.Write(...).
There are some automatic conversion shenanigans going on.
Request.Write(...) doesn't take a string. It takes a Variant. The method will do its darnest to output whatever you pass to it.
If the Variant holds a BSTR (a COM string), it will output that unchanged. It will also try calling VarChangeTypeEx(...) (kind-of; see note below) to try to see if it can get COM to convert it to a BSTR (that's what happens when you pass it a number). If the Variant contains an object with a default method on it ([propvalue]), and it has no better way to output it, it will call the default method and start over with the result of that. I think it has a few other tricks up its sleeve, which are not entirely clearly documented.
At a high level, it should now be clear what's happening. On the first line, req.Form("myKey") returns a COM object, which then gets passed down to Response.Write(...), which then converts that object to a BSTR string and outputs it. On the other hand, when you try to pass req.Form("myKey") to a C# method, the conversion doesn't occur and you get a generic COM object instead, with predictable consequences.
So what is the return value of Request.Form("someKey") then? It's an IRequestDictionary object. And why a dictionary? Because you can submit an http request that has multiple form elements with the same name. This can be the case, for example, when the input elements are checkboxes intended to be overlapping options.
What happens when the form has multiple entries? The conversion process returns a joined string analog to String.Join(", ", someArray) in C#.
It's not clear to me whether Response.Write has intimate knowledge of IRequestDictionary (unlikely), or whether it knows about COM Enumerator pattern (more likely) and it enumerates them to compose the string.
More interesting to me is who is responsible for the conversion process, because VBScript's CStr() will do the same conversion. I had always assumed that CStr() was a thin wrapper around VarChangeTypeEx(...), but I'm pretty sure that VarChangeTypeEx(...) does not concatenate enumerators like that. Obviously CStr() is a lot fancier than I had assumed. I believe that Response.Write simply calls internally whatever API fully implements CStr() and relies on that for the conversion.
For further exploration of the Classic ASP objects and interface, try http://msdn.microsoft.com/en-us/library/ms524856(v=vs.90).aspx instead of the usual VBScript-based descriptions.
I've got some really large memory dumps of a managed process that I'm trying to get a lot of statistics from--as well as be able to present an interactive view of--fairly deep object graphs on the heap. Think something comparable to !do <address> with prefer_dml 1 set in WinDbg with SOS, where you can continually click on the properties and see their values, only in a much friendlier UI for comparing many objects.
I've found Microsoft.Diagnostics.Runtime (ClrMD) to be particularly well suited for this task, but I'm having a hard time working with array fields and I'm a little confused about object fields, which I have working a little better.
Array:
If I target an array with an address directly off the heap and use ClrType.GetArrayLength and ClrType.GetArrayElementValue things work fine, but once I'm digging through the fields on another object, I'm not sure what value I'm getting from ClrInstanceField.GetValue when the ClrInstanceField.ElementType is ClrElementType.SZArray (I haven't encountered Array digging around in my object graph yet, but I should like to handle it as well).
Edit: I just decided to use the ClrType for System.UInt64 to dereference the array field (using parent address + offset of the array field to calculate the address where the array pointer is stored), then I can work with it the same as if I got it from EnumerateObjects. I am now having some difficulty with some arrays not supporting the ArrayComponentType property. I have yet to test with arrays of Structs so I am also wondering if that will be a C-style allocation of inline structs, as it is with int[] or if it will be an array of pointers to structs on the heap. Guid[] is one of the types I'm having an issue getting the ArrayComponentType from.
Object: Fixed (logic error)
With a ClrInstanceField that has a Type of ClrElementType.Object I get much better results, but still need a little more. Firstly, after calling GetFieldValue I get back a ulong address(?) which I can use ClrInstanceField.Type.Fields against just fine, so I can see the field names and values of the nested object. That said, I have to account for polymorphism, so I tried using ClrHeap.GetObjectType on the same address and it either returns NULL or something completely incorrect. It seems odd that the address would work in my first use case, but not the second.
String: Fixed (found workaround)
Because my real project already uses DbgEng w/ SOS, I have a different way to easily get the value of strings by address, but it seemed very odd that trying to use ClrInstanceField.GetFieldValue succeeded in returning a string, but with completely inaccurate results (a bunch of strange characters). Maybe I'm doing this wrong?
Edit: I have extracted an abstraction that now runs in LINQPad from my original code. It's a bit long to post here, but it's all here in a gist. It's still a little messy from all the copy/paste/refactor and I'll be cleaning it up further an likely posting the final source on either CodePlex or GitHub after I've got these issues fixed.
The code base is fairly large and specific to a project, but if it's absolutely necessary I may be able to extract out a sample set. That said, all access to the ClrMD objects is fairly simple. I get the initial addresses from SOS commands like !dumpheap -stat (which works fine for the root objects) and then I use ClrHeap.GetTypeByName or ClrHeap.GetObjectType. After that it relies exclusively on ClrType.Fields and ClrInstanceField members Type, ElementType, and GetFieldValue
As an added bonus, I did find a browser friendly version of the XML Docs provided with the NuGet package, though it's the same documentation IntelliSense provides.
It's going to be hard to answer very precisely without seeing what your code looks like, but basically, it goes like this:
The first thing you need to know in order to be able to call GetFieldAddress/GetFieldValue is if the object address you have is a regular pointer or an interior pointer. That is, if it directly points to an object on the heap, or to an interior structure within an actual object (think String vs. Struct field within an actual object).
If you're getting the wrong values out of GetFieldAddress/GetFieldValue, it usually means you're not specifying that you have an interior pointer (or you thought you had one when you didn't).
The second part is understanding what the values mean.
If field.IsPrimitive() is true: GetFieldValue() will get you the actual primitive value (i.e. an Int32, Byte, or whatever)
If field.IsValueClass() is true, then GetFieldAddress() will get you an interior pointer to the structure. Thus, any calls on GetFieldAddress/Value() that you use on that address you need to tell it that it is an interior pointer!
If field.ElementType is a ClrElementType.String, then I seem to remember you need to call GetFieldValue will get you the actual string contents (need to check, but this should be it).
Otherwise, you have an object reference, in which case GetFieldValue() will get you a regular pointer to the new reference object.
Does this make sense?
My question is about naming, design, and implementation choices. I can see myself going in two different directions with how to solve an issue and I'm interested to see where others who may have come across similar concerns would handle the issue. It's part aesthetics, part function.
A little background on the code... I created a type called ISlice<T> that provides a reference into a section of a source of items which can be a collection (e.g. array, list) or a string. The core support comes from a few implementation classes that support fast indexing using the Begin and End markers for the slice to get the item from the original source. The purpose is to provide slicing capabilities similar to what the Go language provides while using Python style indexing (i.e. both positive and negative indexes are supported).
To make creating slices (instances of ISlice<T>) easier and more "fluent", I created a set of extension methods. For example:
static public ISlice<T> Slice<T>(this IList<T> source, int begin, int end)
{
return new ListSlice<T>(source, begin, end);
}
static public ISlice<char> Slice(this string source, int begin, int end)
{
return new StringSlice(source, begin, end);
}
There are others, such as providing optional begin/end parameters, but the above will suffice for where I'm going with this.
These routines work well and make it easy to slice up a collection or a string. What I also need is way to take a slice and create a copy of it as an array, a list, or a string. That's where things get "interesting". Originally, I thought I'd need to create ToArray, ToList extension methods, but then remembered that the LINQ variants perform optimizations if your collection implements ICollection<T>. In my case, ISlice<T>, does inherits from it, though much to my chagrin as I dislike throwing NotSupportedExceptions from methods like Add. Regardless, I get those for free. Great.
What about converting back into a string as there's no built-in support for converting an IEnumerable<char> easily back into a string? Closest thing I found is one of the string.Concat overloads, but it would not handle chars as efficiently as it could. Just as important from a design stand point is that it doesn't jump out as a "conversion" routine.
The first thought was to create a ToString extension method, but that doesn't work as ToString is an instance method which means it trumps extension methods and would never be called. I could override ToString, but the behavior would be inconsistent as ListSlice<T> would need to special case its ToString for times where T is a char. I don't like that as the ToString will give something useful when the type parameter is a char, but the class name in other cases. Also, if there are other slice types created in the future I'd have to create a common base class to ensure the same behavior or each class would have to implement this same check. An extension method on the interface would handle that much more elegantly.
The extension method leads me to a naming convention issue. The obvious is to use ToString, but as stated earlier it's not allowed. I could name it something different, but what? ToNewString? NewString? CreateString? Something in the To-family of methods would let it fall in with the ToArray/ToList routines, but ToNewString sticks out as being 'odd' when seen in the intellisense and code editor. NewString/CreateString are not as discoverable as you'd have to know to look for them. It doesn't fit the "conversion method" pattern that the To-family methods provide.
Go with overriding ToString and accept the inconsistent behavior hardcoded into the ListSlice<T> implementation and other implementations? Go with the more flexible, but potentially more poorly named extension method route? Is there a third option I haven't considered?
My gut tells me to go with the ToString despite my reservations, though, it also occurred to me... Would you even consider ToString giving you a useful output on a collection/enumerable type? Would that violate the principle of least surprise?
Update
Most implementations of slicing operations provide a copy, albeit a subset, of the data from whatever source was used for the slice. This is perfectly acceptable in most use cases and leaves for a clean API as you can simply return the same data type back. If you slice a list, you return a list containing only the items in the range specified in the slice. If you slice a string, you return a string. And so on.
The slicing operations I'm describing above are solving an issue when working with constraints which make this behavior undesirable. For example, if you work with large data sets, the slice operations would lead to unnecessary additional memory allocations not to mention the performance impact of copying the data. This is especially true if the slices will have further processing done on them before getting to your final results. So, the goal of the slice implementation is to have references into larger data sets to avoid making unnecessary copies of the information until it becomes beneficial to do so.
The catch is that at the end of the processing the desire to turn the slice-based processed data back into a more API and .NET friendly type like lists, arrays, and strings. It makes the data easier to pass into other APIs. It also allows you to discard the slices, thus, also the large data set the slices referenced.
Would you even consider ToString giving you a useful output on a collection/enumerable type? Would that violate the principle of least surprise?
No, and yes. That would be completely unexpected behavior, since it would behave differently than every other collection type.
As for this:
What about converting back into a string as there's no built-in support for converting an IEnumerable>char< easily back into a string?
Personally, I would just use the string constructor taking an array:
string result = new string(mySlice.ToArray());
This is explicit, understood, and expected - I expect to create a new string by passing an object to a constructor.
Perhaps the reason for your conundrum is the fact that you are treating string as a ICollection<char>. You haven't provide details about the problem that you are trying to solve but maybe that's a wrong assumption.
It's true that a string is an IEnumerable<char>. But as you've noticed assuming a direct mapping to a collection of chars creates problems. Strings are just too "special" in the framework.
Looking at it from the other end, would it be obvious that the difference between an ISlice<char> and ISlice<byte> is that you can concatenate the former into a string? Would there be a concatenate operation on the latter that makes sense? What about ISlice<string>? Shouldn't I be able to concatenate those as well?
Sorry I'm not providing specific answers but maybe these questions will point you at the right solution for your problem.
I have a large list of error messages that my biz code can return based on what's entered. The list may end up with more than a thousand.
I'd like to just enum these all out, using the [Description("")] attribute to record the friendly message.
Something like:
public enum ErrorMessage
{
[Description("A first name is required for users.")]
User_FirstName_Required = 1,
[Description("The first name is too long. It cannot exceed 32 characters.")]
User_FirstName_Length = 2,
...
}
I know enums are primitive types, integers specifically. There shouldn't be any problem with that many integers, right?
Is there something I'm not thinking of? It seems like this should be okay, but I figured I should ask the community before spending the time to do it this way.
Does .Net care about enum types differently when they have lots of values?
Update
The reason I didn't want to use Resources is because
a) I need to be able to reference each unique error message with an integer value. The biz layer services an API, in addition to other things, and a list of integer values has to be returned denoting the errors. I don't believe Resources allows you to address a resource value with an integer. Am I wrong?
b) There are no localization requirements.
I think a design that has 1,000+ values in an enum needs some more thought. Sounds like a "God Enum" anti-pattern will have to be invented for this case.
The main downside I'd point out with having the friendly description in an Attribute is that this will cause challenges if you ever need to localize your app for another language. If this is a consideration, it would be a good idea to put the strings in a resource file.
The enum itself should not be a problem, though having all of your error codes in one master list can be confusing. You may consider creating seperate enums for seperate categories of return codes, as this will make it easier for developers to understand the possible return values for a particular function. You can still give them distinct numeric values (by specifying the numeric values explicitly) if it's important that the codes be unique.
On a side note, the .NET BCL does not make much use of return codes and return codes are somewhat discouraged in modern .NET development. They create maintainability issues (you can almost never remove old return codes or risk breaking backwards compatibility) and they require special validation logic to handle the returns for every call. Stateful validation can be accomplished with IDataErrorInfo, where you use an intermediate class that can represent invalid states, but that only allows a Commit of changes that are validated. This allows you to manipulate the object freely, but also provide feedback to the user as to the validity of its state. The equivalent logic with error codes often requires a switch statement for each use.
1000 is not many, you should just make sure that the underlying integer type is big enough (don't use a char for your enum.
On second thought 1000 is tons if you're manually entering them, if they are generated from some data set it could make sense kinda...
I fully agree with duffymo. An enum with 1000+ values smells bad from y design point of view. Not to mention that it would be quite nasty for the developer to use intelligence on such a GOD ENUM:-)
I would better go for using resources.
I think it's very bad, for error handling you can simply use resource, as i see you want to do reflection and fetch the description its bad too.
If you don't want to use resources, you can define different enum for each of your business rules, Also your different business doesn't need others error message (and shouldn't be like this).