The API that I am using takes an XML string. The XML string is based on what request I am trying to do. So, if I have an instance of a customer in my application that does not yet exist in the API software, I create an AddRq XML string, which has all of the fields for the customer:
Once I process this Add request, I get the ID associated with it, which I save in my custom object. If I then decide I want to update the customer record, I need to pass an slightly different XML string:
<Name>John H. Smith</Name>
In my application, I still have just the one instance of this customer. Also, if I am wanting to delete this customer from the API software, I would pass this request:
In each of these cases I have to be specific about which fields get included in the request or it will be rejected. If I were to include any other fields besides the ID in the delete request, the entire request is rejected and ignored. There's also some other factors based on the version of the API that might be in use. For example, they added a feature for tracking Currency in version 12, but if my customer is still using version 11, I need to never include the Currency field in my Add or Mod request or the entire request is rejected.
One way to do this would be to separate out your creation of the serialization from the Customer class, so you would have a DeleteCustomer class, for instance, that would accept an instance of your customer and which would return the appropriate XML. This helps to separate the concerns of your code.
Serialization has nothing to do with functionality. It is solely about data. So it doesn't matter how you modify/update/create that data.
On a Delete request, I have to only supply the ID and the EditSequence fields
What you are referring to is generally about a 'difference'.
And it has nothing to do with the object itself.
The object represents a set of data and functionality associated with the data.
You are attempting to push functionality that involves a specific API and delivery of that data into the object itself. Bad idea.
What needs to happen is that the API layer (your code) needs to understand what it needs to deliver and then provide a way to do that. And not one that relies on the object to do it.
To provide a difference you MUST have two instances of the object. A before and an after. Then the API layer provides a way to either generally or specifically define the difference.
Be very careful in your design decision because a general approach ties one to the idea that ALL objects will be delivered using a difference. If there is even one exception then one must break the architecture to deal with it. Which is not the same an understanding that many objects, but not all, need to be handled with a difference.
One part of handling a difference also requires that one must be able to define the 'id'. That might not solely be one attribute. A general solution would require a way to recognize the specific attribute(s) that are the 'id'. That would either require metadata or hard coded by each object. One way, there ARE other ways, to provide the id is to require an interface on the the object that returns, as a string (generic solution) the id value.
And "null" elements can be suppressed from the output xml using attributes; so this is not an issue (either).
"Transactions" typically employ a "transaction code" that identifies what fields are "required", optional or not applicable. Using a common template for all you transactions should not be an issue with the proper "codes" and logic in place.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
The error is from the API. If I include a field in a request the entire request will be rejected. For example, in a Delete request I can ONLY pass the saved ID of this record. If I include any other information besides the ID (like the name of the customer) the entire request is rejected. If I include a blank <id> tag in an Add request it gets rejected instead of ignored. If I don't include the ID in a Modification request, the request gets rejected.
In this API, a Customer for example can be Added which has one XML Schema, if it already exists then I need to use the Mod XML schema which is slightly different. If I want to delete this Customer, then I have to use the Del XML Schema. All of the data for these schema are coming from my single customer instance.
When I deal with XML API's, I often just convert the XML to classes (using "Paste special" initialy); operate on the classes; and then serialize any "output" classess to strings (i.e. xml) for transmission, using the XmlSerializer.
Thanks Gary. I actually wrote a generic method that I thought would take care of the casting issue, but now I'm getting an "unable to convert from type Object to type Long." I've posted it as a separate question because I'm probably not understanding what syntax to use.
Note that the generic method resolved the first problem I was having, which is that it was returning DBNull in situations for non-nullable types. I understand that the DB field is returned as an object and I understand that the object returned is not going to be implicitly converted to the C# types.
What I can't understand is the syntax I need to use in the generic method. I suspect it's the <t> part because that's where I'm getting "Unable to cast type Object to type long" exceptions
///<summary>/// Converts DB types to C# Types and ensures that DBNull gets converted to the default value for the type.
///</summary>///<typeparamname="T">The expected return type</typeparam>///<paramname="value">The value of a column, straight form the database provider</param>///<returns>The value as its coorisponding C# Type, with DBNull converted to the default value of the type. </returns>public T DBToType<T> ( T value )
if ( !Convert.IsDBNull ( value ) )
return ( T ) Convert.ChangeType ( value , typeof ( T ) );
returndefault ( T ); //returns the default for the type... not null
You only need the async modifier if you've got an await in the method. All this method needs to do is return a Task or some kind, which your method isn't doing. A dirty conversion of your code to returning a Task would be:
public Task<CompanyEntity> GetCompany(int id)
return Task.Factory.StartNew<CompanyEntity>(() =>
using (var db = new JayhawkDB())
CompanyEntity results = null;
var query = from x in db.Companies
where x.Id == id
var record = query.FirstOrDefault<Company>();
results = new CompanyEntity
Id = record.Id,
CreatedById = record.CreatedById,
CreatedDT = record.CreatedDt,
DeletedById = record.DeletedById.GetValueOrDefault(),
DeletedDT = record.DeletedDt.GetValueOrDefault(),
CompanyName = record.CompanyName,
Abbreviation = record.Abbreviation,
Notes = record.Notes
The caller awaits this code, not the other way around.
Oh, and that try/catch block is pretty much useless if all you're going to do is catch all Exceptions and just re-throw them.
System.ItDidntWorkException: Something didn't work as expected.
This works, sort of. However, it does not give me the raw input from the keyboard so when AltGr is pressed it canges from Key.RightAlt => Key.LeftCtrl + Key.RightAlt whitch is Windows interpretation according to this: AltGr key - Wikipedia[^]. I dont want this, as I want the user to be able to "bind" any key to a spesific action.
That could work, but I also want it to react to a sequence of inputs like Visual Studio does. For instance, if you have selected parts of the code you can hold LeftCtrl + K, release the keys and press LeftCtrl + F, VS will format the code for you. Then KeyBoard.IsDown is not really usable.
The problem is that I need to know what happened on your keyboard before windows do changes to it.
I'd have to say this smells badly of spam - it's a limited trial of a paid-for app, and you've been here long enough to know that is the kind of thing that attracts "spam" and "spammer" votes and gets your account closed. Particularly when it's a "special promo" for CodeProject as the link implies.
I don't think spam was your intention, but I'd strongly suggest that you remove the link before it gets reported in S&A and you get kicked out.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!