This exception is thrown when I need to call the Registry of my project and get all services displayed in client.It worked yesterday but dont know why its not working now.Can anyone help with me with this?
This is my method to get all services to client from the registry api
private void btnGetAll_Click(object sender, RoutedEventArgs e)
{
Services services;
User user = User.Instance;
//Api Call is made.
string url = "http://localhost:14470/api/AllServies/ " + Rtoken;
var clinet = new RestClient(url);
var request = new RestRequest();
var response = clinet.Post(request);
List<Services> data = new List<Services>();
data = JsonConvert.DeserializeObject<List<Services>>(response.Content.ToString());
List<Services> gridData = new List<Services>();
foreach (Services line in data)
{
//services = JsonConvert.DeserializeObject<List<Services>>(line);
/*if (services.Status.Equals("Denied"))
{
logout();
break;
}*/
gridData.Add(line);
}
// Services test = serviceInfo.SelectedItem as Services;
serviceInfo.ItemsSource = gridData;
}
This is the all service controller of my registry api
// POST: api/AllServices
[Route("api/AllServies/{token}")]
[HttpPost]
public IHttpActionResult Post([FromBody] int token)
{
//AuthInterface foob = auth.initServerConnection();
// Ilist return for returning list with multple types
//token validation
string validate = foob.Validate(token);
if (validate.Equals("Not Validated"))
{
//if valid token
// path to the text file
string path = "C:\\Users\\ravin\\Desktop\\assignment_1_DC\\Services.txt";
List<string> services = File.ReadAllLines(path).ToList();
List<Rdetails> regservice = new List<Rdetails>();
//checking for every line
foreach (var service in services)
{
//deserlizing text and assigning values to RegistryDetail type object
Rdetails rDetail = JsonConvert.DeserializeObject<Rdetails>(service);
// add details to the created Registry details type list
regservice.Add(rDetail);
}
return Ok(regservice);
}
else
{
// if token is unvalid
Rresponse reg = new Rresponse();
reg.RegStatus = "Denied";
reg.RegReason = "Authentication Error";
List<Rresponse> output = new List<Rresponse>();
output.Add(reg);
return Ok(output);
}
}
}
}
Related
I have seen various posts about this topic but a lot are old
I have an issue where I need to track the content of a request that is coming from a HttpContextAccessor
At present, I use the extension method below
public static string GetBody(this HttpRequest request)
{
try
{
request.EnableBuffering();
request.Body.Position = 0;
var result = new StreamReader(request.Body).ReadToEndAsync().GetAwaiter().GetResult();
return result;
}
catch
{
return "Body not available";
}
}
What is the correct way to get the content? This doesnt work
Please note that I cant use Async because I call this method in a constructor
public TenantService(IHttpContextAccessor httpContextAccessor,
ILogger<TenantService> logger,
IOptions<AppConfiguration> tenantConfig)
{
_logger = logger;
_httpContextAccessor = httpContextAccessor;
_tenantConfig = tenantConfig.Value.Tenant;
Tenant = new TenantDto();
if (_httpContextAccessor?.HttpContext?.Request != null)
{
SetupTenant($"{this.GetType().Name} - Via HttpContextAccessor");
}
}
public void SetupTenant(string typeName)
{
var requestFullInfo = "No Request Available";
var contextHeaders = HeadersFromContext;
if (contextHeaders != null && contextHeaders.ContainsKey("TenantId"))
{
var tenant = TenantById(contextHeaders.GetGuidValue("TenantId"));
ChangeViaTenant(tenant);
}
else
{
if (ContextRequest.LogNoTenantIdRequired())
{
if (ContextRequest != null)
{
var requestBody = ContextRequest.GetBody();
var requestQueryString = ContextRequest.QueryString.ToString();
var requestPath = ContextRequest.Path.ToString();
var requestHost = ContextRequest.Host.ToString();
requestFullInfo = $"Host: {requestHost}. " +
$"Body: {requestBody}. " +
$"Query string: {requestQueryString}. " +
$"Path: {requestPath}. ";
}
var message = $"No TenantId specified for {typeName} so using PVL. Request Info: {requestFullInfo}";
_logger.LogWarning(message);
}
ChangeViaConfig(TenantCodes.Privalgo);
}
}
}
I am trying to figure out how we are getting requests coming in with no tenant id in the header hence the need for this logging
Cheers
Paul
I have a Problem Updating the Server details in the dataset of the uploaded power bi Report. Please Help.
Here I used 2 approaches.
Approach 1
Used the below method in Microsoft.PowerBI.Api.V2
UpdateDatasourcesInGroup
public static void UpdateSqlDatabaseConnectionString(string WorkspaceId, string DatasetId, string Server, string Database)
{
var tokenCredentials = GetTokenCredentials();
using (var pbiClient = new PowerBIClient(new Uri(ApiUrl), tokenCredentials.Item1))
{
Datasource targetDatasource = pbiClient.Datasets.GetDatasourcesInGroup(WorkspaceId, DatasetId).Value.First();
string currentServer = targetDatasource.ConnectionDetails.Server;
string currentDatabase = targetDatasource.ConnectionDetails.Database;
if (Server.ToLower().Equals(currentServer.ToLower()) && Database.ToLower().Equals(currentDatabase.ToLower()))
{
Console.WriteLine("New server and database name are the same as the old names");
return;
}
DatasourceConnectionDetails connectionDetails = new DatasourceConnectionDetails
{
Database = Database,
Server = Server
};
UpdateDatasourceConnectionRequest updateConnRequest =
new UpdateDatasourceConnectionRequest
{
DatasourceSelector = targetDatasource,
ConnectionDetails = connectionDetails
};
UpdateDatasourcesRequest updateDatasourcesRequest = new UpdateDatasourcesRequest(updateConnRequest);
pbiClient.Datasets.UpdateDatasourcesInGroup(WorkspaceId, DatasetId, updateDatasourcesRequest);
}
}
Captured the request in fiddler
Request:
{
"updateDetails": [
{
"connectionDetails": {
"server": "OldServer",
"database": "OldDatabase"
},
"datasourceSelector": {
"datasourceType": "Sql",
"connectionDetails": {
"server": "NewServer",
"database": "NewDatabase"
},
"gatewayId": "gatewayId",
"datasourceId": "datasourceId"
}
}
]
}
Response:
{"error":{"code":"InvalidRequest","message":"Operation is not supported for selector # - connection details contains parameters"}}
Approach 2
Called the Power BI rest API
public static void UpdateServerName_RestAPI(string groupId, string datasetId)
{
var tokenCredentials = InitPowerBI_New();
HttpResponseMessage response;
try
{
var httpClient = new HttpClient();
// Add AccessToken in header
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenCredentials.Item2);
var url = $"https://api.powerbi.com/v1.0/myorg/groups/{groupId}/datasets/{datasetId}/Default.UpdateDatasources";
var form = prepareJsonForUpdateServerDetails();
var content = new StringContent(form, Encoding.UTF8, "application/json");
response = httpClient.PostAsync(url, content).Result;
response.EnsureSuccessStatusCode();
httpClient.Dispose();
}
catch (Exception)
{
}
}
Request :
{
"UpdateDetails":[
{
"datasourceSelector":{
"datasourceType":"Sql",
"connectionDetails":{
"server":"OldServer",
"database":"OldDatabase"
}
},
"connectionDetails":{
"server":"NewServer",
"database":"NewDatabase"
}
}
]
}
Response:
{"error":{"code":"InvalidRequest","message":"Operation is not supported for selector # - connection details contains parameters"}}
Please Help.
Thank You
This happens when the report queries connect to a database using a parameter. In this case you cannot update the connection, rather update the parameters or remove the connection from the query.
So, if you see in your query code something like Sql.Database(#"ServerName",... you must use Client.Datasets.UpdateParameters and pass in for details:
UpdateMashupParameterDetails request = new()
{
Name = "ServerName",
NewValue = "newServerName"
};
and similarly for database.
Further details https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/update-parameters
I am trying to implement a code to modify entities through WCF Dataservices from the OData client I have generated. I have followed the same principle that was implemented in this link - https://msdn.microsoft.com/en-us/library/dd756368(v=vs.110).aspx
I am getting "CSRF token validation failed" error during the SaveChanges method call. Please see code below:
// Define the URI of the public Northwind OData service.
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Uri cuanUri =
new Uri("https://xxxx.xxxx.com:44300/sap/opu/odata/sap/CUAN_IMPORT_SRV/",
UriKind.Absolute);
// Create a new instance of the typed DataServiceContext.
DateTime stimestamp = new DateTime();
DateTime dob = new DateTime(1992,05,02);
CUAN_IMPORT_SRV_Entities context = new CUAN_IMPORT_SRV_Entities(cuanUri);
context.SendingRequest2 += SendBaseAuthCredsOnTheRequest;
Contact newContact = Contact.CreateContact("C160717055735", "SAP_ODATA_IMPORT", stimestamp);
//Product newProduct = Product.CreateProduct(0, "White Tea - loose", false);
newContact.CompanyId = "BLUEFIN1";
newContact.CompanyIdOrigin = "SAP_ODATA_IMPORT";
newContact.CountryDescription = "Singapore";
newContact.DateOfBirth = dob;
newContact.EMailAddress = "j_prado#yahoo.com";
newContact.EMailOptIn = "Y";
newContact.FirstName = "Jeffrey1";
newContact.FunctionDescription = "Consultant";
newContact.GenderDescription = "Male";
newContact.LastName = "Prado1";
newContact.PhoneNumber = "+6596492714";
newContact.PhoneOptin = "Y";
Company newCompany = Company.CreateCompany("BLUEFIN1", "SAP_ODATA_IMPORT", stimestamp);
newCompany.IndustryDescription = "1007";
newCompany.CompanyName = "BLUEFIN1";
Interaction newInteraction = Interaction.CreateInteraction("");
newInteraction.CommunicationMedium = "WEB";
newInteraction.ContactId = "C160717055735";
newInteraction.ContactIdOrigin = "SAP_ODATA_IMPORT";
newInteraction.InteractionType = "WEBSITE_REGISTRATION";
newInteraction.Timestamp = stimestamp;
ImportHeader newHeader = ImportHeader.CreateImportHeader("");
newHeader.Timestamp = stimestamp;
newHeader.UserName = "ENG";
newHeader.SourceSystemType = "EXT";
newHeader.SourceSystemId = "HYBRIS";
try
{
// Add the new entities to the CUAN entity sets.
context.AddToImportHeaders(newHeader);
context.AddToContacts(newContact);
context.AddToCompanies(newCompany);
context.AddToInteractions(newInteraction);
// Send the insert to the data service.
DataServiceResponse response = context.SaveChanges();
// Enumerate the returned responses.
foreach (ChangeOperationResponse change in response)
{
// Get the descriptor for the entity.
EntityDescriptor descriptor = change.Descriptor as EntityDescriptor;
if (descriptor != null)
{
Contact addedContact = descriptor.Entity as Contact;
if (addedContact != null)
{
Console.WriteLine("New contact added with ID {0}.",
addedContact.CompanyId);
}
}
}
}
catch (DataServiceRequestException ex)
{
throw new ApplicationException(
"An error occurred when saving changes.", ex);
}
}
private static void SendBaseAuthCredsOnTheRequest(object sender,
SendingRequest2EventArgs e)
{
var authHeaderValue = Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}"
, "XXXXX", "XXXXX")));
e.RequestMessage.SetHeader("Authorization", "Basic " + authHeaderValue); //this is where you pass the creds.
}
The code above fails when invoking: DataServiceResponse response = context.SaveChanges();
I'm writing a program to allow a user to upload files to their Google Drive account. I have the upload part working and am using OAuth2. The issue I'm currently having is getting a list of folders from the users Drive account.
I found some code that is supposed to do this using the .setUserCredentials method, but it doesn't work:
DocumentsService service1 = new DocumentsService("project");
service1.setUserCredentials("user","pass");
FolderQuery query1 = new FolderQuery();
// Make a request to the API and get all documents.
DocumentsFeed feed = service1.Query(query1);
// Iterate through all of the documents returned
foreach (DocumentEntry entry in feed.Entries)
{
var blech = entry.Title.Text;
}
Nothing is returned. Ideally, I want to use OAuth2 to do this. I've been trying with the following code, trying to set the authentication token, but I always get denied access:
String CLIENT_ID = "clientid";
String CLIENT_SECRET = "secretid";
var docprovider = new NativeApplicationClient(GoogleAuthenticationServer.Description, CLIENT_ID, CLIENT_SECRET);
var docstate = GetDocAuthentication(docprovider);
DocumentsService service1 = new DocumentsService("project");
service1.SetAuthenticationToken(docstate.RefreshToken);
FolderQuery query1 = new FolderQuery();
DocumentsFeed feed = service1.Query(query1); //get error here
// Iterate through all of the documents returned
foreach (DocumentEntry entry in feed.Entries)
{
// Print the title of this document to the screen
var blech = entry.Title.Text;
}
..
private static IAuthorizationState GetDocAuthentication(NativeApplicationClient client)
{
const string STORAGE = "storagestring";
const string KEY = "keystring";
string scope = "https://docs.google.com/feeds/default/private/full/-/folder";
// Check if there is a cached refresh token available.
IAuthorizationState state = AuthorizationMgr.GetCachedRefreshToken(STORAGE, KEY);
if (state != null)
{
try
{
client.RefreshToken(state);
return state; // Yes - we are done.
}
catch (DotNetOpenAuth.Messaging.ProtocolException ex)
{
}
}
// Retrieve the authorization from the user.
state = AuthorizationMgr.RequestNativeAuthorization(client, scope);
AuthorizationMgr.SetCachedRefreshToken(STORAGE, KEY, state);
return state;
}
Specifically, I get "Execution of request failed: https://docs.google.com/feeds/default/private/full/-/folder - The remote server returned an error: (401) Unauthorized".
I've also tried:
var docauth = new OAuth2Authenticator<NativeApplicationClient>(docprovider, GetDocAuthentication);
DocumentsService service1 = new DocumentsService("project");
service1.SetAuthenticationToken(docauth.State.AccessToken);
but "State" is always null, so I get a null object error. What am I doing wrong and how is this done?
You should use the Drive SDK, not the Documents List API, which allows you to list folders. You can use "root" as a folderId if you want to list the root directory.
I actually implemented the v3 version of the GDrive SDK for .NET and needed to search for folders as well.
I prefer requesting uniquely all folders instead of getting all files and then performing a LinQ query to keep just the folders.
This is my implementation:
private async Task<bool> FolderExistsAsync(string folderName)
{
var response = await GetAllFoldersAsync();
return response.Files
.Where(x => x.Name.ToLower() == folderName.ToLower())
.Any();
}
private async Task<Google.Apis.Drive.v3.Data.FileList> GetAllFoldersAsync()
{
var request = _service.Files.List();
request.Q = "mimeType = 'application/vnd.google-apps.folder'";
var response = await request.ExecuteAsync();
return response;
}
You could request the name on the Q this way as well:
request.Q = $"mimeType = 'application/vnd.google-apps.folder' and name = '{folderName}'";
Which would lead and simplify things to (obviating null checking):
private async Task<bool> FolderExistsAsync(string folderName)
{
var response = await GetDesiredFolder(folderName);
return response.Files.Any();
}
private async Task<FileList> GetDesiredFolder(string folderName)
{
var request = _service.Files.List();
request.Q = $"mimeType = 'application/vnd.google-apps.folder' and name = '{folderName}'";
var response = await request.ExecuteAsync();
return response;
}
private IEnumerable<DocumentEntry> GetFolders(string id) {
if (IsLogged) {
var query = new FolderQuery(id)
{
ShowFolders = true
};
var feed = GoogleDocumentsService.Query(query);
return feed.Entries.Cast<DocumentEntry>().Where(x => x.IsFolder).OrderBy(x => x.Title.Text);
}
return null;
}
...
var rootFolders = GetFolders("root");
if (rootFolders != null){
foreach(var folder in rootFolders){
var subFolders = GetFolders(folder.ResourceId);
...
}
}
where GoogleDocumentsService is a instance of DocumentsService and IsLogged is a success logged flag.
I got this way to get list of folders from google drive
FilesResource.ListRequest filelist= service.Files.List();
filelist.Execute().Items.ToList().Where(x => x.MimeType == "application/vnd.google-apps.folder").ToList()
Working Platform: ASP.NET 4.0 C# ( Framework Agnostic )
Google GData is my dependency
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Documents;
I have two pages Auth and List.
Auth redirects to Google Server like this
public ActionResult Auth()
{
var target = Request.Url.ToString().ToLowerInvariant().Replace("auth", "list");
var scope = "https://docs.google.com/feeds/";
bool secure = false, session = true;
var authSubUrl = AuthSubUtil.getRequestUrl(target, scope, secure, session);
return new RedirectResult(authSubUrl);
}
Now it reaches the List Page if Authentication is successful.
public ActionResult List()
{
if (Request.QueryString["token"] != null)
{
String singleUseToken = Request.QueryString["token"];
string consumerKey = "www.blahblah.net";
string consumerSecret = "my_key";
string sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, null).ToString();
var authFactory = new GOAuthRequestFactory("writely", "qwd-asd-01");
authFactory.Token = sessionToken;
authFactory.ConsumerKey = consumerKey;
authFactory.ConsumerSecret = consumerSecret;
//authFactory.TokenSecret = "";
try
{
var service = new DocumentsService(authFactory.ApplicationName) { RequestFactory = authFactory };
var query = new DocumentsListQuery();
query.Title = "project";
var feed = service.Query(query);
var result = feed.Entries.ToList().ConvertAll(a => a.Title.Text);
return View(result);
}
catch (GDataRequestException gdre)
{
throw;
}
}
}
This fails at the line var feed = service.Query(query); with the error
Execution of request failed: https://docs.google.com/feeds/default/private/full?title=project
The HttpStatusCode recieved on the catch block is HttpStatusCode.Unauthorized
What is wrong with this code? Do I need to get TokenSecret? If so how?
You need to request a token from Google and use it to intialize your DocumentsService instance.
Here's an example using Google's ContactsService. It should be the same for the DocumentsService.
Service service = new ContactsService("My Contacts Application");
service.setUserCredentials("your_email_address_here#gmail.com", "yourpassword");
var token = service.QueryClientLoginToken();
service.SetAuthenticationToken(token);
But as you mentioned, you are using AuthSub. I jumped the gun a bit too fast.
I see that you are requesting a session token. According to the documentation of the API you must use the session token to authenticate requests to the service by placing the token in the Authorization header. After you've set the session token, you can use the Google Data APIs client library.
Here's a complete example (by Google) on how to use AuthSub with the .NET client library:
http://code.google.com/intl/nl-NL/apis/gdata/articles/authsub_dotnet.html
Let me include a shortened example:
GAuthSubRequestFactory authFactory =
new GAuthSubRequestFactory("cl", "TesterApp");
authFactory.Token = (String) Session["token"];
CalendarService service = new CalendarService(authFactory.ApplicationName);
service.RequestFactory = authFactory;
EventQuery query = new EventQuery();
query.Uri = new Uri("http://www.google.com/calendar/feeds/default/private/full");
EventFeed calFeed = service.Query(query);
foreach (Google.GData.Calendar.EventEntry entry in calFeed.Entries)
{
//...
}
And if I see correctly your example code pretty follows the same steps, except that you set the ConsumerKey and ConsumerSecret for the AuthFactory which is not done in the example by Google.
Used the 3-legged OAuth in the Google Data Protocol Client Libraries
Sample Code
string CONSUMER_KEY = "www.bherila.net";
string CONSUMER_SECRET = "RpKF7ykWt8C6At74TR4_wyIb";
string APPLICATION_NAME = "bwh-wssearch-01";
string SCOPE = "https://docs.google.com/feeds/";
public ActionResult Auth()
{
string callbackURL = String.Format("{0}{1}", Request.Url.ToString(), "List");
OAuthParameters parameters = new OAuthParameters()
{
ConsumerKey = CONSUMER_KEY,
ConsumerSecret = CONSUMER_SECRET,
Scope = SCOPE,
Callback = callbackURL,
SignatureMethod = "HMAC-SHA1"
};
OAuthUtil.GetUnauthorizedRequestToken(parameters);
string authorizationUrl = OAuthUtil.CreateUserAuthorizationUrl(parameters);
Session["parameters"] = parameters;
ViewBag.AuthUrl = authorizationUrl;
return View();
}
public ActionResult List()
{
if (Session["parameters"] != null)
{
OAuthParameters parameters = Session["parameters"] as OAuthParameters;
OAuthUtil.UpdateOAuthParametersFromCallback(Request.Url.Query, parameters);
try
{
OAuthUtil.GetAccessToken(parameters);
GOAuthRequestFactory authFactory = new GOAuthRequestFactory("writely", APPLICATION_NAME, parameters);
var service = new DocumentsService(authFactory.ApplicationName);
service.RequestFactory = authFactory;
var query = new DocumentsListQuery();
//query.Title = "recipe";
var feed = service.Query(query);
var docs = new List<string>();
foreach (DocumentEntry entry in feed.Entries)
{
docs.Add(entry.Title.Text);
}
//var result = feed.Entries.ToList().ConvertAll(a => a.Title.Text);
return View(docs);
}
catch (GDataRequestException gdre)
{
HttpWebResponse response = (HttpWebResponse)gdre.Response;
//bad auth token, clear session and refresh the page
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
Session.Clear();
Response.Write(gdre.Message);
}
else
{
Response.Write("Error processing request: " + gdre.ToString());
}
throw;
}
}
else
{
return RedirectToAction("Index");
}
}
This 2-legged sample never worked for me for google docs.