I have a WCF service receiving data from a client. The data in the client has a time stamp in it. As part of some troubleshooting, I used the WCF Trace tools and noticed that the time stamp saved on the client side is serialized with the client time offset in it, but when the message is received on the server, the time offset shows up with the server time offset.
Example:
Client is GMT-2
Server is GMT-7
Trace log on the client has a field in the message that says:
2021-12-02T20:24:10.1234567-02:00
Trace log on the server has that message but the timeStamp listed as:
2021-12-02T20:24:10.1234567-07:00
I found this very strange and tried to dig deeper. My hypothesis was that during deserialization WCF may have automatically converted it, but I would assume that the raw message if printed out as string would have the "-02:00" in it. So I implemented a message filter and output the message using:
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
_logger.Information($"message: {request.ToString()}");
...
}
Running this, my logged message however still shows a converted rather than original time stamp.
My next hypothesis was that the Message.ToString method was deserializing it with whatever default deserializer we have. So I tried to use an XMLSerializer to parse just the timestamp out myself:
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
var bufferedMessage = request.CreateBufferedCopy(int.MaxValue);
var message = bufferedMessage.CreateMessage();
var xmlOutput = "";
var xmlReader = message.GetReaderAtBodyContents();
while (xmlReader.Read())
{
if (xmlReader.Name == "timeStamp")
{
xmlReader.Read();
_logger.Information($"Raw Timestamp: {xmlReader.Value}");
}
}
_logger.Information($"message :\r\n{xmlOutput}");
request = bufferedMessage.CreateMessage();
return null;
}
Yet I still get the timestamp returned in the server time zone.
This now leaves me out of ideas on what to try next because:
WCF Trace logs on client show that it definitely is putting in the "-2:00" client time zone in there.
MessageInspector logging on the server side shows that it is already converted to "-7:00" server time zone.
The server has no other endpoint behaviors configured (I checked the configuration file as well as the program itself)
The client configuration does not have any other endpoint behaviors configured
I have tried changing the ServiceOperation parameter type to string but get the same result (server timestamp shows up)
Anyone have any ideas on what's going on here or where I should probably check next?
Related
I am sending an MQ message and getting a messageID and correlationID back in return as expected, and I can capture the response from specific message that I send using the messageID returned by the MQ server.
I put my application into a load testing tool and I saw that in some cases the messageID returned by the queue manager was the same as a previous message, and in these cases the app failed to read the next message with the same messageID.
I'm not the owner of the queue manager and the response from the admin was "created your own message id".
Can I do that? Does the messageID need to have a specific format?
This is my code :
message = strInputMsg;
queueMessage = new MQMessage();
queueMessage.WriteString(message);
queueMessage.Format = MQC.MQFMT_STRING;
queueMessage.Expiry = timeOutExpiry;
queueMessage.ReplyToQueueName = QueueNameExpiry;
queuePutMessageOptions = new MQPutMessageOptions();
queuePutMessageOptions.Options = MQC.MQRO_COPY_MSG_ID_TO_CORREL_ID;
queue.Put(queueMessage, queuePutMessageOptions);
bytReturn = queueMessage.MessageId;
So can I set the MessageID property to my own message ID value before I send the message, like the below?
queueMessage.MessageId = myOwnMessageId
Yes, it's possible that the code sets the message ID explicitly but your code appears to not reuse the MQMD structure which is how that normally happens. It is more likely based on your description and code provided that the load testing tool is replaying the same messages multiple times and preserving the Message ID while doing so.
If MQ is allowed to set the Message ID it guarantees this to be unique within the queue manager for IDs that it generates. It does not guarantee a GUID across many queue managers but does attempt to ensure no collisions by including 12 characters of the QMgr name in the Message ID. So although we have no information as to which load testing tool is being used and if it employs message replay, that possibility seems much more likely than that MQ has a bug that duplicates message IDs during execution of the .Net MQMessage() class constructor.
Please see:
MQMessage.NET class which says "Creates an MQMessage object with default message descriptor information..." Of course, the default MQMD causes the QMgr to generate the Message ID.
MQMD - MsgId (MQBYTE24) which explains in a note at the bottom how MsgID is made to be unique and in the body how it can be controlled by the application putting the messages.
I am developing a custom transport agent for Exchange 2013. I am getting null in e.MailItem.Message.CalendarPart though I am sending a meeting request.
if (e.MailItem.Message.CalendarPart != null)
{
LocationProcessorStrategy.AddLocationInBody(e.MailItem.Message);
}
else
{
e.MailItem.Message.Subject += " [There is no calendar part - added by agent.]";
}
e.MailItem.Message.MapiMessageClass is giving me the value "IPM.Schedule.Meeting.Request" but CalendarPart is null.
That generally means that at the Messaging stage you trying to intercept the message there is no ICal Body part to parse. iCal is usually create post categorisation depending on the recipient type https://technet.microsoft.com/en-us/library/bb232174(v=exchg.150).aspx . So either push your Agent to run after categorisation has occurred or use the TNEFReader/TNEFWriter to parse the TNEFStream for the message. Note you may need two solution if you want process bother internal and external Calendar Invites because of the formats used.
I am using a WCF client proxy to call a web service. I am adding logging to each request using IClientMessageInspector. I want to get info out of the underlying HTTP message, and found out I can get it by the following:
public class WCFLoggingInspector : IClientMessageInspector
{
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var httpRequest = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
var method = httpRequest.Method;
return null;
}
}
While stepping through in the debugger, this works fine. However, running normally, I get an error from the Properties indexer: "A property with the name 'httpRequest' is not present"
Can anyone explain whats going on here, or an alternate way to get at the HttpRequest? (I'm also doing the same thing for AfterReceiveReply)
It seems that Visual Studio creates this when the debugger is attached.
if (!properties.ContainsKey(HttpRequestMessageProperty.Name))
properties.Add("httpRequest", new HttpRequestMessageProperty());
Source: Property httpRequest' not present
In C# using NMS API we set Response topic for ActiveMQ in this way
IDestination temp = session.CreateTemporaryTopic();
ITopic consumer = session.CreateConsumer(temp);
And while sending message we set it like this ...
TextMessage reqMessage = session.CreateTextMessage(message);
reqMessage.NMSReplyTo = temp;
How can we do the same thing using Stomp.js?
Most STOMP operations are done using specific headers that are placed in the Message that you send. In this case the 'reply-to' header indicates the address where the receiving client should send its response. So the pattern would be to send the message with the 'reply-to' header set, something like this depending on the library you are using:
stomp.subscribe("/temp-queue/response-queue")
stomp.publish("/queue/work-queue", "WORK", {"reply-to" => "/temp-queue/response-queue"})
Since you are using temp Topic you must ensure that there is subscriber prior to the response message being sent, otherwise it will not get all the replies.
I am using azure mobile services and I have the following code on the server:
request.respond(statusCodes.OK, "success");
On my windows store app I have:
await App.MobileService.GetTable<UserEntity>().InsertAsync(App.CurrentUser);
How can I retrieve the body message?
The mobile services client, expects the response content from a table call to return JSON on success. It will attempt to deserialize the response into the requested object (UserEntity) and mutate the item you passed in if successful.
Since the string you are returning ("success") is probably not able to be deserialized into a UserEntity object, I'd expect the insertAsync() to throw an error on along the lines of "Newtonsoft reader, unexpected character encountered..."
If you update your request.respond() to return a valid json packet like { name: 'username', address: '123 Home' }, etc then your App.CurrentUser object would be updated to reflect those changes.
note: If you're not seeing the above error, double check that your call to request.respond() is in the request.execute() success callback. You may be trying to write to the response a second time, and that second time will fail (and should be visible in your app's logs)