I am trying to check the replication role of a SQL Azure database using the Azure SDK for .NET.
I used the SqlManagementClient to fetch databases from our subscription but there are no properties indicating the replication role.
I used the following code to fetch databases.
var client = GetSqlManagementClient();
var database = client.Databases
.List("<serverName>")
.First(x => x.Name == "<databaseName>");
Is there another way to get this information that I am missing?
If you means to read secondly location, I think Azure ARM management could help us to do this. I have tried it on my local and get the result as followings:
[Update]
Here is my test code:
public async Task<string> GetToken()
{
AuthenticationResult result = null;
string test;
AuthenticationContext authContext = new AuthenticationContext(adInfo.AuthUrl + adInfo.Telnant);
ClientCredential cc = new ClientCredential(adInfo.ClientId, adInfo.ClientSecret);
try
{
result = await authContext.AcquireTokenAsync(adInfo.Resource,cc);
test = result.AccessToken;
return test;
}
catch (AdalException ex)
{
return ex.Message;
}
}
public async Task GetSQLInfo()
{
string token = await GetToken();
var sqlclient = new SqlManagementClient(new TokenCloudCredentials(adApplication.Subscription, token));
var data = await sqlclient.Databases.GetAsync("jatestgroup", "jaserver", "jasql");
}
Here is my class about adInfo and adApplication:
public class AdInfo
{
[JsonProperty(PropertyName = "clientid")]
public string ClientId { get; set; }
[JsonProperty(PropertyName = "clientsecret")]
public string ClientSecret { get; set; }
[JsonProperty(PropertyName = "returnurl")]
public string ReturnUrl { get; set; }
[JsonProperty(PropertyName = "telnantid")]
public string Telnant { get; set; }
[JsonProperty(PropertyName = "authurl")]
public string AuthUrl { get; set; }
[JsonProperty(PropertyName = "resource")]
public string Resource { get; set; }
}
public class AdApplication
{
[JsonProperty(PropertyName = "ARMTemplate")]
public AdInfo Application { get; set; }
[JsonProperty(PropertyName = "subscription")]
public string Subscription { get; set; }
}
My Json Settings:
{
"ARMTemplate": {
"clientid": "****",
"clientsecret": "****",
"returnurl": "http://localhost:20190",
"telnantid": "****",
"authurl": "https://login.microsoftonline.com/",
"resource": "https://management.core.windows.net/"
},
"subscription": "***"
}
Since this issue is more related with Auth failed. I would suggest you create a new thread and give more info for us if my code does not give you help.
Related
Doing some simple queries using Azure.Data.Table TableClient and the response is not including the ETag.
My entities inherit ITableEntity as required so have the ETag property.
The code is pretty vanilla:
var tableClient = new TableClient(
new Uri(storageUri),
tableName,
new TableSharedKeyCredential(accountName, storageAccountKey));
var response = await tableClient.GetEntityAsync<TEntity>(partitionKey, rowKey);
return response.Value;
The output produced is:
{
"partitionKey": "Partition Key",
"rowKey": "RowKey",
"timestamp": "2023-02-07T20:55:45.6532507+00:00",
"eTag": {},
"forename": "Forename",
"surname": "Surname",
"mobile": "Mobile",
"address": "Address"
}
I'm at a bit of a loss to think what to do as it is all handled within the TableClient so I can't debug all that much.
Any thoughts much appreciated.
UPDATE
I have modified the code to run using the type <TableEntity> and also for the type <User> which is define as:
public class User : ITableEntity, IResult
{
public User() { }
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public ETag ETag { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string Mobile { get; set; }
public string Address { get; set; }
}
The TableClient GetEntityAsync methods are respectivly:
var response = await tableClient.GetEntityAsync<TableEntity>(partitionKey, rowKey);
var response = await tableClient.GetEntityAsync<User>(partitionKey, rowKey);
The first populates all the fields and the ETag correctly and the latter just populates all of the other fields apart from the ETag.
Dont know if this helps shed some light on what I'm doing wrong?
I tried with some piece of code with Microsoft.azure.cosomos.table to get the Etag.
Code:
using Microsoft.Azure.Cosmos.Table;
namespace azuretablestr
{
class program
{
public static void Main()
{
string connectionString = "your connection string";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("table1");
TableOperation retrieveOperation = TableOperation.Retrieve<DynamicTableEntity>("partitionkey2", "rowkey2");
TableResult retrievedResult = table.Execute(retrieveOperation);
DynamicTableEntity entity = (DynamicTableEntity)retrievedResult.Result;
string etag = entity.ETag;
Console.WriteLine("Etag :",etag);
}
}
}
Console:
The above code executed successfully and retrieved Etag successfully.
Reference:
Microsoft.Azure.Cosmos.Table Namespace - Azure for .NET Developers | Microsoft Learn
I have an Azure B2C user flow. It is associated with an API Connector pointing to an Azure Function. The function returns a ResponseContent with extension claims:
public class ResponseContent
{
public const string ApiVersion = "1.0.0";
public ResponseContent()
{
this.version = ResponseContent.ApiVersion;
this.action = "Continue";
}
public ResponseContent(string action, string userMessage)
{
this.version = ResponseContent.ApiVersion;
this.action = action;
this.userMessage = userMessage;
}
public ResponseContent(string userTypes, string accountIdentifiers, string pricebookAuthorized, string portalAuthorized)
{
this.version = ResponseContent.ApiVersion;
this.action = "Continue";
this.extension_UserTypes = userTypes;
this.extension_AccountIdentifiers = accountIdentifiers;
this.extension_PricebookAuthorized = pricebookAuthorized;
this.extension_PortalAuthorized = portalAuthorized;
}
public string version { get; }
public string action { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string userMessage { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string extension_UserTypes { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string extension_AccountIdentifiers { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string extension_PricebookAuthorized { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string extension_PortalAuthorized { get; set; }
}
Here are the claims of the user flow:
When I run this Azure function using Postman, the following is returned:
{
"version": "1.0.0",
"action": "Continue",
"extension_UserTypes": "",
"extension_AccountIdentifiers": "",
"extension_PricebookAuthorized": "",
"extension_PortalAuthorized": ""
}
But when I try to run the user flow on Azure, I get
Microsoft.Identity.Client.MsalServiceException:
AADB2C90261: The claims exchange 'PreSendClaimsRestful' specified in
step '2' returned HTTP error response that could not be parsed.
What might be wrong, and how this can be diagnosed?
Please check if below points can help:
Each key value pair in the JSON is treated as string, string
collection or Boolean.
AADB2C may not deserialise the claim in the JSON you send. One may
need to deserialise the string at the API, or will have to return a
nested JSON object without the escape characters.
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
Reference: dotnet-external-identities-api-connector-azure-function-validate
ยท GitHub
To troubleshoot the unexpected response, try sending Azure AD B2C
logs to Application Insights.
References:
Azure B2C - REST API call Error
Add extra claims to an Azure B2C user flow using API connectors and
ASP.NET Core | (damienbod.com)
how-to-parse-json-in-net-core
I am trying to automate creation of repositories and its initialization using Azure DevOps REST APIs. I am able to successfully create a repo using APIs.
How can we commit a bulk data, say a list of folders and files, that constitute the basic code structure, using REST API? In the request body of Pushes - Create , contentType can either be base64encoded or rawtext. I have used rawtext to test commit of a single file and it worked successfully. Now, I have to commit both files and folders together.
Accually, Rest API is always used to commit the documents related to the project.
If you want to commit all files in folders, you should define the paths of all files in changes. Shayki Abramczyk's comment is really helpful. Note: Git folders cannot be empty.
For example, these two paths will commit folder "content".
"item": {
"path": "/tasks/content/newtasks.md"
}
"item": {
"path": "/tasks/content/inactivetasks.md"
}
Please refer to this similar issue, Rakesh has created a function with C# to push files automatically.
public class Refs
{
public string name { get; set; }
public string objectId { get; set; }
public string oldObjectId { get; set; }
public Creator creator { get; set; }
public string url { get; set; }
}
public class Change
{
public string changeType { get; set; }
public Item item { get; set; }
public Newcontent newContent { get; set; }
}
public class CommitToAdd
{
public string comment { get; set; }
public ChangeToAdd[] changes { get; set; }
}
public class ChangeToAdd
{
public string changeType { get; set; }
public ItemBase item { get; set; }
public Newcontent newContent { get; set; }
}
public class ItemBase
{
public string path { get; set; }
}
public class Newcontent
{
public string content { get; set; }
public string contentType { get; set; }
}
// ### Implementation
//on your Program.cs file
public static class program
{
public async Task AddFileToRepository(string projectName, string repositoryId, Dictionary<string, Task<string>> blobContainer)
{
var refs = new List<Refs>() { new Refs { oldObjectId = "0000000000000000000000000000000000000000", name = Constants.DevOps.MASTER_REPO_REF_NAME } };
var changes = new List<ChangeToAdd>();
foreach (var blob in blobContainer)
{
if (!blob.Key.StartsWith(".git"))
{
ChangeToAdd changeJson = new ChangeToAdd()
{
changeType = "add",
item = new ItemBase() { path = blob.Key },
newContent = new Newcontent()
{
contentType = "rawtext",
content = blob.Value.Result
}
};
changes.Add(changeJson);
}
}
CommitToAdd commit = new CommitToAdd();
commit.comment = "commit from code";
commit.changes = changes.ToArray();
var content = new List<CommitToAdd>() { commit };
var request = new
{
refUpdates = refs,
commits = content
};
var uri = $"https://dev.azure.com/{_orgnizationName}/{projectName}/_apis/git/repositories/{repositoryId}/pushes{Constants.DevOps.API_VERSION}";
using (var client = this.HttpClient)
{
var authorizationToken = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", personalaccessToken)));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authorizationToken);
var requestJson = JsonConvert.SerializeObject(request);
var httpContent = new StringContent(requestJson, Encoding.ASCII, "application/json");
var response = await client.PostAsync(uri, httpContent);
if (!response.IsSuccessStatusCode)
{
throw new Exception(ApplicationMessages.FailedToAddFilesToRepository);
}
}
}
}
I found the following document: CosmosDB grant permission to multiple resources?
The answer there states that after the resource token broker gets the Permissions feed of the user and sends it back to client:
FeedResponse<Permission> permFeed = await client.ReadPermissionFeedAsync(UriFactory.CreateUserUri("dbid", " userId"));
List<Permission> permList = permFeed.ToList();
The client app can then initialize an instance of the DocumentClient class and pass the list (provided that it will deserialize the Json to List<Permission>).
var jsonString = await response.Content.ReadAsStringAsync();
var permissions = JsonConvert.DeserializeObject<List<Permission>>(jsonString);
var client = new DocumentClient(new Uri(EndpointUri), permisions);
The problem that I have is that the Permission class has a Token property that has only a getter and no setter exists. The following source code is from Microsoft.Azure.Documents namespace.
namespace Microsoft.Azure.Documents
{
public class Permission : Resource
{
[JsonProperty(PropertyName = "resource")]
public string ResourceLink { get; set; }
[JsonProperty(PropertyName = "resourcePartitionKey")]
public PartitionKey ResourcePartitionKey { get; set; }
[JsonConverter(typeof (StringEnumConverter))]
[JsonProperty(PropertyName = "permissionMode")]
public PermissionMode PermissionMode { get; set; }
[JsonProperty(PropertyName = "_token")]
public string Token { get; } <------------------------------------- HERE
}
}
As such, trying to serialize the Token field, the value copied is null.
Anyone has any solution for that?
Here is my code used
TODOITEM1.cs
public class TODOITEM1
{
[JsonProperty(PropertyName = "ID")]
public int ID { get; set; }
[JsonProperty(PropertyName = "TEXT")]
public string TEXT { get; set; }
[JsonProperty(PropertyName = "COMPLETE")]
public bool COMPLETE { get; set; }
}
and here is MainPage.Xaml.cs
string DbPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "MTZDATABASE3.db");
private async void Button_Clicked(object sender, EventArgs e)
{
var store = new MobileServiceSQLiteStore("MTZDATABASE3.db");
store.DefineTable<TODOITEM1>();
string URL6 = "https://mtzstorageaccount2.table.core.windows.net/TODOITEM1";
MobileServiceClient client = new MobileServiceClient(URL6);
await client.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler());
IMobileServiceSyncTable<TODOITEM1> todoTable = client.GetSyncTable<TODOITEM1>();
await todoTable.PullAsync("allTODOITEM", todoTable.CreateQuery());
and this is the error that appears Microsoft.WindowsAzure.MobileServices.MobileServiceInvalidOperationException: 'The request could not be completed. (The specified resource does not exist.)
and here is a screenshot of my table enter image description here