UWP MediaFrameReader - System.ArgumentException: 'Value does not fall within the expected range.' - c#

I am trying to create a UWP application that uses the laptop's webcam to process mediaframes on which I want to search faces using Microsoft Azure Face API.
I created a MediaCapture that works well, and a MediaFrameReader, which throws the exception mentioned in the question's title.
You can see my code here:
private async void StartDetection()
{
mediaStream = new InMemoryRandomAccessStream();
MediaEncodingProfile encodingProfile = MediaEncodingProfile.CreateMp4(encodingQuality);
await mediaCapture.StartRecordToStreamAsync(encodingProfile, mediaStream);
var frameSourceGroups = await MediaFrameSourceGroup.FindAllAsync();
MediaFrameSourceGroup selectedGroup = null;
MediaFrameSourceInfo colorSourceInfo = null;
foreach (var sourceGroup in frameSourceGroups)
{
foreach (var sourceInfo in sourceGroup.SourceInfos)
{
if (sourceInfo.MediaStreamType == MediaStreamType.VideoRecord
&& sourceInfo.SourceKind == MediaFrameSourceKind.Color)
{
colorSourceInfo = sourceInfo;
break;
}
}
if (colorSourceInfo != null)
{
selectedGroup = sourceGroup;
break;
}
}
var selectedGroupObjects = frameSourceGroups.Select(group =>
new
{
sourceGroup = group,
colorSourceInfo = group.SourceInfos.FirstOrDefault((sourceInfo) =>
{
// On Xbox/Kinect, omit the MediaStreamType and EnclosureLocation tests
return sourceInfo.MediaStreamType == MediaStreamType.VideoRecord
&& sourceInfo.SourceKind == MediaFrameSourceKind.Color
&& sourceInfo.DeviceInformation?.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front;
})
}).Where(t => t.colorSourceInfo != null).FirstOrDefault();
selectedGroup = selectedGroupObjects?.sourceGroup;
colorSourceInfo = selectedGroupObjects?.colorSourceInfo;
if (selectedGroup == null)
{
return;
}
var allGroups = await MediaFrameSourceGroup.FindAllAsync();
var eligibleGroups = allGroups.Select(g => new
{
Group = g,
SourceInfos = new MediaFrameSourceInfo[]
{
g.SourceInfos.FirstOrDefault(info => info.SourceKind == MediaFrameSourceKind.Color),
g.SourceInfos.FirstOrDefault(info => info.SourceKind == MediaFrameSourceKind.Depth),
g.SourceInfos.FirstOrDefault(info => info.SourceKind == MediaFrameSourceKind.Infrared),
}
}).Where(g => g.SourceInfos.Any(info => info != null)).ToList();
if (eligibleGroups.Count == 0)
{
System.Diagnostics.Debug.WriteLine("No source group with color, depth or infrared found.");
return;
}
var selectedGroupIndex = 0;
selectedGroup = eligibleGroups[selectedGroupIndex].Group;
colorSourceInfo = eligibleGroups[selectedGroupIndex].SourceInfos[0];
MediaFrameSourceInfo infraredSourceInfo = eligibleGroups[selectedGroupIndex].SourceInfos[1];
MediaFrameSourceInfo depthSourceInfo = eligibleGroups[selectedGroupIndex].SourceInfos[2];
var colorFrameSource = mediaCapture.FrameSources[colorSourceInfo.Id];
var preferredFormat = colorFrameSource.SupportedFormats.Where(format =>
{
return format.VideoFormat.Width >= 1080
&& format.Subtype == "RGB24";
}).FirstOrDefault();
if (preferredFormat == null)
{
return;
}
await colorFrameSource.SetFormatAsync(preferredFormat);
MediaFrameReader mediaFrameReader;
mediaFrameReader = await mediaCapture.CreateFrameReaderAsync(colorFrameSource, preferredFormat.Subtype);
mediaFrameReader.FrameArrived += CheckFrameForFaces;
await mediaFrameReader.StartAsync();
}
private async void CheckFrameForFaces(MediaFrameReader sender, MediaFrameArrivedEventArgs args)
{
var mediaFrame = sender.TryAcquireLatestFrame(); // -> this is the line that throws the exception
var videoFrame = mediaFrame?.VideoMediaFrame;
var bitmap = videoFrame?.SoftwareBitmap;
WriteableBitmap wb = new WriteableBitmap(bitmap.PixelWidth, bitmap.PixelHeight);
bitmap.CopyToBuffer(wb.PixelBuffer);
var img = Dlib.LoadImageData<RgbPixel>(wb.PixelBuffer.ToArray(), (uint)wb.PixelHeight, (uint)wb.PixelWidth, 3);
ImageWindow im = new ImageWindow(img);
im.WaitUntilClosed();
}
This code by the way is written based on the Microsoft documentation, which can be found here:
https://learn.microsoft.com/en-us/windows/uwp/audio-video-camera/process-media-frames-with-mediaframereader
The only thing I changed is the MediaEncodingSubtype, because it didn't worked with Argb32, so I use Rgb24 (I checked all the supported formats in my computer). And I think the problem is derived from this property. When I initialize the MediaFrameReader object with the subtype Argb32 (as you can see in the documentation example) I get no exception, although the SoftwareBitmap will be null. On the other hand, if I use Rgb24 (because the preferredFormat has this subtype) I get the exception.
I can show some details of the exception:
System.ArgumentException
HResult=0x80070057
Message=Value does not fall within the expected range.
Source=Windows
StackTrace:
at Windows.Media.Capture.Frames.MediaFrameReader.TryAcquireLatestFrame()
at FaceAPI.MainPage.<CheckFrameForFaces>d__17.MoveNext() in P:\Dokumentumok\Suli\BME-VIK_6\Klitech\Házi feladat\KlitechHF\FaceAPI\FaceAPI\MainPage.xaml.cs:line 217

Related

SignalR library throws error when it application run without debug points and work fine while debugging

I have created a .net core chat application using SignalR and I need move to next user by clicking next button. When I click the next button it will trigger the method "getRemoteClientNext" inside the Hub class
public async Task getRemoteClientNext(string RemoteUserId)
{
var name = Context.User.Identity.Name;
var CurrentAppUser = _userManager.FindByNameAsync(name);
if(RemoteUserId != null) {
using (var db = _dBContext)
{
var remotename = db.Users.Find(RemoteUserId);
var RemoteUser = db.Connections.Where(c => c.UsersId != CurrentAppUser.Result.Id && c.UsersId != RemoteUserId && c.RemoteConnected == false).AsEnumerable().GroupBy(c => c.UsersId);
//var remoteConnection = db.Connections.Where(u => u.UsersId == CurrentAppUser.Result.Id || u.UsersId == RemoteUserId).ToList();
//remoteConnection.ForEach(i => i.RemoteConnected = false);
var currntUserConnection = db.Connections.Where(u => u.UsersId == CurrentAppUser.Result.Id).AsEnumerable().FirstOrDefault();
currntUserConnection.RemoteConnected = false;
db.SaveChanges();
var RemoteUserConnection = db.Connections.Where(u => u.UsersId == RemoteUserId).AsEnumerable().FirstOrDefault();
if (RemoteUserConnection != null)
{
RemoteUserConnection.RemoteConnected = false;
}
db.SaveChanges();
var connec = db.Connections.Where(c => c.UsersId == RemoteUserId);
if (connec.Count() == 0)
{
await Clients.Caller.SendAsync("ClienErrors", "The user is no longer connected");
}
else
{
foreach (var connection in connec)
{
await Clients.Client(connection.ConnectionID).SendAsync("maintainConnectionStatus", "Connecting a remote user......");
}
}
await Clients.Caller.SendAsync("maintainConnectionStatus", "Connecting a remote user......");
if (RemoteUser.Count() == 0)
{
await Clients.Caller.SendAsync("maintainConnectionStatus", "Connecting a remote user......");
}
else
{
var selectedRemoteUser = RemoteUser.First().ToList();
var currentUserConnection = db.Connections.Where(u => u.UsersId == CurrentAppUser.Result.Id).AsEnumerable().FirstOrDefault();
// selectedRemoteUser.ForEach(c => c.RemoteConnected = true, c.Remo) ;
foreach(Connections con in selectedRemoteUser)
{
con.RemoteConnected = true;
con.RemoteConnectionID = currentUserConnection.ConnectionID;
currentUserConnection.RemoteConnectionID = con.ConnectionID;
}
// var currentUserConnection = db.Connections.Where(u => u.UsersId == CurrentAppUser.Result.Id).AsEnumerable().FirstOrDefault();
var RemoteId = selectedRemoteUser.Select(u => u.UsersId).FirstOrDefault();
var RemoteName = db.Users.Find(RemoteId);
currentUserConnection.RemoteConnected = true;
db.SaveChanges();
//var RemoteId = selectedRemoteUser.Select(u => u.UsersId).FirstOrDefault();
//var RemoteName = db.Users.Find(RemoteId);
var connec2 = db.Connections.Where(c => c.UsersId == RemoteId);
if (connec2.Count() ==0)
{
await Clients.Caller.SendAsync("ClienErrors", "The user is no longer connected");
}
else
{
foreach (var connection in connec2)
{
await Clients.Client(connection.ConnectionID).SendAsync("SendRemoteUserId", CurrentAppUser.Result.Id, CurrentAppUser.Result.FirstName);
}
}
await Clients.Caller.SendAsync("SendRemoteUserId", RemoteId, RemoteName.FirstName);
}
}
}
}
in java script the event is like
document.getElementById("next").addEventListener("click", function (event) {
connection.invoke("getRemoteClientNext", RemoteUserId);
});
The issue I got is when I click the next button "getRemoteClientNext" will be triggered and work fine when it is debugging. If I disable all the debug points and run the application this will not work. But other functions like sending the chat messages using hub are working finely. Then I check the console and I saw the error message
Uncaught (in promise) Error: An unexpected error occurred invoking 'getRemoteClientNext' on the server.
at _this.callbacks. (signalr.js:2088)
at HubConnection.processIncomingData (signalr.js:2182)
at WebSocketTransport.HubConnection.connection.onreceive (signalr.js:1905)
at WebSocket.webSocket.onmessage (signalr.js:3949)
I removed the SignalR and try to install it again but it is not working and in add client side library also only showing Jquery.SignalR.js and Jquery.SignalR.min.js files. So I added Signalr.js file manually from another project.
Can any one tell me why this is happening is it error in SignalR library
This smells like a race condition just as SomeStudent suggested. Reading through the first couple of lines of code inside the getRemoteClient() method, you are missing an await.
I can't say with 100% certainty this will fix it, but I'm certain it could become a problem even if this wasn't the culprit.
// Add await here.
var CurrentAppUser = await _userManager.FindByNameAsync(name);

Performance issue with c# ToList()

I have this block of code. My data is around 20000 tokens. And I am sending them 1000 and 1000. I am haing performance issues here. What can I do here to make it perform better? Should I try cutting back on the use of .ToList()
var badgewiseGroup = tokensWithoutOnbehlfOf.GroupBy(x => x.BadgeCount);
foreach (var bGroup in badgewiseGroup)
{
var badgeTokensWithoutOnbehlfOf = bGroup.Select(x => x).ToList();
while (badgeTokensWithoutOnbehlfOf.Any())
{
var tokens = badgeTokensWithoutOnbehlfOf.Take(numberToTake).ToList();
Log.Log(EventSeverity.Informational, $"Processing Push notification for MessageId:{pushContent.MessageId}, Username:{tokens.FirstOrDefault().Username}," +
$" OnBehalfOf:{tokens.FirstOrDefault().OnBehalfOf}, Id:{tokens.FirstOrDefault().Id}, DeviceId:{tokens.FirstOrDefault().DeviceId}, " +
$"Token:{tokens.FirstOrDefault().Token}, ");
pushContent.Title = msgTitle;
pushContent.Body = msgBody;
var message = new Messaging.Message();
var androidToken = tokens.Where(x => x.OsVersion != null && x.OsVersion.ToLower().Contains("android")).ToList();
if (androidToken != null && androidToken.Any())
{
message = GetAndroidMessageNotifictationObject(androidToken, pushContent);
SendMessage(message, pushContent.MessageId);
}
var iosToken = tokens.Where(x => x.OsVersion != null && x.OsVersion.ToLower().Contains("ios")).ToList();
if (iosToken != null && iosToken.Any())
{
message = GetIOSMessageNotifictationObject(iosToken, pushContent);
SendMessage(message, pushContent.MessageId);
}
var oldTokens = tokens.Where(x => string.IsNullOrEmpty(x.OsVersion)).ToList();
if (oldTokens != null && oldTokens.Any())
{
message = GetOldAppUsersMessageNotifictationObject(oldTokens, pushContent);
SendMessage(message, pushContent.MessageId);
}
badgeTokensWithoutOnbehlfOf = badgeTokensWithoutOnbehlfOf.Skip(numberToTake).ToList();
}
}
If execute order is not important and u use .Net Core u can try use action block for this.
var blockOptions = new ExecutionDataflowBlockOptions()
{
MaxDegreeOfParallelism = 48,
SingleProducerConstrained = true,
EnsureOrdered = true
};
ActionBlock<TypeInList> block = null;
block = new ActionBlock<TypeInList>(bGroup =>
{
//your bGroup code
}, blockOptions);
tokensWithoutOnbehlfOf.ForEach(bGroup => block.Post(bGroup));
More info about ActionBlock u can find here: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.dataflow.actionblock-1?view=netcore-1.0

Paging with CosmosClient in CosmosDB

I'm trying to implement paging using the SDK v3 CosmosClient instead of the old DocumentClient.
Reason for this is it seems DocumentClient doesn't translate LINQ queries that contains spatial functions very well (ie: When using Within() I'll get an error from DocumentClient stating the methods is not implemented).
Paging works well with DocumentClient.CreateDocumentQuery<T> as such:
var query = DocumentClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri("master", "features"), feedOptions)
.Where(t => t.Type == typeof(T).Name)
.Where(pred)
.AsDocumentQuery();
string queryContinuationToken = null;
var page = await query.ExecuteNextAsync<T>();
if (query.HasMoreResults)
queryContinuationToken = page.ResponseContinuation;
I'm at a little loss as to where to gather a continuation token using CosmosClient and its Container class:
QueryRequestOptions options = new QueryRequestOptions();
options.MaxItemCount = maxRecords;
FeedIterator<T> feed;
if (continuationToken == "")
feed = Container.GetItemLinqQueryable<T>(true, null, options).Where(x => x.Type == typeof(T).Name).Where(pred).ToFeedIterator();
else
feed = Container.GetItemLinqQueryable<T>(true, continuationToken, options).Where(x => x.Type == typeof(T).Name).Where(pred).ToFeedIterator();
FeedIterator seems to have some of the members IDocumentQuery has (like HasMoreResults) but I can't find a continuation token anywhere.
What am I missing?
Alright, here's a Where method I implemented. Seems to work at first glance.
If you do var f = feed.ReadNextAsync() you won't get an object that's of type FeedResponse, preventing you access to the token. You need to declare f explicitly of type FeedResponse<T>
public async Task<(IEnumerable<T> Results, string ContinuationToken)> Where<T>(Expression<Func<T, bool>> pred, int maxRecords = 0, string partitionKey = "", string continuationToken = "") where T : IDocumentModel
{
QueryRequestOptions options = new QueryRequestOptions();
if (partitionKey != "")
options.PartitionKey = new PartitionKey(partitionKey);
if (maxRecords == 0)
{
return (Container.GetItemLinqQueryable<T>(true, null, options).Where(x => x.Type == typeof(T).Name).Where(pred), "");
}
else
{
options.MaxItemCount = maxRecords;
string token = "";
FeedIterator<T> feed;
List<T> res = new List<T>();
if (continuationToken == "")
feed = Container.GetItemLinqQueryable<T>(true, null, options).Where(x => x.Type == typeof(T).Name).Where(pred).ToFeedIterator();
else
feed = Container.GetItemLinqQueryable<T>(true, continuationToken, options).Where(x => x.Type == typeof(T).Name).Where(pred).ToFeedIterator();
Microsoft.Azure.Cosmos.FeedResponse<T> f = await feed.ReadNextAsync();
token = f.ContinuationToken;
foreach (var item in f)
{
res.Add(item);
}
return (res, token);
}
}
With the version 3.12.0 of the Cosmos SDK the following works as expected as a pretty much in place replacement for the older DocumentQuery.
Original DocumentClient method for comparison:
IDocumentQuery<ToDoItem> query = client.CreateDocumentQuery<ToDoItem>(collectionUri)
.Where(t => t.Description.Contains(searchterm))
.AsDocumentQuery();
while (query.HasMoreResults)
{
foreach (ToDoItem result in await query.ExecuteNextAsync())
{
log.LogInformation(result.Description);
}
}
Using a CosmosClient this becomes:
var database = client.GetDatabase("ToDoItems");
var container = database.GetContainer("Items");
var query = container.GetItemLinqQueryable<ToDoItem>()
.Where(t => t.Description.Contains(searchTerm))
.ToFeedIterator();
while (query.HasMoreResults)
{
foreach (ToDoItem result in await query.ReadNextAsync())
{
log.LogInformation(result.Description);
}
}
So your query is now a FeedIterator, and you can call HasMoreResults and ReadNextAsync on it.
Admittedly this won't get you access to the diagnostics, request charge, etc. that comes on the FeedIterator, but it will page through the results cleanly.
IQueryable<returnVModel> query;
var requestOptions = new QueryRequestOptions
{
MaxItemCount = 20
};
if (Token == "" || Token == null)
{
query = Container.GetItemLinqQueryable<returnVModel>(false, null, requestOptions).Where(x => x.id == id);
}
else
{
query = Container.GetItemLinqQueryable<returnVModel>(false, Token, requestOptions).Where(x => x.id == id);
}
var ct = new CancellationTokenSource();
var totalCount = await query.CountAsync(ct.Token); //Total Count
var feedIterator = query.ToFeedIterator();
var queryResults = new List<returnVModel>();
FeedResponse<returnVModel> feedResults = await feedIterator.ReadNextAsync(ct.Token);
queryResults.AddRange(feedResults); // Output
var PaginationToken = feedResults.ContinuationToken //Token
First time we need to pass token as null, from next page onwards pass the token which we received in previous output.
Pagination was working fine in v3.

C# ef second operation started before previous asynchronous operation completed

Just trying to do normal query on ef but getting below error message
"A second operation started on this context before a previous asynchronous operation completed"
I am using await for all aync call but not sure what could be causing this issue.
here' code
var sids = await context.Sites.Where(s => slist.Contains(s.JVSiteID)).ToListAsync();
var header = await context.GenericCsvHeaders.FirstOrDefaultAsync(x => x.Header == csvh) ?? new GenericCsvHeader { Header = csvh };
context.Entry<GenericCsvHeader>(header).State = (header.GenericCsvHeaderID == 0) ? EntityState.Added : EntityState.Unchanged;
var sa = await context.SAs.Where(x => x.StatusID == Data.Enum.Status.Active && mapkeys.Contains(x.SAName)).Select(x => new { x.SAName, x.SACode, x.SAID }).ToListAsync();
if (sa.Count > 0)
sasitelist = await context.Site_SA.Where(x => x.StatusID == Data.Enum.Status.Active && siteids.Contains(x.SiteID ?? 0)).ToListAsync();
var az = await context.Azimuths.Where(x => x.StatusID == Data.Enum.Status.Active && mapkeys.Contains(x.AzimuthName)).Select(x => new { x.AzimuthName, x.AzimuthID }).ToListAsync();
if (az.Count > 0)
azsitelist = await context.Site_Azimuth.Where(x => x.StatusID == Data.Enum.Status.Active && siteids.Contains(x.SiteID ?? 0)).ToListAsync();
var rows = new List<dynamic>(); //getting this list from csv file via csvHelper
foreach (var r in rows)
{
var s = sids.FirstOrDefault(x => x.JVSiteID == (((IDictionary<String, Object>)r)[siteid]).ToString()) ?? new Site();
UpdateSite(s, r, map);
}
private async void UpdateSite(Site site, dynamic csvSite, IDictionary<string, string> map)
{
context.Entry(site).State = (site.StateID == 0) ? EntityState.Added : EntityState.Modified;
site.SiteForAuditTrail = site;
if (map.ContainsKey("SiteName") && !String.IsNullOrWhiteSpace(GetStringOfDynamic(map,csvSite,"SiteName")))
site.SiteName = GetStringOfDynamic(map,csvSite, "SiteName");
if (map.ContainsKey("State") && !String.IsNullOrWhiteSpace(GetStringOfDynamic(map,csvSite, "State")))
{
//getting exception at below line
var state = (await GetRefTypeList<State>(x => x.StateCode == GetStringOfDynamic(map,csvSite, "State"))) ?? new State { StateCode = GetStringOfDynamic(map,csvSite, "State") };
context.Entry(state).State = (state.StateID == 0) ? EntityState.Added : EntityState.Unchanged;
site.State = state;
state.SiteForAuditTrail = site;
}
}
private async Task<T> GetRefTypeList<T>(Func<T, bool> expression) where T : EntityBase
{
if (!refTypes.ContainsKey(typeof(T).Name))
refTypes[typeof(T).Name] = (await context.Set<T>().Where(x => x.StatusID == Data.Enum.Status.Active).ToListAsync());
return (refTypes[typeof(T).Name] as List<T>)?.FirstOrDefault(expression);
}
private string GetStringOfDynamic(IDictionary<string, string> map,dynamic obj, string propertyName)
{
if (((IDictionary<String, Object>)obj).ContainsKey(map[propertyName]))
return (((IDictionary<String, Object>)obj)[map[propertyName]]??"").ToString();
return "";
}
found problem, was missing await when calling UpdateSite
foreach (var r in rows)
{
var s = sids.FirstOrDefault(x => x.JVSiteID == (((IDictionary<String, Object>)r)[siteid]).ToString()) ?? new Site();
**await** UpdateSite(s, r, map);
}
You are having a race condition here. While you are using await you have other code executing potentially before the variable sids, header, sa and az, have been returned.
You should refactor your code so that the remaining code is not executed until these variables are returned. You can do this by using a task and then using the extension WhenAll which will ensure each await has been completed before proceeding. Here is a link to MS docs on Task and WhenAll implementation

How to solve The given key was not present in the dictionary error?

SO.
It has been 3 hours that I am trying to figure out what could be the problem that throws The given key was not present in the dictionary. error but unfortunately being through many SO question and blog posts didn't helped too much.
I have a simple Facebook batch parameters dictionary and when I am iterating through the results it throws the error The given key was not present in the dictionary.
Here is the code where the exception is raised:
foreach (FacebookPermissionModel permissionResult in
result.SelectMany(x => x.data).Where(y => y.status == "granted"))
{
RequiredPermissions[permissionResult.permission].granted = true; // the error comes from here.
}
Here is the complete code:
protected List<FacebookPermissionRequest> CheckPermissions(Dictionary<string, FacebookPermissionRequest> RequiredPermissions)
{
var access_token = HttpContext.Items["access_token"].ToString();
if (!string.IsNullOrEmpty(access_token))
{
var appsecret_proof = access_token.GenerateAppSecretProof();
var fb = new FacebookClient(access_token);
IEnumerable<FacebookPermissionRequest> MissingPermissions =
new List<FacebookPermissionRequest>(); //initialize to an empty list
if (MissingPermissions != null)
{
//create an array of Facebook Batch Parameters based on list of RequiredPermission
FacebookBatchParameter[] fbBatchParameters =
new FacebookBatchParameter[RequiredPermissions.Values.Count()];
int idx = 0;
foreach (FacebookPermissionRequest required_permssion in
RequiredPermissions.Values)
{
fbBatchParameters[idx] = new FacebookBatchParameter
{
HttpMethod = HttpMethod.Get,
Path = string.Format("{0}{1}",
"me/permissions/",
required_permssion.permision_scope_value)
.GraphAPICall(appsecret_proof)
};
required_permssion.granted = false; //initalize all granted indicators to false for each required permission
idx++;
}
dynamic permission_Batchresult = fb.Batch(
fbBatchParameters
);
if (permission_Batchresult != null)
{
List<PermissionResults> result = JsonConvert.
DeserializeObject<List<PermissionResults>>
(permission_Batchresult.ToString());
foreach (FacebookPermissionModel permissionResult in
result.SelectMany(x => x.data).Where(y => y.status == "granted"))
{
RequiredPermissions[permissionResult.permission].granted = true; // the error comes from here.
}
MissingPermissions = RequiredPermissions.Values.
Where(p => p.granted == false);
}
}
return MissingPermissions.ToList();
}
else
throw new HttpException(404, "Missing Access Token");
}
You should check if the dictionary contains the required value before attempting to modify it.
foreach (FacebookPermissionModel permissionResult in
result.SelectMany(x => x.data).Where(y => y.status == "granted"))
{
if (RequiredPermissions.ContainsKey(permissionResult.permission))
{
RequiredPermissions[permissionResult.permission].granted = true;
{
}
some permissions not there in RequiredPermissions
if (RequiredPermissions.ContainsKey(permissionResult.permission))
RequiredPermissions[permissionResult.permission].granted = true; // the error comes from here.
else
Debug.WriteLint("RequiredPermissions obj does not contain this key " + permissionResult.permission);

Categories

Resources