I have trouble with the Microsoft.Azure.ServiceBus.Message class. I want to create a Message object containing a payload object and then read this object back from it. In my current example I am not even sending the Message through a real Azure bus; I'm just creating it in memory and then trying to read it.
I cannot figure out what type I am supposed to read the message body as. I've tried byte[], string and the original object type. In all my cases I get an XmlException: "The input source is not correctly formatted".
Can someone please tell me what I am doing wrong, either when encoding or decoding the Message?
[DataContract]
public class Thingy
{
[DataMember]
public string Doodad { get; set; }
}
private static Message CreateMessage()
{
var entityMessage = new Thingy {Doodad = "foobar"};
var serializedMessageBody = JsonConvert.SerializeObject(entityMessage);
var contentType = typeof(Thingy).AssemblyQualifiedName;
var bytes = Encoding.UTF8.GetBytes(serializedMessageBody);
var message = new Message(bytes) {ContentType = contentType};
return message;
}
[Test]
public void ReadMessageBytes()
{
var message = CreateMessage();
var body = message.GetBody<byte[]>();
Console.WriteLine(body);
}
[Test]
public void ReadMessageString()
{
var message = CreateMessage();
var body = message.GetBody<string>();
Console.WriteLine(body);
}
[Test]
public void ReadMessageThingy()
{
var message = CreateMessage();
var body = message.GetBody<Thingy>();
Console.WriteLine(body);
}
I found out that this works:
[Test]
public void ReadMessageProperly()
{
var message = CreateMessage();
var body = message.Body;
var text = Encoding.UTF8.GetString(body);
var thingy = JsonConvert.DeserializeObject<Thingy>(text);
Assert.IsInstanceOf<Thingy>(thingy);
Assert.AreEqual("foobar", thingy.Doodad);
}
When creating a BrokeredMessage using custom DataContract type and using DataContractSerializer :
Record recordDataContract = new Record { Id = "DataContract Record" };
BrokeredMessage recordDataContractMessage = new BrokeredMessage(recordDataContract, new DataContractSerializer(typeof(Record)));
You can receive this message as:
Record r = receiveMessage.GetBody<Record>(new DataContractSerializer(typeof(Record)));
When creating a **BrokeredMessage** using custom **DataContract** type and using default serializer (DataContract + Binary Xml):
[DataContract(Namespace = "")]
class Record {
[DataMember]
public string Id { get; set; }
}
Record recordDefault = new Record { Id = "default Record" };
BrokeredMessage recordDefaultMessage = new BrokeredMessage(recordDefault);
You can receive this message as:
Record r = receiveMessage.GetBody<Record>();
For additional reference , you can check this blog. It has detailed example for different scenarios.
Hope it helps.
Related
I have C# object
Step1Members step1Members = new Step1Members()
{
businessName = "Test business",
contactName = "Test User"
};
I want to convert step1Members into DynamoDB json like below.
{"businessName" : { "S" : "Test business" }, "contactName" : { "S" : "Test User" }}
Please help me on this.
You can actually do it using the EfficientDynamoDb.
Based on your example, let's imagine you have a class like this:
public class Step1Members
{
[DynamoDbProperty("businessName")]
public string BusinessName { get; set; }
[DynamoDbProperty("contactName")]
public string ContactName { get; set; }
}
In order to generate a DynamoDb JSON, you need to:
// Create DynamoDb context, credentials are not required for JSON generation, only for real database calls
var context = new DynamoDbContext(new DynamoDbContextConfig(RegionEndpoint.EUCenteral1, new AwsCredentials("public_key", "private_key")));
var step1Members = new Step1Members()
{
BusinessName = "Test business",
ContactName = "Test User"
};
await using var memoryStream = new MemoryStream();
await using var jsonWriter = new Utf8JsonWriter(memoryStream);
// Convert a class object into the document
var document = context.ToDocument(step1Members);
// Write the document using Utf8JsonWriter
jsonWriter.WriteStartObject();
foreach (var attribute in document)
{
jsonWriter.WritePropertyName(attribute.Key);
attribute.Value.Write(jsonWriter);
}
jsonWriter.WriteEndObject();
jsonWriter.Flush();
// Read the final JSON string from the memory stream
var jsonString = Encoding.UTF8.GetString(memoryStream.ToArray());
If you don't want to create a C# class for every single use-case, you can just use the plain Document class, which is basically a dictionary.
I want to serialize some json data I get from the web to classes and use the data, so I went to http://json2csharp.com/ and turned the json as below
json: [{"line_descr":"\u03a0\u0395\u0399\u03a1\u0391\u0399\u0391\u03a3 -
\u0392\u039f\u03a5\u039b\u0391","line_descr_eng":"PEIRAIAS - VOYLA"}]
To this class:
public class RootObject
{
public string line_descr { get; set; }
public string line_descr_eng { get; set; }
}
This is my code:
class LineName
{
public async static Task<RootObject> GetLineName(int linecode)
{
var http = new HttpClient();
var response = await http.GetAsync("http://telematics.oasa.gr/api/?act=getLineName&p1=962");
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject)serializer.ReadObject(ms);
return data;
}
}
[DataContract]
public class RootObject
{
[DataMember]
public string line_descr { get; set; }
[DataMember]
public string line_descr_eng { get; set; }
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
RootObject myLine = await LineName.GetLineName(92);
ResultTextBlock.Text = myLine.line_descr_eng;
}
So when I try to get the data and display it in my textblock I get the error: line_descr_eng is null.
Can someone point where the fault is ? since the line_descr_eng should be
PEIRAIAS - VOYLA but mine is null and after a lot of searching I cant find where the fault is.
Your json is an array, not an object, and you should deserialize it into an array.
public async static Task<RootObject[]> GetLineName(int linecode)
{
var http = new HttpClient();
var response = await http.GetAsync("http://telematics.oasa.gr/api/?act=getLineName&p1=962");
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject[]));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject[])serializer.ReadObject(ms);
return data;
}
//...
var myLines = await LineName.GetLineName(92);
var myLine = myLines.FirstOrDefault();
Also you don't need a memory stream, you can read stream from the http response
var result = await response.Content.ReadAsStreamAsync();
You simple can use the JavaScriptSerializer class instead of DataContractJsonSerializer like this:
Replace:
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject)serializer.ReadObject(ms);
with this:
var ser = new JavaScriptSerializer();
var test = ser.Deserialize<List<RootObject>>(json);
If you cannot find JavaScriptSerializer, then you have to do the simple following steps:
Right click References and do Add Reference, then from Assemblies->Framework select System.Web.Extensions.
Now you should be able to add the following to your class file:
using System.Web.Script.Serialization;
Cited from: https://stackoverflow.com/a/15391388/5056173
Why do have this error on this part of the code ?
this part
var data = serializer.Deserialize<EmailTemplate>(httpRequest.Form["data"].ToString());
my procedure
public int UpdateEmailTemplate()
{
HttpResponseMessage result = null;
ObjectService uploadFile = new ObjectService();
List<ActiveUp.Net.Mail.Attachment> attachment = new List<ActiveUp.Net.Mail.Attachment>();
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Form["data"] != null)
{
var serializer = new JavaScriptSerializer();
var data = serializer.Deserialize<EmailTemplate>(httpRequest.Form["data"].ToString());
if (httpRequest.Files.Count > 0)
{
var docfiles = new List<string>();
foreach (string file in httpRequest.Files)
{
MemoryStream target = new MemoryStream();
httpRequest.Files[file].InputStream.CopyTo(target);
uploadFile.AddObject(data.Id, "SU_ENTITY_MSG_TEMPLATE","", target.GetBuffer(), httpRequest.Files[file].FileName);
}
}
AdminService List = new AdminService();
return List.UpdateEmailTemplate(data);
}
MY class
public class EmailTemplate
{
public int Id;
public string TypeObject;
public int? idObject;
public string ObjectName;
public string IdTeam;
public string IdTask;
public string Team;
public string task;
public string Title;
public string Subject;
public string dataHtml;
public List<Objects> fileListRequest;
}
It's pretty plainly saying that the contents of:
httpRequest.Form["data"]
...is an array of some sort. Adding .ToString() will just return it's type name. Passing that to Deserialize is what's giving you the error, as Deserialize is expecting an array and just getting a string.
Try taling the .ToString() off - this may not work. If it doesn't you'll have to convert httpRequest.Form["data"] to what ever data type you've put into it (whuich you do not say).
I would like to make message in MSMQ which will have text for example
<order><data id="5" color="blue"/></order>
This is standard XML. So far I have made Serializable class
[Serializable]
public class order
string id
string color
I am using BinaryFormatter. When i check the message.BodyStream there are some chars which are not supposed to be there( 00,01,FF ), then I cannot receive this message without error.
This task seems to be simple, just put text
<order><data id="5" color="blue"/></order>
into msmq.
Mine whole important code:
public static void Send()
{
using (message = new Message())
{
request req = new request("1", "blue");
message.Recoverable = true;
message.Body = req.ToString();
message.Formatter = new BinaryMessageFormatter();
using (msmq = new MessageQueue(#".\Private$\testrfid"))
{
msmq.Formatter = new BinaryMessageFormatter();
msmq.Send(message, MessageQueueTransactionType.None);
}
}
}
[Serializable]
public class request
{
private readonly string _order;
private readonly string _color;
public request(string order, string color)
{
_order = order;
_color = color;
}
public request()
{ }
public string Order
{
get { return _order; }
}
public string Color
{
get { return _color; }
}
public override string ToString()
{
return string.Format(#"<request> <job order = ""{0}"" color = ""{1}"" /> </request>",_order,_color);
}
}
Your question isn't very clear at all; you can send any type of message you like to MSMQ, so long as you use the BinaryMessageFormatter. Here's an example:
string error = "Some error message I want to log";
using (MessageQueue MQ = new MessageQueue(#".\Private$\Your.Queue.Name"))
{
BinaryMessageFormatter formatter = new BinaryMessageFormatter();
System.Messaging.Message mqMessage = new System.Messaging.Message(error, formatter);
MQ.Send(mqMessage, MessageQueueTransactionType.Single);
MQ.Close();
}
I have not found reason why the Message.Body contains these ascii characters before the string I pass to Body. I just fill directly BodyStream instead of Body and let it convert itself:
Message.BodyStream = new MemoryStream(Encoding.ASCII.GetBytes(string i want to put as Body))
Then the message is simply only the string with nothing else.
You don't need the serializable class to send a string to a message queue.
Since you are using the BinaryMessageFormatter, you must first convert your string to a byte array using a text encoder e.g.
message.Body = new UTF8Encoding().GetBytes(req.ToString());
I'm just using UTF8 as an example, you can use whatever encoding you like.
Then when you read the message from the queue, remember to use the same encoding to get your string back e.g.
string myString = new UTF8Encoding().GetString(message.Body);
Hope this helps
Been trying to figure out how to parse out "in_reply_to_status_id_str -> id_str" form the twitter search page:
https://twitter.com/phoenix_search.phoenix?q=hello&headers%5BX-Twitter-Polling%5D=true&headers%5BX-PHX%5D=true&since_id=203194965877194752&include_entities=1&include_available_features=1&contributor_details=true&mode=relevance&query_source=unknown
Anyone that could write a small example to show how it can be done?
Using Json.Net
dynamic jObj = JsonConvert.DeserializeObject(new WebClient().DownloadString("your url"));
foreach (var item in jObj.statuses)
{
Console.WriteLine("{0} {1}", item.in_reply_to_status_id_str, item.id_str);
}
SO here is where I pull my Json, this is where my list gets made, which you all ready have:
public JsonResult AllStatuses() //from the json called in the _client view
{
var buildStatuses = new List<BuildStatus>();
var projects = Client.AllProjects();
foreach (var project in projects)
{
try
{
var buildConfigs = Client.BuildConfigsByProjectId(project.Id);
foreach (var buildConfig in buildConfigs)
{
var b = new BuildStatus();
var build = Client.LastBuildByBuildConfigId(buildConfig.Id);
var status = build.Status; // Used to loop through BuildConfigID's to find which is a FAILURE, SUCCESS, ERROR, or UNKNOWN
var change = Client.LastChangeDetailByBuildConfigId(buildConfig.Id); // Provides the changeID
var changeDetail = Client.ChangeDetailsByChangeId(change.Id); // Provides the username, this one populates the usernames
if (changeDetail != null)
b.user = changeDetail.Username;
b.id = buildConfig.Id.ToString();
// If the date isn't null place the start date in long format
if (build.StartDate != null)
b.date = build.StartDate.ToString();
// If block; set the status based on the BuildconfigID from the var status
if (status.Contains("FAILURE")){
b.status = "FAILURE";
}
else if (status.Contains("SUCCESS")){
b.status = "SUCCESS";
}
else if (status.Contains("ERROR")){
b.status = "ERROR";
}
else{
b.status = "UNKNOWN";
}
buildStatuses.Add(b);
}
} catch { }
}
var query = buildStatuses.OrderBy(x => x.status); // Create a sorted list from Error - Unknown
return Json(query, JsonRequestBehavior.AllowGet);
Then I copied the JsonConverter I linked you too.
On my Website I finally pulled apart the list of Json with.
public JsonResult AllStatuses() //from the json called in the _client view
{
List<Client> clients = storeDB.Clients.Include("Projects").Include("Projects.Builds").ToList();
var buildStatuses = new List<BuildStatus>();
foreach (var client in clients) {
// Network credentials
// Used to get the Json Service request // URL here: client.ClientURL
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:81/Status/AllStatuses");
var response = request.GetResponse();
var reader = new StreamReader(response.GetResponseStream());
var responseString = reader.ReadToEnd();
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters((new[] { new DynamicJsonConverter() }));
dynamic obj = serializer.Deserialize(responseString, typeof(object)) as dynamic;
foreach (var objects in obj) // Pull apart the dynamic object
{
var id = objects.id;
var status = objects.status;
var date = objects.date;
var user = objects.user;
var bs = new BuildStatus();
try
{
bs.status = status;
bs.date = date;
bs.id = id;
bs.user = user;
}
catch { throw; }
buildStatuses.Add(bs);
}
}
return Json(buildStatuses, JsonRequestBehavior.AllowGet);
}
Go for a jQuery approach:
var obj = jQuery.parseJSON(jsonString);
alert(obj.in_reply_to_status_id_str.id_str);
You can use this json libraryfor accomplish this.
You could also use the DataContractJsonSerializer class available in .NET once you add a reference to System.Runtime.Serialization.
All you need to do is a create two DataContract classes. Something like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
namespace MyNamespace
{
[DataContract]
public class TwitterObject
{
[DataMember(Name = "statuses")]
public TwitterStatus[] Statuses { get; set; }
}
[DataContract]
public class TwitterStatus
{
[DataMember(Name = "in_reply_to_status_id_str")]
public string InReplyToStatusIdStr { get; set; }
[DataMember(Name = "id_str")]
public string IdStr { get; set; }
}
}
Then from any other method you wish, you just have to use the DataContractJsonSerializer to build your JSON into a .NET object:
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(TwitterObject));
// assume the twitterResponse is the JSON you receive
MemoryStream memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(twitterResponse));
var twitterJson = jsonSerializer.ReadObject(memoryStream) as TwitterObject;
There may be some typos, but this should give you the hint. I'm currently working on an extensive synchronization between a server app and a website and this is the method I currently use for JSON communication between the two. I've found the combination of DataContracts and DataContractJsonSerializer is easier to use than 3rd party libraries.