How to Create Blob Output Bind with Queue Trigger Azure Function - blob

While Passing Blob name into Azure Function, it won't able to trigger while adding message to Queue
Not Working
#r "Newtonsoft.Json"
using System;
using Newtonsoft.Json;
public static void Run(string myQueueItem,
Stream outputBlob,
ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
dynamic data = JsonConvert.DeserializeObject(myQueueItem);
log.LogInformation($"We got a new Queue Request Type: {data.MessageType}");
if(data.MessageType == "Create Blob")
{
// outputBlob = data.Message;
}
// outputBlob = "";
string blobFileName = "tettet.script";
}
Working
I want the File To be created as the queue message contain in body section.
Also need to assign the Blob File Name from Queue Object as parameter.(uploadedscript/{blobFileName})

Use the code as below:
using System;
public static void Run(string myQueueItem,out string outputBlob,ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
outputBlob=myQueueItem;
}
And the function.json:
{
"bindings": [
{
"name": "myQueueItem",
"type": "queueTrigger",
"direction": "in",
"queueName": "queue",
"connection": "AzureWebJobsStorage"
},
{
"type": "blob",
"name": "outputBlob",
"path": "container/{queueTrigger}",
"connection": "AzureWebJobsStorage",
"direction": "out"
}
]
}

Related

SQL Server stored procedure in .NET Core 6 Web API to produce JSON data used in Angular app

I have a SQL Server stored procedure that has an ID parameter and returns a string in JSON format that is needed in the Angular app.
Here is a sample of the JSON needed:
[
{
"type": "date",
"name": "asofdate",
"ui":
{
"label": "As Of Date",
"placeholder": "Enter a date"
},
"validators": { "required": "true" }
},
{
"type": "select",
"name": "scope",
"ui": { "label": "Scope", "placeholder": "Select a scope" },
"validators": { "required": "true" },
"source": [
{ "value": 1, "text": "ABC" },
{ "value": 2, "text": "CDE" },
{ "value": 3, "text": "FGI" }
]
}
]
Here is a what the result of running the stored procedure looks like:
When I run the Web API passing the ID parameter to the stored procedure, I would like to capture the response as a JSON object to be used in the Angular app.
But the Web API is returning this:
[
{
"jsonResponse": "[
{
\"type\":\"date\",
\"name\":\"asofdate\",
\"ui\":{\"label\":\"As Of Date\",\"placeholder\":\"Enter a date\"},
\"validators\":{\"required\":\"true\"}
}
,
{
\"type\":\"select\",
\"name\":\"scope\",
\"ui\":{\"label\":\"Scope\",\"placeholder\":\"Select a scope\"},
\"validators\":{\"required\":\"true\"},
\"source\":[{\"value\":1,\"text\":\"ABC\"},{\"value\":2,\"text\":\"DEF\"},{\"value\":3,\"text\":\"GHI\"}]}
}
]
Is there a way to get the JSON response from the Web API without all the "\" and without:
{
"jsonResponse": "
so that it matches the sample above?
Here is the code from the Web API:
[HttpGet("{ReportID}")]
public async Task<ActionResult<IEnumerable<usp_ReportParameterResult>>> GetReportParameters(int ReportID)
{
if (_context.usp_ReportParameterAsync == null)
{
return NotFound();
}
var op = new OutputParameter<int>();
var JSONresponse = await _context.usp_ReportParameterAsync(ReportID, op);
if (JSONresponse == null)
{
return NotFound();
}
return JSONresponse;
}
The stored procedure uses JSON_QUERY and JSON PATH to create the needed nested arrays.
So, in the angular code I have the following hard-coded:
TESTDATA:any[] = [
{
type:'text',
name:'firstName',
validators:{
required:true
},
ui:{label:'First Name',placeholder:'Enter Your First Name'}
}
,
{
"type":"date",
"name":"asofdate",
"ui":{"label":"****As Of Date","placeholder":"Enter a date","class":["date-picker-wrapper"]},
"validators":{"required":"true"}
}
]
What I need is instead of this data being hrad-coded it is being dynamically generated from a Web API.
The hard-coded data looks like the following from browser debug:
[![enter image description here][2]][2]
From the web api data looks like the following:
It is not an array like the TESTDATA. Is the a way to get response from web api into an array format as required?
Actually, easiest solution was to remove the backlashes in the Angular app by simply doing the following:
for (let item of this.formattedJSON) {
item.ui = JSON.parse(item.ui);
item.validators = JSON.parse(item.validators);
}

Return string from Web API .NET Core get operation

I have a get operation that I want to return a string from. An example would be
"000875"
When I return this string from a controller in my Web API Controller in full .NET, it formats it like this:
{
"Property": "000875"
}
When I return the string in my converted .NET Core Controller it returns this:
{
"$id": "1",
"$type": "System.Net.Http.HttpResponseMessage, System.Net.Http",
"Version": "1.1",
"Content": {
"$id": "2",
"$type": "System.Net.Http.StringContent, System.Net.Http",
"Headers": [
{
"Key": "Content-Type",
"Value": [
"application/json; charset=utf-8"
]
}
]
},
"StatusCode": "OK",
"ReasonPhrase": "OK",
"Headers": [],
"TrailingHeaders": [],
"RequestMessage": null,
"IsSuccessStatusCode": true
}
It is interesting to note that the value is not even in there!
I am running some interesting JSON Serialization to make BreezeJs work with .NET Core. It is possible that it is the cause of this weirdness:
.AddNewtonsoftJson(opt =>
{
// Let Breeze say how we serialize. This adds in the Type and Id options the way breeze expects
var jsonSerializerSettings = JsonSerializationFns.UpdateWithDefaults(opt.SerializerSettings);
......
I am hoping for a way to get strings through without all this mess. Can that be done?
I get the impression that the subject action definition returns HttpResponseMessage.
public HttpResponseMessage MyAction(....
HttpRequestMessage is no longer a first class citizen in asp.net-core framework and will be treated as a normal model and serialized.
That explains the JSON you are seeing with your controller
The syntax needs to be updated to return IActionResult derived responses
public IActionResult MyAction() {
//...
return Ok("000875");
}
ActionResult<T>
public ActionResult<string> MyAction() {
//...
if(somecondition)
return NotFound();
return "000875";
}
or the model itself.
public string MyAction() {
//...
return "000875";
}
Reference Controller action return types in ASP.NET Core Web API

Custom ASP.Net Core JSON model binder

My posted JSON object is this:
{{
"emails": [
{
"To": "info#gmail.com",
"Subject": "Subject",
"Body": "Body",
"ID": "d3d13242-6eff-4c57-b718-ef5ad49fe301"
},
{
"To": "hr#gmail.com",
"Subject": "Subject",
"Body": "Body",
"ID": "101edaf0-fcb4-48fc-9e9e-0d7492b591b0"
}
]
}}
By default ASP.NET model binder will not bind this JSON object and as you can see here I get always null when I send post request to the API:
[HttpPost, Route("Send")]
public async Task<IActionResult> Send(Email[] emails)
{
var toSave = from email in emails
select new EmailQueueItem
{
Html = true,
To = email.To,
Subject = email.Subject,
Body = email.Body
};
await Database.BulkInsert(toSave.ToArray());
return Ok();
}
emails property is always null. I would appreciate any help for creating custom model binder that handel this kind of JSON objects.
The issue is that you are actually sending an object containing one property named emails, not an array, to the controller
Option one:
The client object needs to contain just the array
[
{
"To": "info#gmail.com",
"Subject": "Subject",
"Body": "Body",
"ID": "d3d13242-6eff-4c57-b718-ef5ad49fe301"
},
{
"To": "hr#gmail.com",
"Subject": "Subject",
"Body": "Body",
"ID": "101edaf0-fcb4-48fc-9e9e-0d7492b591b0"
}
]
Then read the array from the request body
public async Task<IActionResult> Send([FromBody]Email[] emails)
Option 2:
When you define the array like this in the client
{
"emails":...
}
You need to match that object setup on the controller by defining a model which contains a property called emails
public class RequestModel
{
public Email[] emails { get; set; }
}
Then in the controller method, use the model and read it from the body
public async Task<IActionResult> Send([FromBody]RequestModel emails)

Tracking email with SendGrid alike MailGun

I'm studying some email services, as SensdGrid and MailGun.
In MailGun docs I found a really usefull function: https://documentation.mailgun.com/user_manual.html#events
You can simply ask to MailGun API the events triggered, sending also some filters. It is really simple and powerful. Here an example:
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class EventsDateTimeRecipientChunk
{
public static void Main (string[] args)
{
Console.WriteLine (EventsDateTimeRecipient ().Content.ToString ());
}
public static IRestResponse EventsDateTimeRecipient ()
{
RestClient client = new RestClient ();
client.BaseUrl = new Uri ("https://api.mailgun.net/v3");
client.Authenticator =
new HttpBasicAuthenticator ("api",
"YOUR_API_KEY");
RestRequest request = new RestRequest ();
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.Resource = "{domain}/events";
request.AddParameter ("begin", "Fri, 3 May 2013 09:00:00 -0000");
request.AddParameter ("ascending", "yes");
request.AddParameter ("limit", 25);
request.AddParameter ("pretty", "yes");
request.AddParameter ("recipient", "joe#example.com");
return client.Execute (request);
}
}
and an output sample:
{
"items": [
{
"tags": [],
"timestamp": 1376325780.160809,
"envelope": {
"sender": "me#samples.mailgun.org",
"transport": ""
},
"event": "accepted",
"campaigns": [],
"user-variables": {},
"flags": {
"is-authenticated": true,
"is-test-mode": false
},
"message": {
"headers": {
"to": "user#example.com",
"message-id": "20130812164300.28108.52546#samples.mailgun.org",
"from": "Excited User <me#samples.mailgun.org>",
"subject": "Hello"
},
"attachments": [],
"recipients": [
"user#example.com"
],
"size": 69
},
"recipient": "user#example.com",
"method": "http"
}
],
"paging": {
"next":
"https://api.mailgun.net/v3/samples.mailgun.org/events/W3siY...",
"previous":
"https://api.mailgun.net/v3/samples.mailgun.org/events/Lkawm..."
}
}
Is it possible I can't find the same feature in SendGrid? I'm getting crazy searching in their documents.. I found the webhooks, but it isn't what I need. I only want to see the email status with a http request like MailGun does.
Can you help me?
Hope you figured it out by now,
Yet here's for the future :
You should use the webhooks, as follows:
1 configure the apps: clicktrack, opentrack& .what_you_want_to_tarck.. & eventnotify to true, with Get & activate
2 create a POSTURL using RequestPin,
3 activate the event notification from mail settings in dashboard & check the events you want , when you press the testYourIntegration button, you should get the example post request to the created url.
use this code as described in the official documentation:
string apikey = "......."
sg = sendgrid.SendGridAPIClient(apikey=os.environ.get( apikey ))
to_email = Email("....#gmail.com")
from_email =Email ("....")
subject= '...'
content = Content("text/plain","Trying SendGrid")
mail = Mail(from_email, subject, to_email, content)
response = sg.client.mail.send.post(request_body=mail.get())
Now , go & open or click the email sent by code, to declench the event .., then go back
https://requestb.in/Your_bin_id?inspect
& you should see the notifications after a little while
for more, you can then go to :
https://requestb.in/api/v1/bins/bin_id/requests
do a Get request with code & just parse the JSON

Using .Net Core Web API with JsonPatchDocument

I am using JsonPatchDocument to update my entities, this works well if the JSON looks like the following
[
{ "op": "replace", "path": "/leadStatus", "value": "2" },
]
When i create the object it converts it with the Operations node
var patchDoc = new JsonPatchDocument<LeadTransDetail>();
patchDoc.Replace("leadStatus", statusId);
{
"Operations": [
{
"value": 2,
"path": "/leadStatus",
"op": "replace",
"from": "string"
}
]
}
if the JSON object looks like that the Patch does not work. I believe that i need to convert it using
public static void ConfigureApis(HttpConfiguration config)
{
config.Formatters.Add(new JsonPatchFormatter());
}
And that should sort it out, the problem is i am using .net core so not 100% sure where to add the JsonPatchFormatter
I created the following sample controller using the version 1.0 of ASP.NET Core. If I send your JSON-Patch-Request
[
{ "op": "replace", "path": "/leadStatus", "value": "2" },
]
then after calling ApplyTo the property leadStatus will be changed. No need to configure JsonPatchFormatter. A good blog post by Ben Foster helped me a lot in gaining a more solid understanding - http://benfoster.io/blog/aspnet-core-json-patch-partial-api-updates
public class PatchController : Controller
{
[HttpPatch]
public IActionResult Patch([FromBody] JsonPatchDocument<LeadTransDetail> patchDocument)
{
if (!ModelState.IsValid)
{
return new BadRequestObjectResult(ModelState);
}
var leadTransDetail = new LeadTransDetail
{
LeadStatus = 5
};
patchDocument.ApplyTo(leadTransDetail, ModelState);
if (!ModelState.IsValid)
{
return new BadRequestObjectResult(ModelState);
}
return Ok(leadTransDetail);
}
}
public class LeadTransDetail
{
public int LeadStatus { get; set; }
}
Hope this helps.