Service Bus Topic Doesn't Receive Messages When Using Newtonsoft to Deserialize - c#

I am trying to deserialize messages from a service bus topic created as follows (.NET 4.6.1):
SubscriptionClient ServiceBusClient =
SubscriptionClient.CreateFromConnectionString
(ConnectionString, Topic, SubscriptionName);
I then create the on message method as follows:
OnMessageOptions options = new OnMessageOptions();
options.AutoComplete = false;
options.AutoRenewTimeout = TimeSpan.FromMinutes(1);
ServiceBusClient.OnMessage((message) =>
{
try
{
Stream stream = message.GetBody<Stream>();
StreamReader reader = new StreamReader(stream);
string payload = reader.ReadToEnd();
dynamic deserialize = Newtonsoft.Json.Linq.JObject.Parse(payload);
var avl = AvlDatum.Parser.ParseFrom(Convert.FromBase64String(deserialize.body));
/* do other stuff here */
message.Complete();
}
catch (Exception)
{
message.Abandon();
}
}, options);
Using this code however I receive absolutely no messages. I thought something was wrong with the topic but if I comment out the line with the dynamic object it receives the messages fine. Why am I not able to use the Newtonsoft Parser/dynamic objects inside an OnMessage delegate? Any info would be appreciated.

Related

gRPC StarLink Router .Net

New Info:
I thought I would paste this in full as I can not seem to find any samples on the web of a c# solution for StarLink so hopefully anyone else looking for something may find this helpful and may contribute.
My New Proto File - (partial) - I took the advise of Yuri below. Thanks for the direction here. I was able to I have been using this tool and it has brought a lot of insight but I am still stuck on the c# side of the solution. I am an old VB.Net developer though I have done a bunch in c# I am by no means savvy in it and am probably missing something so simple. Again, any insight would be awesome. I can not post the full proto here as stack has char limit on posts. this is the first bit with messages etc. I can post more if it helps but trying to keep it to the important part.
syntax = "proto3";
option csharp_namespace = "SpaceX.API.Device";
package SpaceX.API.Device;
service Device {
//rpc Handle (.SpaceX.API.Device.Request) returns (.SpaceX.API.Device.Response) {}
//rpc Stream (stream .SpaceX.API.Device.ToDevice) returns (stream .SpaceX.API.Device.FromDevice) {}
rpc Handle (Request) returns (Response);
rpc Stream (Request) returns (Response);
}
message ToDevice {
string message = 1;
}
message Request {
uint64 id = 1;
string target_id = 13;
uint64 epoch_id = 14;
oneof request {
SignedData signed_request = 15;
RebootRequest reboot = 1001;
SpeedTestRequest speed_test = 1003;
GetStatusRequest get_status = 1004;
AuthenticateRequest authenticate = 1005;
GetNextIdRequest get_next_id = 1006;
GetHistoryRequest get_history = 1007;
GetDeviceInfoRequest get_device_info = 1008;
GetPingRequest get_ping = 1009;
SetTrustedKeysRequest set_trusted_keys = 1010;
FactoryResetRequest factory_reset = 1011;
GetLogRequest get_log = 1012;
SetSkuRequest set_sku = 1013;
UpdateRequest update = 1014;
GetNetworkInterfacesRequest get_network_interfaces = 1015;
PingHostRequest ping_host = 1016;
GetLocationRequest get_location = 1017;
EnableFlowRequest enable_flow = 1018;
GetHeapDumpRequest get_heap_dump = 1019;
RestartControlRequest restart_control = 1020;
FuseRequest fuse = 1021;
GetPersistentStatsRequest get_persistent_stats = 1022;
GetConnectionsRequest get_connections = 1023;
FlushTelemRequest flush_telem = 1026;
StartSpeedtestRequest start_speedtest = 1027;
GetSpeedtestStatusRequest get_speedtest_status = 1028;
ReportClientSpeedtestRequest report_client_speedtest = 1029;
InitiateRemoteSshRequest initiate_remote_ssh = 1030;
SelfTestRequest self_test = 1031;
SetTestModeRequest set_test_mode = 1032;
DishStowRequest dish_stow = 2002;
DishGetContextRequest dish_get_context = 2003;
DishSetEmcRequest dish_set_emc = 2007;
DishGetObstructionMapRequest dish_get_obstruction_map = 2008;
DishGetEmcRequest dish_get_emc = 2009;
DishSetConfigRequest dish_set_config = 2010;
DishGetConfigRequest dish_get_config = 2011;
StartDishSelfTestRequest start_dish_self_test = 2012;
WifiSetConfigRequest wifi_set_config = 3001;
WifiGetClientsRequest wifi_get_clients = 3002;
WifiSetupRequest wifi_setup = 3003;
WifiGetPingMetricsRequest wifi_get_ping_metrics = 3007;
WifiGetDiagnosticsRequest wifi_get_diagnostics = 3008;
WifiGetConfigRequest wifi_get_config = 3009;
WifiSetMeshDeviceTrustRequest wifi_set_mesh_device_trust = 3012;
WifiSetMeshConfigRequest wifi_set_mesh_config = 3013;
WifiGetClientHistoryRequest wifi_get_client_history = 3015;
TransceiverIFLoopbackTestRequest transceiver_if_loopback_test = 4001;
TransceiverGetStatusRequest transceiver_get_status = 4003;
TransceiverGetTelemetryRequest transceiver_get_telemetry = 4004;
}
reserved 1025, 3011, 3014;
}
message SignedData {
bytes data = 1;
bytes signature = 2;
}
My New .cs
I have tried many things from Microsoft's examples to thing I can gather from other samples. I simply can not get it to work and am lost. Again, any insight would be amazing and hopefully helpful to others looking for a solution in c#. You will see my commented code of this I have been playing with. Basically I am attempting to achieve three things and have made some movement in one of them.
Goals:
1 - Use Server Reflection to discover services.
I think I got this one resolved with dot-net grpc.
2 - Simply want to check available methods under a service and potentially either check or generate a new .proto file in case things change. StaLink does not publish its proto schema so I assume it could change anytime without warning.
3 - Just run any one of the available methods. I have tried the GetDeviceInfoRequest but can not seem to construct the request message properly. I have not been able to get this accomplishe in the gRPCurl tool either. I can do it on the basic service shown by Microsoft of course but these methods seem to be more complex and I simply get all kinds of errors.
Again, any insight or assistance would be amazing. Thanks to any and all in advance.
New .cs File
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Net.Client;
using Grpc.Reflection.V1Alpha;
using ServerReflectionClient = Grpc.Reflection.V1Alpha.ServerReflection.ServerReflectionClient;
using SpaceX.API.Device;
public class Program
{
static async Task Main(string[] args)
{
//SETUP CHANNEL AND CLIENT
using var channel = GrpcChannel.ForAddress("http://192.168.100.1:9200");
var client = new ServerReflectionClient(channel);
var StarLinkClient = new Device.DeviceClient(channel);
//using var call = StarLinkClient.StreamAsync(new ToDevice { Request = GetDeviceInfoRequest });
//await foreach (var response in call.ResponseStream.ReadAllAsync())
//var request = Device.GetDeviceInfoRequest;
//var reply = await StarLinkClient.HandleAsync(
// new Request {'"getDeviceInfo" : {} '});
//Console.WriteLine(reply.Message);
//=============================================SERVER REFLECTION=============================================================
Console.WriteLine("Calling reflection service:");
var response = await SingleRequestAsync(client, new ServerReflectionRequest
{
ListServices = "" // Get all services
});
Console.WriteLine("Services:");
foreach (var item in response.ListServicesResponse.Service)
{
Console.WriteLine("- " + item.Name);
Console.WriteLine();
var StarLink = item.Name;
//Console.WriteLine(StarLink.getStatus());
}
//=============================================SERVER REFLECTION=============================================================
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
void setupchannel()
{
}
private static Task SingleRequestAsync(ServerReflectionClient client, Metadata metadata)
{
throw new NotImplementedException();
}
private static async Task<ServerReflectionResponse> SingleRequestAsync(ServerReflectionClient client, ServerReflectionRequest request)
{
using var call = client.ServerReflectionInfo();
await call.RequestStream.WriteAsync(request);
Debug.Assert(await call.ResponseStream.MoveNext());
var response = call.ResponseStream.Current;
await call.RequestStream.CompleteAsync();
return response;
}
}
Again, thanks in advance to anyone willing to assist here. Hopefully this helps others as well.

How can I create HttpResponseDatagram and HttpResponseLayer in pcap.net

I cant create these objects in pcap.net
IpV4Datagram ip = packet.Ethernet.IpV4;
TcpDatagram tcp = ip.Tcp;
HttpDatagram http = tcp.Http;
// HttpResponseDatagram resdat=http.; How can i create them?
// HttpResponseLayer resp;
if (tcp.Http.Body != null && http.IsResponse)
body = resp.Body.ToString();
I'm trying to get HTTP Response Body from a tcp packet. If there is another way to do it can someone help?
In the Pcap.Net User Guide, there's a section about sending packets.
In that section, there is an example on how to create HttpRequestLayer, and creating HttpResponseLayer is very similar.
HttpRequestLayer httpLayer =
new HttpRequestLayer
{
Version = HttpVersion.Version11,
Header = new HttpHeader(new HttpContentLengthField(11)),
Body = new Datagram(Encoding.ASCII.GetBytes("hello world")),
Method = new HttpRequestMethod(HttpRequestKnownMethod.Get),
Uri = #"http://pcapdot.net/",
};
HttpResponseDatagram is creating by parsing an HTTP packet.
For example, by doing
packet.Ethernet.IpV4.Tcp.Http
There's no simple way of creating a Datagram without parsing a packet.

How can I add custom properties to a message with Apache.NMS.ActiveMQ (C#)?

I am starting with ActiveMQ in C#.
I serialize my object to json and send it without problem.
I would add properties to my message but I don't succeed. I have seen the setIntProperty(String name,int value) on few websites but I don't find it on Apache.NMS.ActiveMQ (C#).
Here my code :
ActiveMQ mom = new ActiveMQ();
ISession session = mom.Initialize();
IDestination dest = session.GetQueue(queueDestination);
using (IMessageProducer producer = session.CreateProducer(dest))
{
foreach (Store s in stores)
{
List<string> matchKeyProductList = db.GetProductsKeyList(websiteNumberID);
ArrayList arCodesProdToUpdate = db.GetProductsToUpdate(websiteNumberID);
JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue; //Augmentation de la propriété MaxJsonLenth
MessageObject message = new MessageObject(matchKeyProductList, arCodesProdToUpdate);
string jsonMessage = serializer.Serialize(message);
ITextMessage textMessage = producer.CreateTextMessage(jsonMessage);
producer.Send(textMessage);
}
}
mom.Cleanup();
Can anyone help me with an example, please ?
ITextMessage inherits from IMessage, which has a map of Properties, with several applicable set methods. You should be able to set these as follows, before sending:
ITextMessage textMessage = producer.CreateTextMessage(jsonMessage);
textMessage.Properties.SetInt("CustomInt", 1234);
textMessage.Properties.SetString("CustomString", "HelloWorld");
producer.Send(textMessage);

C# Extracting data from Json or DataSets - Porting from Python (Json to Dict)

I have the following Python script which I need to port to C#. This gets a JSON response from a URL and then pops it into a dictionary. Then it checks for the data next_page and if there is data (it's not empty) it then returns true. Underneath I'll paste the C# code I have but I'm really struggling to do the final part. I don't know and I certainly don't want to understand the data in the JSON response, I just want to know if the field next_page is there.
# Gets JSON response
response = requests.get(url, auth=(user, pwd))
if response.status_code != 200:
print('Status:', response.status_code, 'Problem with the request. Exiting.')
exit()
data = response.json()
if(data['next_page']):
return True
else:
return False
So this is the c# code I've got:
using Newtonsoft.Json;
string response = "";
using (WebClient client = new WebClient())
{
client.UseDefaultCredentials = true;
client.Credentials = new NetworkCredential(user, password);
try
{
response = client.DownloadString(url);
} catch (Exception e)
{
throw e;
}
}
XmlDocument xml = JsonConvert.DeserializeXmlNode(json, "RootObject");
XmlReader xr = new XmlNodeReader(xml);
DataSet ds = new DataSet("Json Data");
ds.ReadXml(xr);
From what I've seen on the web DataSets work best when you know what the data inside of it is. I just want to know if there is a field called next_page and if there is, is it empty or does it have data. I'm just struggling to get anything out of the DataSet.
You will want to include the JSON.net nuget package (http://james.newtonking.com/json) this lets you deserialize the JSON response into a dictionary (or preferably a new class) allowing you to access the response.
eg add this into your try catch after including the library
var dict = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
Alternativly you could create a new class that represents the expected JSON and deserialize into that
public class ResponseObject
{
public string next_page { get; set; }
}
var responseResult = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseObject>(response);

How to send an XDocument via MSMQ (using WCF)?

I have an order as an XDocument and I simply want to stick it in the body of a message and send it to an MSMQ queue. I've effectively serialized the order object already and now I just want to send it. Is this possible?
I'm using WCF here but I'd happy with a plain old msmq solution. I'm getting an error here indicating that an XDocument can't be serialized ... obviously can't do that, but how do I get my XDocument into the message body? Do I need to roll my own Serializer?
public void SendOrder(XDocument order)
{
var address = new EndpointAddress(#"msmq.formatname:DIRECT=OS:myServer\private$\myQueue");
var binding = new MsmqIntegrationBinding();
binding.Security.Mode = MsmqIntegrationSecurityMode.None;
binding.ExactlyOnce = false;
binding.Durable = false;
var channelFactory = new ChannelFactory<IOrderSubmitter>(binding, address);
var channel = channelFactory.CreateChannel();
var message = new MsmqMessage<XDocument>(order);
message.Label = "Really Big Order with lots of profit";
message.BodyType = (int)System.Runtime.InteropServices.VarEnum.VT_ARRAY;
using (var scope = new TransactionScope(TransactionScopeOption.Required))
{
channel.SubmitOrder(message);
scope.Complete();
}
}
[ServiceContractAttribute(Namespace = "http://my.namespace.com", Name = "Hello")]
public interface IOrderSubmitter
{
[OperationContract(IsOneWay = true)]
void SubmitOrder(MsmqMessage<XDocument> message);
}
An XDocument is a convenient wrapper over XML data. There is no need to serialize the XDocument, just send the XML data as a string, using XDocument.ToString()
I'm having the same problem developing on a Windows 7 box. It's putting my XML string inside another xml. Everything works just fine in server 2003.
I was finally able to fix this. There seem to be two ways to do this. Both involve setting the Formatter to XmlMessageFormatter. You can either set the Formatter on the MessageQueue or you can set it on the message before you send and after you peek/receive.
messageQueue.Formatter = new System.Messaging.XmlMessageFormatter(new Type[] { typeof(System.String) });

Categories