401 System.UnauthorizedAccessException when access Dropbox With SharpBox API - asp.net

The code
config = CloudStorage.GetCloudConfigurationEasy(nSupportedCloudConfigurations.DropBox)
as DropBoxConfiguration;
//config.AuthorizationCallBack = new Uri("http://localhost:61926/DBoxDemo.aspx");
requestToken = DropBoxStorageProviderTools.GetDropBoxRequestToken(config, "KEY", "SECRET");
//Session["requestToken"] = requestToken;
string AuthoriationUrl = DropBoxStorageProviderTools.GetDropBoxAuthorizationUrl(
config, requestToken);
Process.Start(AuthoriationUrl);
accessToken = DropBoxStorageProviderTools.ExchangeDropBoxRequestTokenIntoAccessToken(
config, "xxxxxxxxxxxxx", "xxxxxxxxxxxxx", requestToken);
CloudStorage dropBoxStorage = new CloudStorage();
var storageToken = dropBoxStorage.Open(config, accessToken);
var publicFolder = dropBoxStorage.GetFolder("/");
// upload a testfile from temp directory into public folder of DropBox
String srcFile = Environment.ExpandEnvironmentVariables(#"C:\Test\MyTestFile.txt");
var rep = dropBoxStorage.UploadFile(srcFile, publicFolder);
MessageBox.Show("Uploaded Successfully..");
**dropBoxStorage.DownloadFile("/MyTestFile.txt",
Environment.ExpandEnvironmentVariables("D:\\test"));**
MessageBox.Show("Downloaded Successfully..");
dropBoxStorage.Close();
This is the Error shown in Visual Studio.

SharpBox has a bug that only occurs in .NET 4.5, because the behavior of the class System.Uri has changed from 4.0 to 4.5.
The method GetDownloadFileUrlInternal() in DropBoxStorageProviderService.cs generates an incorrect URL, because it changes a slash in %2f. In .NET 4.0, this URL will be converted correctly back through the System.Uri object in the method GenerateSignedUrl() in OAuthUrlGenerator.cs.
I have changed the method GetDownloadFileUrlInternal() from this...
public static String GetDownloadFileUrlInternal(IStorageProviderSession session, ICloudFileSystemEntry entry)
{
// cast varibales
DropBoxStorageProviderSession dropBoxSession = session as DropBoxStorageProviderSession;
// gather information
String rootToken = GetRootToken(dropBoxSession);
String dropboxPath = GenericHelper.GetResourcePath(entry);
// add all information to url;
String url = GetUrlString(DropBoxUploadDownloadFile, session.ServiceConfiguration) + "/" + rootToken;
if (dropboxPath.Length > 0 && dropboxPath[0] != '/')
url += "/";
url += HttpUtilityEx.UrlEncodeUTF8(dropboxPath);
return url;
}
...to this...
public static String GetDownloadFileUrlInternal(IStorageProviderSession session, ICloudFileSystemEntry entry)
{
// cast varibales
DropBoxStorageProviderSession dropBoxSession = session as DropBoxStorageProviderSession;
// gather information
String rootToken = GetRootToken(dropBoxSession);
// add all information to url;
String url = GetUrlString(DropBoxUploadDownloadFile, session.ServiceConfiguration) + "/" + rootToken;
ICloudFileSystemEntry parent = entry.Parent;
String dropboxPath = HttpUtilityEx.UrlEncodeUTF8(entry.Name);
while(parent != null)
{
dropboxPath = HttpUtilityEx.UrlEncodeUTF8(parent.Name) + "/" + dropboxPath;
parent = parent.Parent;
}
if (dropboxPath.Length > 0 && dropboxPath[0] != '/')
url += "/";
url += dropboxPath;
return url;
}
and currently it works with .NET 4.5. It may exist a better way to fix the problem, but currently no misconduct noticed.

Related

System.Net.WebClient.DownloadStringTaskAsync method when webpage contains ™ or other special characters

I am using the System.Net.WebClient.DownloadStringTaskAsync async method to upload a web page content and process it or just save it on my local folder. Everything is fine but when the web page contains some special characters like ™ or ®, they are not getting downloaded. Am I missing something here?
String contentToScrapeURL = "https://www.naylornetwork.com/aaho-advertorial/newsletter.asp?issueID=89542";
Boolean success = true;
using (System.Net.WebClient wc = new System.Net.WebClient())
{
String pageSourceCode = await wc.DownloadStringTaskAsync(contentToScrapeURL);
String path = #"C:\MyProjects\TestingThings\App_Data\" + "test.html";
File.WriteAllText(path, pageSourceCode);
}
Found it, or remembered it.
I did set the System.Net.WebClient.Encoding to Encoding.UTF8
So this below is the updated code
using (System.Net.WebClient wc = new System.Net.WebClient())
{
wc.Encoding = Encoding.UTF8;
String pageSourceCode = await wc.DownloadStringTaskAsync(contentToScrapeURL);
String path = #"C:\MyProjects\TestingThings\App_Data\" + "test.html";
File.WriteAllText(path, pageSourceCode);
}

Is it possible to create a folder on the Alfresco site by using OpenCMIS API?

I have the Presentation Web Script (script A) and the Data Web Script (script B).
In the script A I build the dialog that interacts with the script B.
Here I am forming some path where the some file will be uploaded (group, year and number parameters define this path):
...
var submitHandler = function() {
var dataWebScriptUrl = window.location.protocol + '//' +
window.location.host + "/alfresco/s/ms-ws/script-b?guest=true";
var yearCombo = document.getElementById("year");
var year = yearCombo.options[yearCombo.selectedIndex].value;
var groupCombo = document.getElementById("group");
var group = groupCombo.options[groupCombo.selectedIndex].value;
var numberCombo = document.getElementById("number");
var number = numberCombo.value;
var uploadedFile = document.getElementById("uploadedFile");
var file = uploadedFile.files[0];
var formData = new FormData();
formData.append("year", year);
formData.append("group", group);
formData.append("number", number);
formData.append("uploadedFile", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", dataWebScriptUrl);
xhr.send(formData);
};
...
In script B, I'm using the Apache Chemistry OpenCMIS API to create a path in the CMIS-compatible Alfresco repository:
public class CustomFileUploader extends DeclarativeWebScript implements OpenCmisConfig {
...
private void retrievePostRequestParams(WebScriptRequest req) {
String groupName = null, year = null, number = null;
FormData formData = (FormData) req.parseContent();
FormData.FormField[] fields = formData.getFields();
for(FormData.FormField field : fields) {
String fieldName = field.getName();
String fieldValue = field.getValue();
if(fieldName.equalsIgnoreCase("group")) {
if(fieldValue.equalsIgnoreCase("services")) {
groupName = "Услуги";
...
}
firstLevelFolderName = "/" + groupName;
secondLevelFolderName = groupName + " " + year;
thirdLevelFolderName = number;
}
...
Folder firstLevelFolder =
createFolderIfNotExists(cmisSession, docLibFolder, firstLevelFolderName);
...
private Folder createFolderIfNotExists(Session cmisSession,
Folder parentFolder, String folderName) {
Folder subFolder = null;
for(CmisObject child : parentFolder.getChildren()) {
if(folderName.equalsIgnoreCase(child.getName())) {
subFolder = (Folder) child;
}
}
if(subFolder == null) {
Map<String, Object> props = new HashMap<>();
props.put("cmis:objectTypeId", "cmis:folder");
props.put("cmis:name", folderName);
subFolder = parentFolder.createFolder(props);
}
return subFolder;
}
private Folder getDocLibFolder(Session cmisSession, String siteName) {
String path = "/Sites/" + siteName + "/documentLibrary";
return (Folder) cmisSession.getObjectByPath(path);
}
private Session getCmisSession() {
SessionFactory factory = SessionFactoryImpl.newInstance();
Map<String, String> conf = new HashMap<>();
// http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
conf.put(SessionParameter.ATOMPUB_URL, ATOMPUB_URL);
conf.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
conf.put(SessionParameter.USER, USER_NAME);
conf.put(SessionParameter.PASSWORD, PASSWORD);
// "org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl"
conf.put(SessionParameter.OBJECT_FACTORY_CLASS, OBJECT_FACTORY_CLASS);
conf.put(SessionParameter.REPOSITORY_ID, "-default-");
Session session = factory.createSession(conf);
return session;
}
...
It's all works well... But I need to create the directory structure on a specific site, e.g. "contracts-site", here:
/site/contracts-site/documentlibrary
When I specifying the following:
/Sites/contracts-site/documentLibrary/Услуги
/Sites/contracts-site/Услуги
/site/contracts-site/documentlibrary/Услуги
I get the following exception (depending on the path):
org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException: Object not found: /Sites/contracts-site/Услуги
When I specifying the following:
"/Услуги"
Everything works, but the directory structure is created outside the site...
How to create a folder on the Alfresco site by using OpenCMIS API?
Arn't you missing /company_home/ ?
This would lead to
/company_home/Sites/contracts-site/documentLibrary/Услуги
Just accidentally found the solution. Works perfectly if specify the following path:
// locate the document library
String path = "/Сайты/contracts-site/documentLibrary";
Ie, "Сайты" instead of "Sites"... (Cyrillic alphabet)
I'm using ru_RU locale and UTF-8 encoding. Then this example also works.

Upload file into S3 with AWS SDK ASP.NET

I am trying to upload an image from ASP.NET to S3. I am using AWS SDK for that and have already set up what is needed. However, after i run my project, i received an error. I'll be replacing my bucket name to ... for this sample code.
I set up my secretkey and accesskey from User in my Web.config. Please do tell me if u need more codes. I need help.
controller
private static readonly string _awsAccessKey = ConfigurationManager.AppSettings["AWSAccessKey"];
private static readonly string _awsSecretKey = ConfigurationManager.AppSettings["AWSSecretKey"];
[HttpPost]  
        public ActionResult UploadFile(HttpPostedFileBase file)  
        {
try  
            {
if (file.ContentLength > 0)
{
IAmazonS3 client;
using (client = Amazon.AWSClientFactory.CreateAmazonS3Client(_awsAccessKey, _awsSecretKey))
{
PutObjectRequest request = new PutObjectRequest
{
BucketName = "...",
CannedACL = S3CannedACL.PublicRead,
Key = "images/" + (DateTime.Now.ToBinary() + "-" + file.FileName),
FilePath = Server.MapPath("~/UploadedFiles")
};
client.PutObject(request);
}
}
imageUrls = "File Uploaded Successfully!!";
System.Diagnostics.Debug.WriteLine("File Uploaded Successfully!!");
return Json(imageUrls);
            }  
            catch  
            {  
                ViewBag.Message = "File upload failed!!";
System.Diagnostics.Debug.WriteLine("File upload failed!!");
return Json(ViewBag.Message);  
            }  
        }
You're getting the error due to DateTime.Now.ToBinary() which contains invalid characters to be used in a URL. For example, you could use a GUID or a Unix timestamp instead.
Also, the FilePath property you're assigning to the PutObjectRequest is the full path and name to a file to be uploaded. So, you don't need it when you already have HttpPostedFileBase as an input parameter, which contains the InputStream property (i.e., the stream object).
Your PutObjectRequest should look something like this:
.
.
.
Guid guid = Guid.NewGuid();
// Create a client
AmazonS3Client client = new AmazonS3Client(_awsAccessKey, _awsSecretKey);
// Create a PutObject request
PutObjectRequest request = new PutObjectRequest
{
BucketName = "...",
CannedACL = S3CannedACL.PublicRead,
Key = "images/" + guid + "-" + file.FileName
};
using (System.IO.Stream inputStream = file.InputStream)
{
request.InputStream = inputStream;
// Put object
PutObjectResponse response = client.PutObject(request);
}
.
.
.
I finally solved it. I realized i did not place region in AWSClientFactory, right at the end after the keys.

Why does R.NET work locally but stop working in IIS?

I have an ASP.NET MVC application that sends parameters to an R script, the R script then generates a file and puts it in a folder locally. The process works perfectly on my local machine through Visual Studio but goes in and out after I publish and use IIS. Below is how I am initializing R.NET and getting these values from my view via AJAX.
I also have placed both of these PATHs in my system environment variables.
If anyone knows why IIS only works right after I restart my OS and then stops working shortly after I would greatly appreciate it. Seems odd that I have no problems in Visual Studio that I face in IIS.
[HttpGet]
public JsonResult Index1(string modelTypes = null, string fileNames = null, string[] locations = null, string lowerLimits = null, string upperLimits = null, string areas = null, string productivities = null, string[] fobs = null)
{
#ViewBag.UserName = System.Environment.UserName;
string userName = #ViewBag.UserName;
//Declare field parameters
var strModelTypeValue = modelTypes;
string strFileName = fileNames;
var strLocationValue = locations;
var strLowerLimitValue = lowerLimits;
var strUpperLimitValue = upperLimits;
string strAreaValue = areas;
string strProductivityValue = productivities;
string strFobValue = fobs.ToString();
var libraryLocation = "C:/Users/" + userName + "/Documents/R/win-library/3.2";
string rPath = #"C:\Program Files\R\R-3.3.2\bin\x64";
string rHome = #"C:\Program Files\R\R-3.3.2";
//Initialize REngine
REngine.SetEnvironmentVariables(rPath, rHome);
REngine engine = REngine.GetInstance();
engine.Initialize();
if (fobs.Length > 1)
{
strFobValue = string.Join(" ", fobs);
}
else
{
strFobValue = "ALL";
}
//Declare R Script path
var rScriptPath = "C:/Users/" + userName + "/Documents/R/RWDir/Loop_Optimization.R";
//Check to see if there was more than one location selected
if (strLocationValue.Length > 1)
{
foreach (var item in strLocationValue)
{
//Set string location to each location value in loop
var strlocation = item;
//Add values to parameter list
var myParams = new List<string>
{
strModelTypeValue,
strFileName,
strlocation,
strLowerLimitValue,
strUpperLimitValue,
strAreaValue,
strProductivityValue,
strFobValue,
libraryLocation
};
//Set myParams as arguments to be sent to r script
engine.SetCommandLineArguments(myParams.ToArray());
engine.Evaluate("source('" + rScriptPath + "')");
}
}
//Only one location specified, no need to loop
else
{
foreach (var item in strLocationValue)
{
//Set string location to each location value in loop
var strlocation = item;
var myParams = new List<string>
{
strModelTypeValue,
strFileName,
strlocation,
strLowerLimitValue,
strUpperLimitValue,
strAreaValue,
strProductivityValue,
strFobValue,
libraryLocation
};
engine.SetCommandLineArguments(myParams.ToArray());
engine.Evaluate("source('" + rScriptPath + "')");
}
}
//engine.Evaluate("source('" + rScriptPath + "')");
//engine.Dispose();
return Json("success", JsonRequestBehavior.AllowGet);
}
have you done any debugging by attaching process .

X509Certificate2 - the system cannot find the path specified

I wish to get the data of Google analytics via service account.
When I launch first time the application, everything works correctly and I have access to the data. But When I launch second time the application I have the following error which appears: " the system cannot find the path specified ". Have you an idea? I thought it can be a lock.
This is my source code:
public static String GetAccessToken(string clientIdEMail, string keyFilePath, String scope)
{
// certificate
var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
// header
var header = new { typ = "JWT", alg = "RS256" };
// claimset
var times = GetExpiryAndIssueDate();
var claimset = new
{
iss = clientIdEMail,
scope = scope,
aud = "https://accounts.google.com/o/oauth2/token",
iat = times[0],
exp = times[1],
};
JavaScriptSerializer ser = new JavaScriptSerializer();
// encoded header
var headerSerialized = ser.Serialize(header);
var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
var headerEncoded = Convert.ToBase64String(headerBytes);
// encoded claimset
var claimsetSerialized = ser.Serialize(claimset);
var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
var claimsetEncoded = Convert.ToBase64String(claimsetBytes);
// input
var input = headerEncoded + "." + claimsetEncoded;
var inputBytes = Encoding.UTF8.GetBytes(input);
// signiture
var rsa = certificate.PrivateKey as RSACryptoServiceProvider;
var cspParam = new CspParameters
{
KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
Flags = CspProviderFlags.UseMachineKeyStore
};
var aescsp = new RSACryptoServiceProvider(1024,cspParam) { PersistKeyInCsp = false };
var signatureBytes = aescsp.SignData(inputBytes, "SHA256");
var signatureEncoded = Convert.ToBase64String(signatureBytes);
// jwt
var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;
var client = new WebClient();
client.Encoding = Encoding.UTF8;
var uri = "https://accounts.google.com/o/oauth2/token";
var content = new NameValueCollection();
content["assertion"] = jwt;
content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
string response = Encoding.UTF8.GetString(client.UploadValues(uri, "POST", content));
JsonGoogleResponse result = (ser.Deserialize<JsonGoogleResponse>(response));
return result.access_token;
}
And this is the stack:
à System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
à System.Security.Cryptography.SafeProvHandle._FreeCSP(IntPtr pProvCtx)
à System.Security.Cryptography.SafeProvHandle.ReleaseHandle()
à System.Runtime.InteropServices.SafeHandle.InternalFinalize()
à System.Runtime.InteropServices.SafeHandle.Dispose(Boolean disposing)
à System.Runtime.InteropServices.SafeHandle.Finalize()
If you are running in IIS, you need to set "Load User Profile" to True in the application pool's advanced settings to be able to load a cert by filename & password.
So, I just had the exact same problem. I tried to solve it for almost 4 hours.
Problem was in passed path to key. Because I used the code from Google sample console application, where the path was just "key.p12" and the key was in the same directory as the exe file.
And when I wanted to create MVC application, I did not realize, that root of virtual server path can not be called just like "key.p12".
SOLUTION
Double check the path to the key. If it is MVC application (or another ASP web), then add the key file to the root and in code call the key by using Server.MapPath("key.p12").
I just had the same issue, in my case it was a space in the path. I have no idea why, but when I put the p12 file on c:\ root, it's working...

Resources