简体   繁体   中英

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

在此输入图像描述

THE PROBLEM

The problem arises when I use simple ODATA query

在此输入图像描述

ODATA-Expanding the dynamic property returns 404

在此输入图像描述

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

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/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM