Can we bind to connection string value in order to simply output-bind to a specific storage account?
I would like to create a blob mover, where the consumer would pass an object like:
{
"sourceConnection":"..blob connection string",
"destinationConnection":"...blob connection string",
"filename":"/someContainer/someDir/myfile.jpg"
}
The function would be trigger by a queue:
{
"name": "myQueueItem",
"queueName": "myqueue-items",
"connection":"",
"type": "queueTrigger",
"direction": "in"
}
...where myQueueItem would have the payload as above.
How do we move a blob from sourceConnection to destinationConnection?
I'm specifying both the javascript as well as c# tags, because I need to make a solution in either one.
If we assumed that the source as well as destination storage accounts were the same, we could simply write a function to move blobs between two containers like so:
public static class BlobMover
{
[StorageAccount("Connection")]
[FunctionName("BlobMover")]
public static async Task Run(
[QueueTrigger("%BlobMover:TriggerQueue%")] BlobMessage msg,
[Blob("{source}-error/{name}", FileAccess.Write)] CloudBlockBlob error,
[Blob("{destination}/{name}", FileAccess.Write)] CloudBlockBlob #out,
[Blob("{source}/{name}", FileAccess.Read)] CloudBlockBlob #in,
ILogger log)
{
await #out.StartCopyAsync(#in);
}
}
However, the storage accounts are going to be different, so the solution above would not work.
Let’s assume you receive a payload input using a HTTP Triggered Azure function:
public class Payload
{
public string SourceContainer { get; set; }
public string DestinationContainer { get; set; }
public string SourceConnection{ get; set; }
public string DestinationConnection{ get; set; }
}
Now receive the information from the request:
var payload = req.Content.ReadAsAsync<Payload>();
var sourceConnection = payload.SourceConnection;
var destConnection = payload.DestinationConnection;
var sourceContainer = payload.SourceContainer;
var destContainer= payload.DestinationContainer;
Create the sourceClient and destinationClient:
#SOURCE
CloudStorageAccount sourceAccount = CloudStorageAccount.Parse(sourceConnection);
CloudBlobClient sourceClient = sourceAccount.CreateCloudBlobClient();
#DEST
CloudStorageAccount destAccount = CloudStorageAccount.Parse(destConnection);
CloudBlobClient destClient = destAccount .CreateCloudBlobClient();
Downloading from source
CloudBlobContainer sourceBlobContainer = sourceClient.GetContainerReference(sourceContainer);
ICloudBlob sourceBlob = await sourceBlobContainer.GetBlobReferenceFromServerAsync("MyBlob.doc");
await sourceBlob.DownloadToFileAsync("MyFile.doc", FileMode.Create);
Uploading to the destination
CloudBlobContainer destBlobContainer = destClient.GetContainerReference(destContainer);
CloudBlockBlob destBlob = destBlobContainer.GetBlockBlobReference("NewBlob.doc");
await destBlob.UploadFromFileAsync("MyFile.doc");
Related
So I'm a bit stuck on this scenario.
I have a frontend sending the following request through Axios to my API:
const objectInBody = {
Id,
Input
};
const result: any = await axios.Post(`Order/Reservation`, JSON.stringify(objectInBody));
return result.data;
And I have a RESTful .NET Core API running that recieves these requests.
Relevant routing logic:
[HttpPost("[action]")]
public async Task<IActionResult> Reservation([FromBody] string jsonObj)
{
Reservation reservation = JsonConvert.DeserializeObject<Reservation>(jsonObj);
try
{
var result = await orderManager.Reserve(reservation);
return Ok(result);
}
catch (Exception e)
{
return BadRequest(e.Message);
}
}
The problem here is, my API blocks the request, because my API doesn't recognize the 'JSON.stringify(objectInBody)' as a string and will not run through the code.
When I pass other strings, the API accepts it without any problem and continues the logic. Which is weird to me because I thought the JSON.stringify results in a string type?
On console.log(JSON.stringify(objectInBody)); I get {Id:1, Input:1} without quotation marks.
But when I console.log(typeof(JSON.stringify(objectInBody))); it does say 'string' in my console.
I can also adjust the "expected" type in my API to JsonObject or something else, but this is a bad 'fix', since it seems to me Json.Stringify has to return a string and pass it without problems, like I said, not a JsonObject ofcourse.
The reason that your current code is not working, is because Axios don't send Content-Type: application/json automatically for string payloads. Hence, to make your current solution working, you'll have to do like this (please follow my recommendation at the end of this answer instead):
const result: any = await axios.post("Order/Reservation", JSON.stringify(objectInBody), {headers: {"Content-Type": "application/json"}});
Recommended solution
You should change your controller method like this:
[HttpPost("[action]")]
public async Task<IActionResult> Reservation([FromBody] Reservation reservation)
{
try
{
var result = await orderManager.Reserve(reservation);
return Ok(result);
}
catch (Exception e)
{
return BadRequest(e.Message);
}
}
Then change your Axios call like this:
const result: any = await axios.post(`Order/Reservation`, objectInBody);
Assuming that Reservation class is like this
public class Reservation
{
public string Id {get; set;}
public string Input {get; set;}
}
Try this code
objectInBody = {
Id:"id",
Input: "input"
};
const result: any = await axios.Post('/Order/Reservation',
{ jsonObj:JSON.stringify(objectInBody)});
I want to pass the url of a webpage containing a <span id="spanID"> value </span> tag to a method like setTextBoxText(string url, string id) which is written in a wpf application codeBehind (MainWindow.xaml.cs) and set the Text of a specific TextBox Control to the span value, without loading the webpage. (for Ex. tracking price of a product in amazon)
I prefer to execute JavaScript code to get value of html elements and set the content of wpf controls to the result of the js code (function)
something like this:
public partial class MainWindow : Window
{
string url = "https://websiteaddress.com/rest";
setTextBoxText(url, "spanID");
static void setTextBoxText(string url, string id)
{
// code to get document by given url
txtPrice.Text = getHtmlElementValue(id);
}
string getHtmlElementValue(string id)
{
// what code should be written here?
// any combination of js and c#?
// var result = document.getElementById(id).textContent;
// return result;
}
}
You can use the HttpClient to load the HTML content of an URL and then process the DOM object in a JavaScript like syntax by wrapping the response into a mshtml.HTMLDocument - requires reference to Microsoft.mshtml.dll:
private mshtml.HTMLDocument HtmlDocument { get; set; }
private async Task SetTextBoxTextAsync(string url, string id)
{
await UpdateHtmlDocumentAsync(url);
var value = GetHtmlElementValueById(id);
txtPrice.Text = value;
}
public async Task UpdateHtmlDocumentAsync(string url)
{
using (HttpClient httpClient = new HttpClient())
{
byte[] response = await httpClient.GetByteArrayAsync(url);
string httpResponseText = Encoding.GetEncoding("utf-8").GetString(response, 0, response.Length - 1);
string htmlContent = WebUtility.HtmlDecode(httpResponseText);
this.HtmlDocument = new HTMLDocument();
(this.HtmlDocument as IHTMLDocument2).write(htmlContent);
}
}
public string GetHtmlElementValueById(string elementId)
=> this.HtmlDocument.getElementById(elementId).innerText;
I've been given a script function and would like to partially translate it to C# in a Blazor app
<script>
function pay() {
var token = document.getElementById('token').value;
var card = document.getElementById('card').value;
var exp = document.getElementById('exp').value;
var cvv = document.getElementById('cvv').value;
var paymentData = {
ssl_txn_auth_token: token,
ssl_card_number: card,
ssl_exp_date: exp ,
ssl_cvv2cvc2: cvv
};
ConvergeEmbeddedPayment.pay(paymentData);
return false;
}
</script>
I want to call the script (that is inside the script above)
ConvergeEmbeddedPayment.pay(paymentData);
Directly from c# . Like so
await JsRuntime.InvokeVoidAsync("ConvergeEmbeddedPayment.pay", paymentData);
There is some good information here:
https://learn.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-3.1
But it stops short of helping me.
What kind of variable should I pass in the paymentData parameter? And how should I pass it?
I've tried var , object and string and also tried JsonSerializer.Serialize( ); but no luck
Based on suggestion from #BurningKarl I tried Dictionary and object[] but
I get an error saying the content is missing or "Expected BEGIN_OBJECT but was STRING "
Looks like you have to create your own c# class that mimics the payment data object in your Javascript.
Something like this
public class PaymentData
{
public string ssl_txn_auth_token {get; set;}
public string ssl_card_number{get; set;}
public string ssl_exp_date{get; set;}
public string ssl_cvv2cvc2{get; set;}
}
Then you have to create an instance of this class and pass it to InvokeVoidAsync as an argument.
var data = new PaymentData ()
{
ssl_txn_auth_token = "authtokenvalue",// you have to get it from control
ssl_card_number = "card number",
ssl_exp_date: "date", // probably it should be daytime or similar
ssl_cvv2cvc2 = "111"
}
await JsRuntime.InvokeVoidAsync("ConvergeEmbeddedPayment.pay", data);
I have an object as follows which is then stored in an array of them.
I would like to send the array of them to Web API, usually you would use JSON.stringify on an object, but would this work also being in an array?
I then need to work out what type of object they would be received as the other end as I need to iterate through them. I was hoping to use a typeof class.
var fieldarray = [];
$("div[class*=container_]").each(function (index) {
var firstElement = $(this).first();
var object = $(this).find('.object');
fielddata = {
id: firstElement.attr('class').match(/\d+/)[0],
attributes: [{
'label_text': firstElement.text(),
'label_width': firstElement.width(),
'label_height': firstElement.height(),
'label_color': firstElement.css('color'),
'Field_Width': object.width(),
'Field_Height': object.height,
'Field_Type': object.attr('Field_Type'),
'PositionX': firstElement.offset().left,
'PositionY': firstElement.offset().top,
'Field': firstElement.attr('class').match(/\d+/)[0],
'Label_Font': firstElement.css('font-family')
}]
}
array.push(fielddata);
});
Can I send this using JSON.stringify, and if so, what type would I receive this as in the Web API server side?
I usually use a public class type but the above code has an object inside an object - that is my problem.
I have sorted this now, basically I used:
[HttpPut]
public int Put(int id, [FromBody] FormData HTMLFORM)
{
....
}
and stored it in my type class as a string:
public class FormData
{
public int id { get; set; }
public string HTML { get; set; }
public string fieldData { get; set; }
}
I then used
IList<AttributeData> findingList = JsonConvert.DeserializeObject<IList<AttributeData>>(HTMLFORM.fieldData);
And it was stored in the list which I can iterate through using my type class of AttributeData!
Thanks
In my chat application project, I am trying to broadcast usernames to all the users whenever a new user is connected to a server. and remove a username whenever the user leaves the server. The below is the code which I have tried by going through tutorials. (please check the file.js file which is not showing the desired output)
Chat.cs (Working) --> Implements "Hub" class of SignalR
public class Chat : Hub
{
/* showing only related content */
static ConcurrentDictionary<string, User> _users = new ConcurrentDictionary<string, User>();
public override Task OnDisconnected()
{
var user = _users[Context.ConnectionId]; //user as ConnectionId
User removedUser; //new class object
_users.TryRemove(Context.ConnectionId, out removedUser);
return Clients.All.leave(user, DateTime.Now.ToString()); //dynamic expression
}
public void Joined()
{
User user = new User(Context.ConnectionId, Clients.Caller.username);
_users.TryAdd(user.ConnectionID, user);
Clients.All.joins(user.ConnectionID, user.Name, DateTime.Now); //dynamic expression
}
}
User.cs (Working)
public class User
{
public User(string ConnID, string Username)
{
Name = Username;
ConnectionID = ConnID;
}
public string Name { get; set; }
public string ConnectionID { get; set; }
}
file.js (not working)
var chatUsername = window.prompt("Enter Username:", ""); //username
var chat = $.connection.chat; //connection
//
chat.client.joins = function (ConnectionId, name, Date) {
ConnectionId = 1; /* given value to just test */
name = chatUsername;
};
chat.client.leave = function (user, date) {
user = ""; //making the string empty so that the disconnected user value will be lost.
};
//Here is the connection which calls the "Joined" function of the server (Chat.cs)
What should I write in file.js functions (joins and leave) so that I will get the desired result as I mentioned above. Before asking here, I have gone through this site which is doing the same but including additional javascript files(knockout.js and json) which I dont want to include.(bcos I am new to jquery).
In order to pass UserNames to the client you can take your dictionary and in your joined server side method you could change the SignalR line to be:
Clients.All.joins(_users.Values); //dynamic expression
Then the client version of joins would be:
chat.client.joins = function (users) {
for(var i = users.length - 1; i >= 0; i--) {
alert("User Name: " + users[i].Name + "\nUser Connection ID: " + users[i].ConnectionID);
}
};
Of course you can handle the user information differently than alerting it, but that's the gist of how to handle the data. Lastly, I'd recommend against passing down the connection ID to everyone because a third party could then easily hijack it.