I learn with asp.net identity, async/await, and I have this problem:
I have some function for IEnumerable<T> list
. This list I fill using query syntax and looks like this:
private IEnumerable<SomeModel> GetPersons(int categoryId) {
IEnumerable<SomeModel> persons = from g in db.Categories
join c in db.Persons on g.PersonTypeId equals c.PersonTypeId
where g.CategoryId == categoryId
select new SomeModel
{
PersonName = c.FirstName + " " + c.LastName,
//....etc.
//And here I need call asynchronous function something like this:
IsAdmin = GetPermission(c.Email)
}
if (persons.Any()) {
return persons;
}
return Enumerable.Empty<SomeModel>();
}
In SomeModel is IsAdmin
as bool (when I tried Task<bool>
in GetPermission I use Task<bool>
in SomeModel).
In GetPermission()
is this:
private bool GetPermission(string email) {
var user = SomeMembershipService.GetUser(email); //SomeMembershipService is Interface with Tasks and so on.
var roles = SomeMembershipService.GetRoles(user.Id); //user.Id is as string
bool result = false;
if (roles != null) {
var adm = roles.Result.FirstOrDefault(x => x.Name.Contains("Admin"));
result = adm != null;
}
return result;
}
I tried this write with async/await and as Task, but both my tries was false. So I thought that I have to call GetPermission()
outside of IEnumerable<SomeModel> persons
so I add this block of code into condition after. So code looks like this:
private IEnumerable<SomeModel> GetPersons(int categoryId) {
IEnumerable<SomeModel> persons = from g in db.Categories
join c in db.Persons on g.PersonTypeId equals c.PersonTypeId
where g.CategoryId == categoryId
select new SomeModel
{
PersonName = c.FirstName + " " + c.LastName
//....etc.
}
if (persons.Any())
{
//new code
foreach (var p in persons)
{
p.IsAdmin = GetPermission(p.Email);
}
//end of new code
return persons;
}
return Enumerable.Empty<SomeModel>();
}
But this is wrong too. Maybe I understand bad to asp.net identity and async/await and their use...
Can you help me - what I have to do? Because now, GetPermission
is called too late, so app crash. When I call GetPermission
in persons query, function is called too late (after filled persons list) too. I have no idea how to continue.
GetUser()
is as public IUser GetUser(string username)
and GetRoles()
is as public async Task<IEnumerable<IRole>> GetRoles(string userId)
. I'am sure, that these two methods work fine, I use them in other codes and no problem with them. So it has to be somewhere in code above I think.
I am sorry, if it is stupid question, but I read about this lot here and on msdn, but cannot find result. Thanks to all.
Why I want to use async function as above
I want the function there because when I make whole function as async Task, another function which call this doesn't work properly.
I have this function - it's databinding for kendogrid ():
[HttpPost]
public ActionResult _PersonsBinding([DataSourceRequest]DataSourceRequest request, int id)
{
DataSourceResult result = GetPersons(id).ToDataSourceResult(request);
return Json(result);
}
When I make function IEnumerable<SomeModel> GetPersons
as async Task<IEnumerable<SomeModel>> GetPersons
the binding function doesn't know ToDataSourceResult(), when I make this function as async too. If can be problem here, how can I fix it?
Please be patient with me, I am a newbie...
Ok, I resolve it.
An error wasn't in code above, problem was in async Task<IEnumerable<IRole>> GetRoles(string userId)
. This method works fine but it is not good for my code above.
Async getting roles looks like this:
public async Task<IEnumerable<IRole>> GetRolesAsync(string userId)
{
return await IdentityManager.Roles.GetRolesForUserAsync(userId);
}
But I had to use getting roles which is in code below.
I've made new method in IMembershipService - public IEnumerable<IRole> GetRoles(string userId)
(the first method renamed to GetRolesAsync) and looks like this:
public IEnumerable<IRole> GetRoles(string userId)
{
return AsyncHelper.RunSync(() => IdentityManager.Roles.GetRolesForUserAsync(userId));
}
This returns common IEnumerable<T>
. At least I can use my function GetPermissions in sql query. GetPermission() now looks like this:
private bool GetPermission(string email) {
var user = SomeMembershipService.GetUser(email);
var roles = SomeMembershipService.GetRoles(user.Id);
bool result = false;
if (roles != null) {
var adm = roles.FirstOrDefault(x => x.Name.Contains("Admin"));
result = adm != null;
}
return result;
}
in sql query I can use now this:
....
select new SomeModel
{
PersonName = c.FirstName + " " + c.LastName,
IsAdmin = GetPermission(c.Email) // <-- This
}
....
thanks to all, especially Jeroen, who tried to help.