Getting error that “‘object’ does not contain a definition for ‘key'” while accessing the key property in Asp.Net

I had researched a lot but I am not able to understand why I am getting this error, while debugging I can see the value of key in “fgroup” but still it is throwing below error:-

{
    "Message": "An error has occurred.",

    "ExceptionMessage": "'object' does not contain a definition for 'key'",

    "ExceptionType": "Microsoft.CSharp.RuntimeBinder.RuntimeBinderException",

    "StackTrace": "   at CallSite.Target(Closure , CallSite , Object )rn   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)rn   at WEBAPINILAYAM.Controllers.HomeController.TempMethod(List`1 firstRecord, List`1 secoudRecord)rn   at WEBAPINILAYAM.Controllers.HomeController.<GetUserList>d__1.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__1`1.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()"

}

Kindly find my Code Below:-

 var flatuser = await (from f in DatabaseContext.FlatUserDetails
                                  where f.SocietyCode.Equals(SocietyCode)                                   
                                  select new
                                  { 
                                      userName = f.Users.UserName,
                                      fullName = f.Users.FullName,
                                      phoneNumber = f.Users.PhoneNumber,
                                      email = f.Users.Email,                       
                                      flatNumber = f.FlatDetails.FlatNumber,
                                      buildingNumber = f.BuildingDetails.BuildingNumber

                                  }).GroupBy(x => x.userName).ToListAsync<dynamic>();

  foreach (var fgroup in flatuser)
    {
                                
                String k = fgroup.key;  // Getting error at this line

  foreach(var temp in fgroup)
           {
                 // accessing the object

            }

     }

Kindly help me I want to get the value of the key.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The reason of your error is the use of your .ToListAsync<dynamic>();

The solution is to end your query with .ToListAsync();

… all the variables inside select are of anonymous type. If I remove dynamic then I have to first create a model class and create its object in the query with the defined property

That’s only true if you want to return the fetched data from a method. If you only want to put them in an anonymous type, and use immediately after it, like you did in your code, then you can use your anonymous type.

Let do this with a simple example. Let’s create a Customer, a sequence of Customers and a GroupbBy.

Just do this in a simple console program:

class Program
{
    static void Main(string[] args)
    {
        var flatUsers = new []
        {
            new {Id=1, UserName="A", FullName="A B"},
            new {Id=2, UserName="B", FullName="B C"},
            new {Id=3, UserName="C", FullName="D E"},
            new {Id=4, UserName="A", FullName="A E"},
            new {Id=5, UserName="C", FullName="C D"},
            new {Id=6, UserName="D", FullName="D E"},
            new {Id=7, UserName="A", FullName="A D"},
            new {Id=8, UserName="B", FullName="D F"},
       };

In visual studio, if you hove your mouse over variable flatUsers it will say that is is an array of some anonymous type.

Experiment with this. Add a ToList() and see what happens, or add a Select(flatUser => new {...} and see what the result is.

Make groups of flatUsers that have the same UserName:

var flatUsersGroupedByUserName = flatUsers.GroupBy(flatUser => flatUser.UserName);

Again: hover your mouse. Is says that the variable is an `IEnumerable<IGrouping<string, some anonymous type>>

Now can we use this anonymous type? Let’s try:

foreach (var flatUserGroup in flatUsersGroupedByUserName)
{
    Console.WriteLine("Flat users in group " + flatUserGroup.Key.ToString()
    foreach (flatUser in flatUserGroup)
    {
         Console.WriteLine("[{0}] {1} - {2} ", flatUser.Id, flatUser.UserName, flatUser.FullName);
    }
}

So, if you are creating an anonymous type, you can use it as long as you are in the same method.

You cannot return the anonymous type of a method: it needs a return type.

<return type needed here> GetFlatUserGroups (...);

Of course you could use List<dynamic> here as return type, but in that case it would be very difficult for users of your method to know what’s in the list. I’m not sure if that would be wise. Errors won’t be detected until run time. If you really can’t tell the callers of your method what’s in the return value, consider to return List and let your callers use reflection to find out what’s in it. But again: try to avoid this. The fact that you don’t want to type a class for your return value is not a good reason. Ask your project leader, and he will agree.

Summarized: please do use anonymous type. Do some experimenting to get acquainted with them. Anonymous types have full type checking. You will detect errors at compile time. Try to avoid using dynamic.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x