1

I am getting a dynamic model like this-

var termDetail = await _context.Terms
                .Include(t => t.Parents).ThenInclude(p => p.Parent)
                .Include(t => t.Children).ThenInclude(c => c.Child)
                .Select(term => new
                {
                    Id = term.Id,
                    Name = term.Name,
                    ParentCount = term.Parents.Count(),
                    ChildCount = term.Children.Count(),
                    Parents = term.Parents.Select(p => new
                    {
                        Id = p.Parent.Id,
                        Name = p.Parent.Name,
                        ParentCount = p.Parent.Parents.Count(),
                        ChildCount = p.Parent.Children.Count()
                    }),
                    Children = term.Children.Select(c => new
                    {
                        Id = c.Child.Id,
                        Name = c.Child.Name,
                        ParentCount = c.Child.Parents.Count(),
                        ChildCount = c.Child.Children.Count()
                    })
                })
                .FirstOrDefaultAsync(m => m.Id == id);

I am passing it to view like this-

(In Controller)

ViewBag.term = termDetail;

(In View)

<dd>
    ....
    ....
    @ViewBag.term.Name
</dd>

If I debug, I am getting this-

debug

So, the value is actually passed from controller to view.

But I can't show it in view. I am getting this error-

An unhandled exception occurred while processing the request. RuntimeBinderException: 'object' does not contain a definition for 'Name'

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'Name'
   at CallSite.Target(Closure , CallSite , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at AspNetCore.Views_Terms_Details.ExecuteAsync() in D:\Education\0. Research\1. Knowledge-Base\Code\Asp.NetCore_3.1-PostGRE_Role-Claim_Management\Views\Terms\Details.cshtml:line 21
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ActionContext actionContext, IView view, ViewDataDictionary viewData, ITempDataDictionary tempData, String contentType, Nullable`1 statusCode)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext context, ViewResult result)
   at Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at WebMarkupMin.AspNetCore3.WebMarkupMinMiddleware.ProcessAsync(HttpContext context, Boolean useMinification, Boolean useCompression)
   at WebMarkupMin.AspNetCore3.WebMarkupMinMiddleware.ProcessAsync(HttpContext context, Boolean useMinification, Boolean useCompression)
   at WebMarkupMin.AspNetCore3.WebMarkupMinMiddlewareBase.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

enter image description here

I like to do it without creating a View Model.

Is it possible?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Abrar Jahin
  • 13,970
  • 24
  • 112
  • 161
  • Try it with out the `.Name`. What do you think `.Name` does? – Peter Smith Apr 04 '21 at 18:57
  • Well, when I am reproducing it is working for me.. Could you please share you IActionResult? – Burak Apr 04 '21 at 19:01
  • @Burak I have already provided that with screenshot- https://i.stack.imgur.com/itgq9.png – Abrar Jahin Apr 04 '21 at 19:13
  • @PeterSmith `@ViewBag.term.Name` is already tried but not working – Abrar Jahin Apr 04 '21 at 19:15
  • This is weird... What happens when you assign it to a variable in your ```.cshtml``` – Burak Apr 04 '21 at 19:16
  • I have added all screenshots friend @Burak It is happening because it is the general use-case for the `view-model`. But for fast coding, I don't like to use the `view-model`. If you know any alternate way, please suggest. Or if you can find a way to solve my error, that would be fine also. Thanks – Abrar Jahin Apr 05 '21 at 00:08
  • Hi @AbrarJahin, any updates about this case? I'd like to know if the solution I shared can help resolve the issue. – Fei Han Apr 13 '21 at 01:47
  • No update yet actually. I have defined a ViewModel and used the ViewModel. But I don't like to use the ViewModel, so I have asked this question – Abrar Jahin Apr 13 '21 at 01:53

1 Answers1

0

An unhandled exception occurred while processing the request. RuntimeBinderException: 'object' does not contain a definition for 'Name'

You can try to implement and use the following extension method "ToExpando" to convert your anonymous-types data.

public static class MyExtensions
{
    public static ExpandoObject ToExpando(this object anonymousObject)
    {
        IDictionary<string, object> expando = new ExpandoObject();

        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(anonymousObject.GetType()))
        {
            expando.Add(property.Name, property.GetValue(anonymousObject));
        }

        return (ExpandoObject)expando;
    }
}

In controller

ViewBag.term = termDetail.ToExpando();

Test Result

enter image description here

Fei Han
  • 26,415
  • 1
  • 30
  • 41