sanjay
sanjay

Reputation: 31

Publish a json message to AWS SNS topic using C#

I Am trying to publish a Json Message to AWS SNS topic from my C# Application using AWS SDk. Its [enter image description here][1]populating message in string format and message attribute filed is not populated.

Code sample is as below:

        var snsClient = new AmazonSimpleNotificationServiceClient(accessId, secretrkey, RegionEndpoint.USEast1);
        PublishRequest publishReq = new PublishRequest()
        {
            TargetArn = topicARN,
            MessageStructure = "json",
            Message = JsonConvert.SerializeObject(message)
        };
        var msgAttributes = new Dictionary<string, MessageAttributeValue>();
        var msgAttribute = new MessageAttributeValue();
        msgAttribute.DataType = "String";
        msgAttribute.StringValue = "123";
        msgAttributes.Add("Objectcd", msgAttribute);
        publishReq.MessageAttributes = msgAttributes;
        PublishResponse response = snsClient.Publish(publishReq);

Upvotes: 3

Views: 3124

Answers (2)

Bruno Schaatsbergen
Bruno Schaatsbergen

Reputation: 406

Great coincidence! I was just busy writing a C# implementation to publish a message to SNS when I stumbled up on this post. Hopefully this helps you.

The messageBody argument we pass down to PublishMessageAsync is a string, it can be deserialized JSON for example.

public class SnsClient : ISnsClient
{
    private readonly IAmazonSimpleNotificationService _snsClient;
    private readonly SnsOptions _snsOptions; // You can inject any options you want here.

    public SnsClient(IOptions<SnsOptions> snsOptions, // I'm using the IOptionsPattern as I have the TopicARN defined in the appsettings.json
        IAmazonSimpleNotificationService snsClient)
    {
        _snsOptions = snsOptions.Value;
        _snsClient = snsClient;
    }

    public async Task<PublishResponse> PublishMessageAsync(string messageBody)
    {
        return await _snsClient.PublishAsync(new PublishRequest
        {
            TopicArn = _snsOptions.TopicArn,
            Message = messageBody
        });
    }
}

Also note the above setup uses Dependency Injection, so it would require you to set up an ISnsClient and you register an instance when bootstrapping the application, something as following:

services.TryAddSingleton<ISnsClient, SnsClient>();

Upvotes: 0

xf-boy
xf-boy

Reputation: 1

Older question but answering as I came across when dealing with similar issue

When you set the MessageStructure to "json".
The json must contain at least a top-level JSON key of "default" with a value that is a string.
So json needs to look like
{ "default" : "my message" }
My solution looks something like

   var messageDict = new Dictionary<string,object>()
   messageDict["default"] = "my message";
   PublishRequest publishReq = new PublishRequest()
        {
            TargetArn = topicARN,
            MessageStructure = "json",
            Message = JsonConvert.SerializeObject(messageDict)
        };
        // if json is an object
        // then 
        messageDict["default"] = JsonConvert.SerializeObject(myMessageObject); 

I'm am using PublishAsync on v3

From the documentation https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/SNS/TPublishRequest.html

Message structure
Gets and sets the property MessageStructure.

Set MessageStructure to json if you want to send a different message for each protocol. For example, using one publish action, you can send a short message to your SMS subscribers and a longer message to your email subscribers. If you set MessageStructure to json, the value of the Message parameter must:

be a syntactically valid JSON object; and

contain at least a top-level JSON key of "default" with a value that is a string.

You can define other top-level keys that define the message you want to send to a specific transport protocol (e.g., "http").

Valid value: json

Upvotes: 0

Related Questions