how to post plain json data to service stack rest service - servicestack

Below is the code I am using to post json data to a rest ful service
var client = new JsonServiceClient(BaseUri);
Todo d = new Todo(){Content = "Google",Order =1, Done = false };
var s = JsonSerializer.SerializeToString < Todo>(d);
// client.Post<string>("/Todos/", "[{\"content\":\"YouTube\"}]");
// string payload= "[{\"id\":2,\"content\":\"abcdef\",\"order\":1,\"done\":false}]";
// string payload = #"{""todo"":{ {""content"":""abcdef"",""order"":1}} }";
client.Post<string>("/todos/", s);
I tried passing plain json data , it keep on fialing with message "Bad data". Then i tried serizliing the entity that also didn't work.

You can use PostJsonToUrl, which is included in ServiceStack.Text.

Related

(Node.js) Create Egypt ITIDA CAdES-BES Signature with Automatic JSON Canonicalization

I am using an example (Node.js Create Egypt ITIDA CAdES-BES Signature with Automatic JSON Canonicalization) but I always get this error ( 4043 4043:message-digest attribute value does not match calculated value[message-digest attribute value does not match calculated value] ).
Can you help me with the solution?
Code Used:
// This example assumes the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
var crypt = new chilkat.Crypt2();
crypt.VerboseLogging = true;
var cert = new chilkat.Cert();
cert.VerboseLogging = true;
// Set the smart card PIN, which will be needed for signing.
cert.SmartCardPin = "12345678";
// There are many ways to load the certificate.
// This example was created for a customer using an ePass2003 USB token.
// Assuming the USB token is the only source of a hardware-based private key..
var success = cert.LoadFromSmartcard("");
if (success !== true) {
console.log(cert.LastErrorText);
return;
}
// Tell the crypt class to use this cert.
success = crypt.SetSigningCert(cert);
if (success !== true) {
console.log(crypt.LastErrorText);
return;
}
var cmsOptions = new chilkat.JsonObject();
// Setting "DigestData" causes OID 1.2.840.113549.1.7.5 (digestData) to be used.
cmsOptions.UpdateBool("DigestData",true);
cmsOptions.UpdateBool("OmitAlgorithmIdNull",true);
// Indicate that we are passing normal JSON and we want Chilkat do automatically
// do the ITIDA JSON canonicalization:
cmsOptions.UpdateBool("CanonicalizeITIDA",true);
crypt.CmsOptions = cmsOptions.Emit();
// The CadesEnabled property applies to all methods that create CMS/PKCS7 signatures.
// To create a CAdES-BES signature, set this property equal to true.
crypt.CadesEnabled = true;
crypt.HashAlgorithm = "sha256";
var jsonSigningAttrs = new chilkat.JsonObject();
jsonSigningAttrs.UpdateInt("contentType",1);
jsonSigningAttrs.UpdateInt("signingTime",1);
jsonSigningAttrs.UpdateInt("messageDigest",1);
jsonSigningAttrs.UpdateInt("signingCertificateV2",1);
crypt.SigningAttributes = jsonSigningAttrs.Emit();
// By default, all the certs in the chain of authentication are included in the signature.
// If desired, we can choose to only include the signing certificate:
crypt.IncludeCertChain = false;
var jsonToSign = "{ ... }";
// Create the CAdES-BES signature.
crypt.EncodingMode = "base64";
// Make sure we sign the utf-8 byte representation of the JSON string
crypt.Charset = "utf-8";
var sigBase64 = crypt.SignStringENC(jsonToSign);
if (crypt.LastMethodSuccess == false) {
console.log(crypt.LastErrorText);
return;
}
console.log("Base64 signature:");
console.log(sigBase64);
Check to see if the information at this Chilkat blog post helps: https://cknotes.com/itida-4043message-digest-attribute-value-does-not-match-calculated-value/
See this example for details about debugging and what you can send to Chilkat: https://www.example-code.com/nodejs/itida_egypt_debug.asp
We were having this error, until we were advised of not using any null values in the json file. So, pls try to replace any null values in json file with "".

Azure Service Bus GetBody<Stream> encoding cannot be determined

I'm trying to get a BrokeredMessage from AzureServiceBus in a .NET client and choose how to deal with the message based on the type of message coming in, but ContentType and other message properties are not set.
My test message sending looks like this:
var client =
QueueClient.CreateFromConnectionString(connectionString, queueName);
var message = new BrokeredMessage("test");
client.Send(message);
My code to receive is using GetBody so that I can inspect the serialized data and decide how to deal with it:
var stream = message.GetBody<Stream>();
string s = null;
using (StreamReader sr = new StreamReader(stream))
{
s = sr.ReadToEnd();
}
The problem is that "s" above ends up with what looks like it should be XML created from a DataContractSerializer, but it is strangely encoded. I've tried many encodings on the receiving side and none seem to get me valid xml. Example results:
#string3http://schemas.microsoft.com/2003/10/Serialization/�test
I see the serialization namespace and what looks like it should start with <string, but as you can see I'm getting control characters. Does any one know how I can try to get the serialized data here as valid XML so I can dynamically handle it?
TIA for any help.
To be really clear I want to test the body so I can do something like:
if (BodyIsString(s)) { do something }
if (BodyIsPerson(s)) { do something else }
If I could getbody twice this would be really easy.
As Sean Feldman mentioned when send message is string type we could use
var body = message.GetBody<string>();
to get message body, after I decompile the WindowsAzure.ServiceBus.dll then get the code:
public T GetBody<T>()
{
if (typeof (T) == typeof (Stream))
{
this.SetGetBodyCalled();
return (T) this.BodyStream;
}
if (!this.bodyObjectDecoded || this.bodyObject == null)
return this.GetBody<T>((XmlObjectSerializer) new DataContractBinarySerializer(typeof (T)));
this.SetGetBodyCalled();
return (T) this.bodyObject;
}
I find that if the send message
is not Stream type it will be DataContractBinarySerializer. so we also could get the message body with following way
var stream = message.GetBody<Stream>();
var messageBody = new DataContractSerializer(typeof(string)).ReadObject(XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max));
From the decompiled code we could know that if we send the stream message, we could get the message body with the way you mentioned.
Send stream message code :
var client = QueueClient.CreateFromConnectionString(connectionString, queueName);
var byteArray = Encoding.UTF8.GetBytes("test stream");
MemoryStream stream = new MemoryStream(byteArray);
client.Send(new BrokeredMessage(stream));
then receive message as you mentioned it should work:
var stream = message.GetBody<Stream>();
string s = null;
using (StreamReader sr = new StreamReader(stream))
{
s = sr.ReadToEnd();
}
Edit :According to update question:
If I could getbody twice this would be really easy.
we could clone the BrokerMessage
var newMessage = receiveMessage.Clone();
Edit2:
We also can get the message Properties to know the body type if we set it during sending. Take Label for example:
var message = new BrokeredMessage(object);
message.Label = "Type of message body";
client.Send(message);
While we receive the message we could get the message Label value then select the corresponding way to get the body.
You passed your payload as a string
var message = new BrokeredMessage("test");
therefore it was serialized as a string. Upon receive you should get the body as a string as well in the following manner:
var body = message.GetBody<string>();
You would use Stream if you'd actually construct your brokered message using a stream.

ServiceStack Raw Client query string

This should be simple, but I must be using the wrong key words to find the answer.
How can I output the raw query string that the jsonserviceclient is generating when sending a request to the server? I know I could use fiddler or something else to snoop the answer to this, but I'm interested if there is something like:
var client = new JsonServiceClient("http://myService:port/");
var request = new MyOperation
{
SomeDate = DateTime.Today
};
Console.Out.Writeline(client.AsQueryString(request));
You can use the Reverse Routing extension methods to see what urls different populated Request DTOs would generate, e.g:
var relativeUrl = new MyOperation { SomeDate = DateTime.Today }.ToGetUrl();
var absoluteUrl = new MyOperation { SomeDate = DateTime.Today }.ToAbsoluteUri();

Servicestack-RabbitMq: Return response type in message headers

Is there any way to add the type of the response dto to the rabbitmq response message's headers collection?
(My consumer is using spring's rabbitmq handler which seems to depend on explicit type information inside the mq header when deserializing.)
Currently servicestack's mq producer already returns serveral headers, such as "content_type='application/json".
I am in need of an additional header, e.g. "typeId"="HelloResponse", so that the consuming web app knows how to deserialize the message, even in RPC cases where the response queue name is some kind of GUID.
Is there some kind of configuration which would enable me to archieve such an behaviour? Or some hook before the message gets published so that I can add the header myself?
I've added support for automatically populating the Message Body Type in RabbitMQ's IBasicProperties.Type as well as adding support for both Publish and GetMessage Filters in this commit.
Here's an example of configuring a RabbitMqServer with custom handlers where you can modify the message and its metadata properties when its published and received:
string receivedMsgApp = null;
string receivedMsgType = null;
var mqServer = new RabbitMqServer("localhost")
{
PublishMessageFilter = (queueName, properties, msg) => {
properties.AppId = "app:{0}".Fmt(queueName);
},
GetMessageFilter = (queueName, basicMsg) => {
var props = basicMsg.BasicProperties;
receivedMsgType = props.Type; //automatically added by RabbitMqProducer
receivedMsgApp = props.AppId;
}
};
mqServer.RegisterHandler<Hello>(m =>
new HelloResponse { Result = "Hello, {0}!".Fmt(m.GetBody().Name) });
mqServer.Start();
Once Configured any message published or received will go through the above handlers, e.g:
using (var mqClient = mqServer.CreateMessageQueueClient())
{
mqClient.Publish(new Hello { Name = "Bugs Bunny" });
}
receivedMsgApp.Print(); // app:mq:Hello.In
receivedMsgType.Print(); // Hello
using (IConnection connection = mqServer.ConnectionFactory.CreateConnection())
using (IModel channel = connection.CreateModel())
{
var queueName = QueueNames<HelloResponse>.In;
channel.RegisterQueue(queueName);
var basicMsg = channel.BasicGet(queueName, noAck: true);
var props = basicMsg.BasicProperties;
props.Type.Print(); // HelloResponse
props.AppId.Print(); // app:mq:HelloResponse.Inq
var msg = basicMsg.ToMessage<HelloResponse>();
msg.GetBody().Result.Print(); // Hello, Bugs Bunny!
}
This change is available from ServiceStack v4.0.33+ that's now available on MyGet.

how to pass in paramters to a post request using the servicestack json client

I'm having trouble getting my servicestack json client to format a REST Post request.
I'm trying to post to my login service with a raw json body of
{"Uname":"joe", "Password":"test"}
but the post methods is actually mistakenly sending this
{"login":""}
Here's the code I'm using.
JsonServiceClient.HttpWebRequestFilter = filter =>
{
filter.Headers.Add(string.Format("X-API-Key: {0}", "test"));
};
var client = new JsonServiceClient(url);
var url = "/login";
var login = new LoginModel { Uname = uname, Password = pwd };
return client.Post<UserCredentials>(url, login);
How should I structure the parameter object so that it serializes to the correctly to the intended raw value in the post request? Additionally, can I just pass in a dictionary or a more generic object so that I don't have to create a LoginModel class or struct?
It turns out the issue was that I was using public fields instead of public properties in my LoginModel. Changing it to properties fixed it.

Resources