Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET WebAPI: Dynamic object and OData service

I have an entity with a dynamic property

 public partial class Meeting  //partial class of POCO EF object
 {
       public dynamic UiPermissions { get; set; }
 }

In my web api, I have a service method that implements OData query

    [Queryable(MaxExpansionDepth = 5)]
    [HttpGet("users/{id}/meetings")]
    public IEnumerable<Meeting> GetUserMeetings(int id)
    {
        var meetings = _meetingRepository.GetUserMeetings(id);

        // populate dynamic UiPermission
        meetings.SetMeetingPermission(_permissionRepository, id);

        return meetings;
    }

I populate the dynamic property with ExpandoObject as IDictionary

 public static class PermissionExtensions
{
    public static void SetMeetingPermission(this IEnumerable<Meeting> meetings, IPermissionRepository permissionRepository, int userId)
    {
        // get properties to be created from database table 
        var permissions = permissionRepository.GetAll();

        // create a dynamic object
        var uiPermission = new ExpandoObject() as IDictionary<string, Object>;
        permissions.ToList().ForEach(p => uiPermission.Add(p.Code, false));

       ....

    }

A simple call on the API service yields perfect result

enter image description here

THE PROBLEM

The problem arises when I use simple ODATA query

enter image description here

ODATA-Expanding the dynamic property returns 404

enter image description here

Stack Trace of the error (actually, the 404 response)

{"$id":"1","Message":"The query specified in the URI is not valid.","ExceptionMessage":"Property 'UiPermissions' is not a Navigation Property.","ExceptionType":"Microsoft.Data.OData.ODataException","StackTrace":"   at Microsoft.Data.OData.Query.SyntacticAst.ExpandBinder.GenerateExpandItem(ExpandTermToken tokenIn)\r\n   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()\r\n   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)\r\n   at Microsoft.Data.OData.Query.SyntacticAst.ExpandBinder.Bind(ExpandToken tokenIn)\r\n   at Microsoft.Data.OData.Query.ODataUriParser.ParseSelectAndExpandImplementation(String select, String expand, IEdmEntityType elementType, IEdmEntitySet entitySet)\r\n   at System.Web.Http.OData.Query.Validators.SelectExpandQueryValidator.Validate(SelectExpandQueryOption selectExpandQueryOption, ODataValidationSettings validationSettings)\r\n   at System.Web.Http.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\r\n   at System.Web.Http.QueryableAttribute.ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)\r\n   at System.Web.Http.QueryableAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)\r\n   at System.Web.Http.QueryableAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)"}

Additional

in the WebApiConfig, i have this line about json serializer

 public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
       ...
        var json = config.Formatters.JsonFormatter;
        json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
        config.Formatters.Remove(config.Formatters.XmlFormatter);

       ...
    }
}

Can anybody point out what I am missing here? TIA

like image 221
Linc Abela Avatar asked Nov 12 '22 18:11

Linc Abela


1 Answers

dynamic type is not supported by default because assigned value type is not known. So type is unkown and serialization provider too.

This link may solve your problem. http://loosexaml.wordpress.com/2011/01/01/wcf-serialization-of-dlr-dynamic-types/

like image 125
Omer Faruk Zorlu Avatar answered Nov 15 '22 07:11

Omer Faruk Zorlu