Access denied using mvxfilestore, mvvmcross annd xamarin touch ios 8.1 - xamarin.ios

My app just got reject from apple and i believe it might be caused by them changing to test with ios 8.1. However I cannot reproduce the error in any way. Their chrash report states the app chrashes on startup.
It seems that the exception(have the crash log) comes from
<Warning> Unhandled managed exception: Access to the path "/var/mobile/Documents/settings" is denied. (System.UnauthorizedAccessException)
which originates from
Cirrious.MvvmCross.Plugins.File.MvxFileStore.WriteFileCommon
I am using the mvvmcross 3.11 MvxFileStore plugin. Deployment target ios7, 8.1 ios sdk.
I have been surfing the web and some states Documents directory has moved in iOS 8 and this might cause the exception.
But I cant wrap my head around the fact that I cant reproduce this error.
Do anyone have a similar issue, a suggestion how to fix or an idea how to reproduce their crash.
Anything is appreciated.
Update:
From the post it is suggested to do the following fix
int SystemVersion = Convert.ToInt16(UIDevice.CurrentDevice.SystemVersion.Split('.')[0]);
if (SystemVersion >= 8)
{
var documents = NSFileManager.DefaultManager.GetUrls(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User)[0].Path;
filename = Path.Combine(documents, sFile);
}
else
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); // iOS 7 and earlier
filename = Path.Combine(documents, sFile);
}
I have tried adding it to our project. We used the MvxFileStore to create the path to the settings file
var filestore = Mvx.Resolve<IMvxFileStore>();
string path = filestore.PathCombine(filestore.NativePath (string.Empty), FILENAME);
Now We de the following
var filestore = Mvx.Resolve<IMvxFileStore>();
string path = this.DocsDir() + "/" + FILENAME;
public string DocsDir ()
{
var version = int.Parse(UIDevice.CurrentDevice.SystemVersion.Split('.')[0]);
string docsDir = "";
if (version>=8) {
var docs = NSFileManager.DefaultManager.GetUrls (NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User) [0];
docsDir = docs.Path;
Console.WriteLine("ios 8++ "+docsDir);
} else {
docsDir = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments);
Console.WriteLine("ios 7.1-- " + docsDir);
}
return docsDir;
}
I will resubmit our app and post the result.

Okay,
The fix we did by seperating ios 8 and the rest of ios and do different implementations depending on the ios worked.
Apple has approved our apps and all is love (y)

Related

Tweetinvi doesn't work

I am using mono develop on Ubuntu os.I downloaded Tweetinvi lib from nuget.This used to work on windows.
public static void Main (string[] args)
{
var appCredentials = new TwitterCredentials("AppCred", "AppCred");
var authenticationContext = AuthFlow.InitAuthentication(appCredentials);
Process.Start(authenticationContext.AuthorizationURL);
string pinCode = Console.ReadLine();
var userCredentials = AuthFlow.CreateCredentialsFromVerifierCode(pinCode, authenticationContext);
Auth.SetCredentials(userCredentials);
var firstTweet = Tweet.PublishTweet("Hello World!");
}
Now I get this exception : Unhandled Exception:
System.TypeLoadException: Could not resolve type with token 01000015, in terminal.
I tried different versions of the Tweetinvi library and I got: System.TypeInitialization Exception,at
var authenticationContext = AuthFlow.InitAuthentication(appCredentials);
This worked well in Xamarin Studio in Windows but I must do this in Linux.I guess I must add a reference or something so that ubuntu can open firefox and start authentication process.

Why won't my ASP.NET application export CSV when hosted as an Azure Web app?

MY application exports CSV's fine when I test it from Visual Studio, but when I deploy it to an Azure as a Web app, instead of exporting a CSV I get a Error code: ERR_INVALID_RESPONSE.
Below is the method I use :
public void ExportEmpReport(int? er_id)
{
var er_hdr = db.expense_report_hdr.Include(w => w.employeeExpUser).Where(x => x.ID == er_id).FirstOrDefault();
StringWriter sw = new StringWriter();
sw.WriteLine("Employee Name: " + er_hdr.employeeExpUser.fullname + ", Period: " + er_hdr.period + ", Expense Report ID: " + er_id);
sw.WriteLine("Date of Expense , Expense Class , Detail , Cust/Conv , Notes , Amount , GL Code , Project Code");
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment;filename=ExpenseReport_" + er_id + ".csv");
Response.ContentType = "text/csv";
var lines = db.expense_report_line.Where(y => y.er_id == er_id);
foreach (var line in lines)
{
string exp_class = line.expenseType.expense.ToString().Replace(",", "");
string detail = (line.expense_detail != null) ? line.expense_detail.Replace(",", "") : "";
string cust_conv = (line.cust_conv != null) ? line.cust_conv.Replace(",", "") : "";
string notes = (line.notes != null) ? line.notes.Replace(",", "") : "";
sw.WriteLine(string.Format("{0},{1},{2},{3},{4},{5},{6},{7}", line.expense_date, exp_class, detail, cust_conv, notes, line.amount, line.gl_code.GL_code, line.project_code));
}
Response.Write(sw.ToString());
Response.End();
}
Here are some suggestions you may use to try and troubleshoot it:
A. Debug the web app locally, while connected to the DB on Azure. Are the tables being read correctly?
If the code fails to read the data from the database, make sure that the database is updated to the latest schema.
B. If it reads the data correctly, debug it step by step, and watch exactly where it fails.
If it fails at a particular line, remove/replace some lines of code until the local web app is running correctly against the DB on Azure. You may be able to identify the offending line(s) of code, and then report back here to allow others to help you troubleshoot further.
C. Once you get it working with the local app against the DB on Azure, deploy the updated project code to the Web App on Azure to see if it still runs correctly.
If it still doesn't work, maybe there's a setting on your Web App that is preventing it from running the code successfully.
D. Check the version of the .NET Framework on the Web App in Azure. The choices should be v3.5 or v4.6 (for non-Core 1.0 applications).
If it has the wrong version selected, make sure you select the correct version.
E. Enable Remote Debugging of the Web App running on Azure.
There's a Remote Debugging feature that you can toggle on/off in the Application Settings blade, where you can also select the VS version (2012, 2013, 2015). Turn it on to pinpoint which line of code it's failing at.

Azure Schema Extensions in Graph Client

Whatever I tried I cannot set an extension property on a User object, here is a reproducible piece of code:
public async Task CleanTest(string extName)
{
ExtensionProperty ep = new ExtensionProperty
{
Name = extName,
DataType = "String",
TargetObjects = { "User" }
};
App app = (App)(await _client.Applications.Where(a => a.AppId == _managementAppClientId).ExecuteSingleAsync());
app.ExtensionProperties.Add(ep);
await app.UpdateAsync();
GraphUser user = (GraphUser)(await _client.Users.Where(u => u.UserPrincipalName.Equals("email")).ExecuteSingleAsync());
string propName = FormatExtensionPropertyName(extName); //formats properly as extesion_xxx_name
user.SetExtendedProperty(propName, "testvalue");
//user.SetExtendedProperty(extName, "testvalue");
await user.UpdateAsync(); // fails here
}
user.UpdateAsync() according to Fiddler doesn't even go out and application fails with an exception:
"The property 'extension_e206e28ff36244b19bc56c01160b9cf0_UserEEEqdbtgd3ixx2' does not exist on type 'Microsoft.Azure.ActiveDirectory.GraphClient.Internal.User'. Make sure to only use property names that are defined by the type."
This issue is also being tracked here:
https://github.com/Azure-Samples/active-directory-dotnet-graphapi-console/issues/28
I've got an alternative workaround for this bug, for those that want to use the version 5.7 OData libraries rather than redirecting to the v5.6.4 versions.
Add a request pipeline configuration handler.
// initialize in the usual way
ActiveDirectoryClient activeDirectoryClient =
AuthenticationHelper.GetActiveDirectoryClientAsApplication();
// after initialization add a handler to the request pipline configuration.
activeDirectoryClient.Context
.Configurations.RequestPipeline
.OnMessageWriterSettingsCreated(UndeclaredPropertyHandler);
In the handler, change the ODataUndeclaredPropertyBehaviorKinds value on the writer settings to SupportUndeclaredValueProperty.
private static void UndeclaredPropertyHandler(MessageWriterSettingsArgs args)
{
var field = args.Settings.GetType().GetField("settings",
BindingFlags.NonPublic | BindingFlags.Instance);
var settingsObject = field?.GetValue(args.Settings);
var settings = settingsObject as ODataMessageWriterSettings;
if (settings != null)
{
settings.UndeclaredPropertyBehaviorKinds =
ODataUndeclaredPropertyBehaviorKinds.SupportUndeclaredValueProperty;
}
}
Just in case you still looking for solution to this problem or someone else is facing the same issue:
I got similar issue and it looks like, at least for me, the problem was in latest version of "Microsoft.Data.Services.Client" package - 5.7.0 (or in one of it dependencies). When I downgraded to previous version - 5.6.4 it worked as a charm.
I had same symptoms - updating of extended property was failing even w/o any request is made (also used Fiddler)
Hope it helps!
Artem Liman

Xamarin iOS 8 Bundle Resource - Access to the path is denied

I've have a Xamarin iOS project with a file that I have marked as a bundle resource. The file is configured in the project like so:
<BundleResource Include="my\folder\file.xyz" />
I've have been using the following to access the file as a stream:
string ext = Path.GetExtension ("file.xyz");
string filenameNoExt = filename.Substring (0, filename.Length - ext.Length);
string path = Path.Combine ("my/folder", filenameNoExt);
var resourcePathname = NSBundle.MainBundle.PathForResource (path, ext.Substring (1, ext.Length - 1));
var fStream = new FileStream (resourcePathname, FileMode.Open);
It won't work on iOS 8. It worked without issue before iOS 8.
I get the following error:
Access to the path "/private/var/mobile/Containers/Bundle/Application/0E6DD32F-4E6F-4E54-B47E-A91060097E16/myapp.app/my/folder/file.xyz" is denied.
What, exactly, do I need to change to get this to work in iOS 8?
Provide also FileAccess.Read when you create the stream. Otherwise it will throw an UnauthorizedAccessException for read-only files.

Can't access to Azure Storage folder using Lucene.Net

We decided to implement a search functionality in our API which is developed in ServiceStack, we decided to use Lucene.Net since we heard it was a great indexer to make searches.
We created a worker role whose job is to create the indexes in a Azure Storage folder, we guided ourselves using Leon Cullen's tutorial. We use the AzureDirectory library specified in that post, so we could use the latest Azure SDK.
Then in our API project we added the references for Lucene.Net and AzureDirectory too, our endpoint ended up looking like this:
public object Post(SearchIndex request)
{
List<Product> products = new List<Product>();
var pageSize = -1;
var totalpages = -1;
int.TryParse(ConfigurationManager.AppSettings["PageSize"], out pageSize);
if (request.Page.Equals(0))
{
request.Page = 1;
}
// Get Azure settings
AzureDirectory azureDirectory ;
try
{
// This is the line where we get the Access denied exception thrown at us
azureDirectory = new AzureDirectory(Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(ConfigurationManager.AppSettings["ConnectionStringAzureSearch"]), "indexsearch");
IndexSearcher searcher;
using (new AutoStopWatch("Creating searcher"))
{
searcher = new IndexSearcher(azureDirectory);
}
using (new AutoStopWatch(string.Format("Search for {0}", request.SearchString)))
{
string[] searchfields = new string[] { "Id", "Name", "Description" };
var hits = searcher.Search(QueryMaker(request.SearchString, searchfields), request.Page * pageSize);
int count = hits.ScoreDocs.Count();
float temp_totalpages = 0;
temp_totalpages = (float)hits.ScoreDocs.Count() / (float)pageSize;
if (temp_totalpages > (int)temp_totalpages)
{
totalpages = (int)temp_totalpages + 1;
}
else
{
totalpages = (int)temp_totalpages;
}
foreach (ScoreDoc match in hits.ScoreDocs)
{
Document doc = searcher.Doc(match.Doc);
int producId = int.Parse(doc.Get("Id"));
Product product = Db.Select<Product>("Id={0}", producId).FirstOrDefault();
products.Add(product);
}
}
return new SearchIndexResult { result = products.Skip((int)((request.Page - 1) * 10)).Take(pageSize).ToList(), PageSize = pageSize, TotalPages = totalpages };
}
catch (Exception e)
{
return new HttpResult(HttpStatusCode.NoContent, "azureDirectory. Parameter: " + request.SearchString + ". e: " + e.Message);
}
}
If we run this locally it works as expected, returning us the results we were expecting. But when we published our API to Azure and tried to access to the search endpoint we received an 403 error message with the message 'Access to the path "D:/AzureDirectory" is denied".
We're confused as to why is trying to access to such folder at all, the name of the folder is wrong and I think it's trying to access a local route, we really don't know why does it work fine locally but once it's deployed to Azure it stops working.
The worker role runs without a problems, but it's the API side that cannot access to the folder in Azure Storage. Are we missing some important step in the configuration? The tutorial we followed wasn't very clear for beginners using Lucene.Net or Azure Storage so we fear we might have missed an important step. We've checked our connection strings and everything seems ok though.
As for reference:
https://github.com/azure-contrib/AzureDirectory/blob/master/AzureDirectory/AzureDirectory.cs
when you do this
azureDirectory = new AzureDirectory(Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(ConfigurationManager.AppSettings["ConnectionStringAzureSearch"]), "indexsearch");
This executes
var cachePath = Path.Combine(Path.GetPathRoot(Environment.SystemDirectory), "AzureDirectory");
var azureDir = new DirectoryInfo(cachePath);
if (!azureDir.Exists)
azureDir.Create();
var catalogPath = Path.Combine(cachePath, _containerName);
var catalogDir = new DirectoryInfo(catalogPath);
if (!catalogDir.Exists)
catalogDir.Create();
_cacheDirectory = FSDirectory.Open(catalogPath);
So simple solution for you might be to have that directory on site root
DirectoryInfo info = new DirectoryInfo(HostingEnvironment.MapPath("~/"));
azureDirectory = new AzureDirectory(storageAccount, containerName, new SimpleFSDirectory(info), true);
I got it to work.
I just got the latest version of AzureDirectory from GitHub.
Got the latest nuGet packages for Azure Storage etc.
Recreated the index.
In addition to #brykneval answer, I tried his solution but last parameter bool compressBlob = false which he set to true made my local debug fail with 404 exception from AzureDirectory library and when I published to Azure web app, it had exception with message: System.IO.InvalidDataException: Block length does not match with its complement.
I removed last parameter from constructor and everything works like a charm. Hope this helps anyone.

Resources