Azure Reporting Service - rsAuthenticationExtensionError - azure

I have an Azure Reporting Services instance I want to connect to via the Report Execution Web Service. I have referenced this article to connect. However, I am receiving an error...
The URL of the service is:
i593ehr-i.reporting.windows.net
I connected to:
i593ehr-i.reporting.windows.net/ReportServer/ReportExecution2005.asmx
and downloaded the WSDL file. It should be noted that the documentation used ReportExecution2010.asmx, but that didn't direct to a WSDL file... I used the command supplied in the file to generate a proxy class. I then used this code to connect:
var service = new ReportExecutionService();
service.CookieContainer = new CookieContainer();
service.Credentials = new NetworkCredential("report", "******", "i593ehr-i.reporting.windows.net");
service.LoadReport2(reportPath, null);
string extension;
string mimeType;
string encoding;
Warning[] warnings;
string[] streamIds;
var reportData = service.Render("PDF", null, out extension, out mimeType, out encoding, out warnings, out streamIds);
File.WriteAllBytes(outputFile, reportData);
and it's returning the message:
The Authentication Extension threw an unexpected exception or returned a value that is not valid: identity==null. (rsAuthenticationExtensionError)
What am I doing wrong?

It turns out that I needed to use the LogonUser method instead of NetworkCredentials, which the documentation specified but I must have overlooked... The code should be:
service.LogonUser("report", "******", "i593ehr-i.reporting.windows.net");

Related

How to download an Excel file that has been opened by Google Sheets?

I've been running into issues when downloading Excel .xlsx files using Google Drive Api v3. The code I'm using is as follows (I'm using the .NET SDK):
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace DriveQuickstart
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/drive-dotnet-quickstart.json
static string[] Scopes = { DriveService.Scope.Drive };
static string ApplicationName = "Drive API .NET Quickstart";
const string FileId = "my_file_id"; //put the ID of the Excel file you want to download here
public static void Main(string[] args)
{
Run().GetAwaiter().GetResult();
Console.Read();
}
private static async Task Run()
{
UserCredential credential;
using (var stream =
new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
// The file token.json stores the user's access and refresh tokens, and is created
// automatically when the authorization flow completes for the first time.
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Drive API service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
FilesResource.GetRequest getRequest = service.Files.Get(FileId);
using (var stream = new System.IO.FileStream("anExcelFile.xlsx", System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite))
{
var downloadProgress = await getRequest.DownloadAsync(stream, CancellationToken.None);
if (downloadProgress.Exception != null)
{
Console.WriteLine(string.Format("We got error {0} {1} {2}", downloadProgress.Exception.Message, Environment.NewLine, downloadProgress.Exception.StackTrace));
}
else
{
Console.WriteLine("Download ok");
}
}
}
}
}
You can run this sample easily by following the steps described here. This works fine, however, as soon as someone opens the file with Google Sheets and modifies it, I start seeing the following error
D2020-03-16 02:10:13.647293 Response[00000007] Response status: InternalServerError 'Internal Server Error'
D2020-03-16 02:10:13.653278 Response[00000007] An abnormal response wasn't handled. Status code is InternalServerError
D2020-03-16 02:10:13.660288 Response[00000007] Abnormal response is being returned. Status Code is InternalServerError
E2020-03-16 02:10:13.667240 Exception occurred while downloading media The service drive has thrown an exception: Google.GoogleApiException: Internal Server Error
at Google.Apis.Download.MediaDownloader.<DownloadCoreAsync>d__31.MoveNext()
Looking at the file info after it was open with Google sheets, I can see that its size is changed to 0, so I tried to export it as you would for a Google spreadsheet, like so:
FilesResource.ExportRequest exportRequest = client.Files.Export(fileId, mimeType);
using (var stream = new System.IO.FileStream(fileName, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite))
{
await exportRequest.DownloadAsync(stream, cancellationToken);
}
With mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
However, I then run in the following error:
D2020-03-16 01:53:13.512928 Response[00000003] Response status: Forbidden 'Forbidden'
D2020-03-16 01:53:13.520906 Response[00000003] An abnormal response wasn't handled. Status code is Forbidden
D2020-03-16 01:53:13.525911 Response[00000003] Abnormal response is being returned. Status Code is Forbidden
E2020-03-16 01:53:13.538857 Exception occurred while downloading media The service drive has thrown an exception: Google.GoogleApiException: Google.Apis.Requests.RequestError
Export only supports Google Docs. [403]
Errors [
Message[Export only supports Google Docs.] Location[ - ] Reason[fileNotExportable] Domain[global]
]
at Google.Apis.Download.MediaDownloader.<DownloadCoreAsync>d__31.MoveNext()
So it seems that neither downloading nor exporting is working in this particular case. Anything else I should be trying ? Using the webContentLink (https://drive.google.com/uc?id=fileId&export=download) works fine (in a browser that is) so I guess it should be possible to download the file.
I raised the issue to Google and it seems it was fixed (cf this issue). I tried again today and following the steps described in the original question, I now can see that after the Excel file has been edited with Google sheets, its size is now greater than 0 and it can be downloaded.
Files that couldn't be downloaded because of this issue still appear to have the same problem but deleting/reuploading manually these files should make them downloadable.

The remote server returned an error: (405) The resource doesn't support specified Http Verb

I want to update json file in Blob Storage on Azure, while WebClient.uploadData(url,data) it gives the error:
The remote server returned an error: (405) The resource doesn't support specified Http Verb..
The code something like this:
[Route("PostJsonData")]
[HttpPost]
public void PostJSONData(string value)
{
try
{
string url = #"https://apkupdates.blob.core.windows.net/polaadapk/keywords.json";
byte[] json1 = new WebClient().DownloadData(url);
string result = System.Text.Encoding.UTF8.GetString(json1);
byte[] array = System.Text.Encoding.ASCII.GetBytes(value);
WebClient myWebClient = new WebClient();
Stream postStream = myWebClient.OpenWrite(url, "POST");
postStream.Write(array, 0, array.Length);
myWebClient.UploadData(url, array);
postStream.Close();
}
catch (Exception ex)
{
throw ex;
}
}
As Gaurav already mentioned, you are using the wrong verb. However, I would highly recommend to use the existing SDK for .NET:
Azure Storage APIs for .NET
The SDK also implements a exponential retry policy to handly transient errors (503 - Service Unavailble) which you otherwise have to implement yourself.
The correct HTTP verb for uploading is a blob is PUT and not POST. Because you're using POST instead of a PUT you're getting this error.
Please change the following line of code:
Stream postStream = myWebClient.OpenWrite(url, "POST");
to
Stream postStream = myWebClient.OpenWrite(url, "PUT");
And you should not get this MethodNotAllowed (405) error. Please note that you may get 403 error because the request is not authenticated. I would recommend reading Storage Service REST API documentation before proceeding.

Swagger generated API for the Microsoft Cognative Services Recommendations

I can't seem to figure out how to include the CSV file content when calling the Swagger API generated methods for the Microsoft Cognitive Services Recommendations API method Uploadacatalogfiletoamodel(modelID, catalogDisplayName, accountKey);. I've tried setting the catalogDisplayName to the full path to the catalog file, however I'm getting "(EXT-0108) Passed argument is invalid."
When calling any of the Cog Svcs APIs that require HTTP body content, how do I include the body content when the exposed API doesn't have a parameter for the body?
I guess, Swagger can't help you testing functions that need to pass data thru a form. And I guess sending the CSV content in the form data shall do the trick, if you know the proper headers.
I work with nuGet called "Microsoft.Net.Http" and code looks like
HttpContent stringContent = new StringContent(someStringYouWannaSend);
HttpContent bytesContent = new ByteArrayContent(someBytesYouWannaSend);
using (var client = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
formData.Add(stringContent, "metadata", "metadata");
formData.Add(bytesContent, "bytes", "bytes");
HttpResponseMessage response = client.PostAsync(someWebApiEndPoint.ToString(), formData).Result;
if (!response.IsSuccessStatusCode)
{
return false; //LOG
}
string responseContent = response.Content.ReadAsStringAsync().Result;
jsonResult= JsonConvert.DeserializeObject<someCoolClass>(responseContent);
return true;
}
Sorry about that someVariables that can't compile. Hope you'll figure this out.
When you are basing your code on the Swagger definition you depend on the good will of the person that created that Swagger definition. Maybe it is not complete yet.
If you are working on C#, try looking at the Samples repo.
Particularly for the Uploading of the catalog there are several functions on the ApiWrapper class that might be helpful, one has this signature: public CatalogImportStats UploadCatalog(string modelId, string catalogFilePath, string catalogDisplayName), another has this other signature public UsageImportStats UploadUsage(string modelId, string usageFilePath, string usageDisplayName) (where it seems like you can point to a public url).
In your case I'd probably try the second one.
Download the sample and use the Wrapper code defined there in your project.

Create and Update Named Caches in Azure Managed Cache using Management API

I am attempting to create an Azure Managed Cache using PowerShell and the Azure Management API, this two pronged approach is required because the Offical Azure PowerShell Cmdlets only have very limited support for Creation and Update of Azure Managed Cache. There is however an established pattern for calling the Azure Management API from PowerShell.
My attempts at finding the correct API to call have been somewhat hampered by limited documentation on the Azure Managed Cache API. However after working my way through the cmdlets using both the source code and the -Debug option in PowerShell I have been able to find what appear to be the correct API endpoints, as such I have developed some code to access these endpoints.
However, I have become stuck after the PUT request has been accepted to the Azure API as subsequent calls to the Management API /operations endpoint show that the result of this Operation was Internal Server Error.
I have been using Joseph Alabarhari's LinqPad to explore the API as it allows me to rapidly itterate on a solution using the minimum possible code, so to execute the following code snippets you will need both LinqPad and the following extension in your My Extensions script:
public static X509Certificate2 GetCertificate(this StoreLocation storeLocation, string thumbprint) {
var certificateStore = new X509Store(StoreName.My, storeLocation);
certificateStore.Open(OpenFlags.ReadOnly);
var certificates = certificateStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
return certificates[0];
}
The complete source code including the includes are available below:
My Extensions - you can replace an "My Extensions" by right clicking My Extensions in the bottom left hand pane and choosing "Open Script Location in Windows Explorer" then replacing the highlighted file with this one. Alternatively you may wish to merge my extensions into your own.
Azure Managed Cache Script - you should simply be able to download and double click this, once open and the above extensions and certificates are in place you will be able to execute the script.
The following settings are used throughout the script, the following variables will need to it for anyone who is following along using their own Azure Subscription ID and Management Certificate:
var cacheName = "amc551aee";
var subscriptionId = "{{YOUR_SUBSCRIPTION_ID}}";
var certThumbprint = "{{YOUR_MANAGEMENT_CERTIFICATE_THUMBPRINT}}";
var endpoint = "management.core.windows.net";
var putPayloadXml = #"{{PATH_TO_PUT_PAYLOAD}}\cloudService.xml"
First I have done some setup on the HttpClient:
var handler = new WebRequestHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ClientCertificates.Add(StoreLocation.CurrentUser.GetCertificate(certThumbprint));
var client = new HttpClient(handler);
client.DefaultRequestHeaders.Add("x-ms-version", "2012-08-01");
This configures HttpClient to both use a Client Certificate and the x-ms-version header, the first call to the API fetches the existing CloudService that contains the Azure Managed Cache. Please note this is using an otherwise empty Azure Subscription.
var getResult = client.GetAsync("https://" + endpoint + "/" + subscriptionId + "/CloudServices");
getResult.Result.Dump("GET " + getResult.Result.RequestMessage.RequestUri);
This request is successful as it returns StatusCode: 200, ReasonPhrase: 'OK', I then parse some key information out of the request: the CloudService Name, the Cache Name and the Cache ETag:
var cacheDataReader = new XmlTextReader(getResult.Result.Content.ReadAsStreamAsync().Result);
var cacheData = XDocument.Load(cacheDataReader);
var ns = cacheData.Root.GetDefaultNamespace();
var nsManager = new XmlNamespaceManager(cacheDataReader.NameTable);
nsManager.AddNamespace("wa", "http://schemas.microsoft.com/windowsazure");
var cloudServices = cacheData.Root.Elements(ns + "CloudService");
var serviceName = String.Empty;
var ETag = String.Empty;
foreach (var cloudService in cloudServices) {
if (cloudService.XPathSelectElements("//wa:CloudService/wa:Resources/wa:Resource/wa:Name", nsManager).Select(x => x.Value).Contains(cacheName)) {
serviceName = cloudService.XPathSelectElement("//wa:CloudService/wa:Name", nsManager).Value;
ETag = cloudService.XPathSelectElement("//wa:CloudService/wa:Resources/wa:Resource/wa:ETag", nsManager).Value;
}
}
I have pre-created a XML file that contains the payload of the following PUT request:
<Resource xmlns="http://schemas.microsoft.com/windowsazure">
<IntrinsicSettings>
<CacheServiceInput xmlns="">
<SkuType>Standard</SkuType>
<Location>North Europe</Location>
<SkuCount>1</SkuCount>
<ServiceVersion>1.3.0</ServiceVersion>
<ObjectSizeInBytes>1024</ObjectSizeInBytes>
<NamedCaches>
<NamedCache>
<CacheName>default</CacheName>
<NotificationsEnabled>false</NotificationsEnabled>
<HighAvailabilityEnabled>false</HighAvailabilityEnabled>
<EvictionPolicy>LeastRecentlyUsed</EvictionPolicy>
</NamedCache>
<NamedCache>
<CacheName>richard</CacheName>
<NotificationsEnabled>true</NotificationsEnabled>
<HighAvailabilityEnabled>true</HighAvailabilityEnabled>
<EvictionPolicy>LeastRecentlyUsed</EvictionPolicy>
</NamedCache>
</NamedCaches>
</CacheServiceInput>
</IntrinsicSettings>
</Resource>
I construcuct a HttpRequestMessage with the above Payload and a URL comprised of the CloudService and Cache Names:
var resourceUrl = "https://" + endpoint + "/" + subscriptionId + "/cloudservices/" + serviceName + "/resources/cacheservice/Caching/" + cacheName;
var data = File.ReadAllText(putPayloadXml);
XDocument.Parse(data).Dump("Payload");
var message = new HttpRequestMessage(HttpMethod.Put, resourceUrl);
message.Headers.TryAddWithoutValidation("If-Match", ETag);
message.Content = new StringContent(data, Encoding.UTF8, "application/xml");
var putResult = client.SendAsync(message);
putResult.Result.Dump("PUT " + putResult.Result.RequestMessage.RequestUri);
putResult.Result.Content.ReadAsStringAsync().Result.Dump("Content " + putResult.Result.RequestMessage.RequestUri);
This request is nominally accepted by the Azure Service Management API as it returns a StatusCode: 202, ReasonPhrase: 'Accepted' response; this essentially means that the payload has been accepted and will be processed offline, the Operation ID can be parsed out of the HTTP Header to retreve further information:
var requestId = putResult.Result.Headers.GetValues("x-ms-request-id").FirstOrDefault();
This requestId can be used to request an update upon the status of the operation:
var operation = client.GetAsync("https://" + endpoint + "/" + subscriptionId + "/operations/" + requestId);
operation.Result.Dump(requestId);
XDocument.Load(operation.Result.Content.ReadAsStreamAsync().Result).Dump("Operation " + requestId);
The request to the /operations endpoint results in the following payload:
<Operation xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ID>5364614d-4d82-0f14-be41-175b3b85b480</ID>
<Status>Failed</Status>
<HttpStatusCode>500</HttpStatusCode>
<Error>
<Code>InternalError</Code>
<Message>The server encountered an internal error. Please retry the request.</Message>
</Error>
</Operation>
And this is where I am stuck, the chances are I am subtly malforming the request in such a way that the underlying request is throwing a 500 Internal Server Error, however without a more detailed error message or API documentation I don't think there is anywhere I can go with this.
We worked with Richard offline and the following XML payload got him un-blocked.
Note - When adding/removing named cache to an existing cache, the object size is fixed.
Note 2- The Azure Managed Cache API is sensitive to whitespace between the element and the element.
Also please note, we are working on adding Named cache capability to our PowerShell itself, so folks don't have to use APIs to do so.
<Resource xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<IntrinsicSettings><CacheServiceInput xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SkuType>Standard</SkuType>
<Location>North Europe</Location>
<SkuCount>1</SkuCount>
<ServiceVersion>1.3.0</ServiceVersion>
<ObjectSizeInBytes>1024</ObjectSizeInBytes>
<NamedCaches>
<NamedCache>
<CacheName>default</CacheName>
<NotificationsEnabled>false</NotificationsEnabled>
<HighAvailabilityEnabled>false</HighAvailabilityEnabled>
<EvictionPolicy>LeastRecentlyUsed</EvictionPolicy>
<ExpirationSettings>
<TimeToLiveInMinutes>10</TimeToLiveInMinutes>
<Type>Absolute</Type>
</ExpirationSettings>
</NamedCache>
<NamedCache>
<CacheName>richard</CacheName>
<NotificationsEnabled>false</NotificationsEnabled>
<HighAvailabilityEnabled>false</HighAvailabilityEnabled>
<EvictionPolicy>LeastRecentlyUsed</EvictionPolicy>
<ExpirationSettings>
<TimeToLiveInMinutes>10</TimeToLiveInMinutes>
<Type>Absolute</Type>
</ExpirationSettings>
</NamedCache>
</NamedCaches>
</CacheServiceInput>
</IntrinsicSettings>
</Resource>

File uploading from web application to Sharepoint server

This is my first time ever with Sharepoint. Here is the scenario
I have a stand alone web application
I also have a stand alone sharepoint server.
Both are on different servers.
I need to upload a file from web application to sharepoint
I found 2 methods online,
Using the webservice provided by Sharepoint (CopyIntoItems)
Using jQuery library of Sharepoint webservice
After searching the web, I think the jQuery part will not work (you can correct me).
I am looking for a method that takes username/password and uploads a pdf file to Sharepoint server. The following is my C# code that tries to upload but ends up in error
public bool UploadFile(string file, string destination)
{
bool success = false;
CopySoapClient client = new CopySoapClient();
if (client.ClientCredentials != null)
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
try
{
client.Open();
string filename = Path.GetFileName(file);
string destinationUrl = destination + filename;
string[] destinationUrls = { destinationUrl };
FieldInformation i1 = new FieldInformation { DisplayName = "Title", InternalName = "Title", Type = FieldType.Text, Value = filename };
FieldInformation[] info = { i1 };
CopyResult[] result;
byte[] data = File.ReadAllBytes(file);
//uint ret = client.CopyIntoItems(filename, destinationUrls, info, data, out result);
uint ret = client.CopyIntoItems(file, destinationUrls, info, data, out result);
if (result != null && result.Length > 0 && result[0].ErrorCode == 0)
success = true;
}
finally
{
if (client.State == System.ServiceModel.CommunicationState.Faulted)
client.Abort();
if (client.State != System.ServiceModel.CommunicationState.Closed)
client.Close();
}
return success;
}
I am calling the above function like this
UploadFile(#"C:\temp\uploadFile.txt", "http://spf-03:300/demo/Dokumente").ToString();
Error that i get:
Error Code: Destination Invalid
Error Message: The service method 'Copy' must be called on the same domain that contains the target URL.
There is the 3rd option with SharePoint 2010 and that is to use the Client Side object model. The client side object model a a sub set of the larger Sharepoint API, but it does cover uploading documents. Below is blog post with an example of uploading.
Upload document through client object model
As with most things in SharePoint you will need to authenticate against it the site, so find out if your site collection is forms based or claims based and then you should be able to find sample code for your situation.
Solution to the problem:
The problem was that the "security token webservice" was not working and it was giving some error when we manually ran the webservice.
The server was unable to process the request due to an internal error.
For more information about the error, either turn on
IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute
or from the configuration behavior) on the server in order to send the
exception information back to the client, or turn on tracing as per
the Microsoft .NET Framework 3.0 SDK documentation and inspect the
server trace logs.
The above exception is a generic one. To view the exact exception we enabled remote error viewing from the web.config file of the webservice(link) and saw the exact exception.
We found the solution for the exception and the service started. After that everything was working fine.

Resources