Breeze EdmBuilder自定义枚举序列化错误

时间:2014-12-07 03:59:29

标签: c# entity-framework asp.net-web-api odata breeze

我正试图轻松地将我的webapi与实体框架结合使用,但当我尝试查询使用自定义枚举的某个实体时,似乎卡住了。

我正在使用breeze EDMbuilder为我的元数据生成edm模型。

我的配置:

config.Routes.MapODataServiceRoute(
    routeName: "odata",
    routePrefix: "odata",
    model: EdmBuilder.GetEdm<Base.DAL.Entities.DbContextFixForEdm>(),
    batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer)
);

生成元数据,如果我查询odata / $ metadata,我会看到我的所有实体及其属性。

现在我遇到的问题如下。

我有一个非常基本的实体,名为ApiUserEntity,具有以下属性:

public class ApiUserEntity : BaseEntity
{
    public string Username { get; set; }
    public string Password { get; set; }
    public string Email { get; set; }
    public string Salt { get; set; }

    public ApiUserRole Role { get; set; }

    public ApiPermission Permission { get; set; }
}

一个简单的Odatacontroller get函数返回一个iquUable的ApiUserEntities:

// GET: odata/ApiUsers
[EnableQuery]
public IQueryable<ApiUserEntity> GetApiUsers(ODataQueryOptions<ApiUserEntity> opts)
{
    return _userService.GetUsers();
}

然而,每当我查询此方法时,我总会收到以下错误:

'Base.DAL.Entities.ApiUserRole' cannot be serialized using the ODataMediaTypeFormatter.

这个错误不仅仅是当我用微风查询它时,也是当我从浏览器访问该方法时。

在生成的元数据文件中,apiuserentity如下所示:

<EntityType xmlns:p5="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" Name="ApiUserEntity" p5:ClrType="Base.DAL.Entities.ApiUserEntity, Base.DAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <Key>
    <PropertyRef Name="Id"/>
    </Key>
    <Property xmlns:p7="http://schemas.microsoft.com/ado/2009/02/edm/annotation" Name="Id" Type="Edm.Int32" Nullable="false" p7:StoreGeneratedPattern="Identity"/>
    <Property Name="Username" Type="Edm.String" Nullable="false" MaxLength="255" FixedLength="false" Unicode="true"/>
    <Property Name="Password" Type="Edm.String" Nullable="false" MaxLength="300" FixedLength="false" Unicode="true"/>
    <Property Name="Email" Type="Edm.String" Nullable="false" MaxLength="255" FixedLength="false" Unicode="true"/>
    <Property Name="Salt" Type="Edm.String" MaxLength="255" FixedLength="false" Unicode="true"/>
    <Property Name="Role" Type="Base.DAL.Entities.ApiUserRole" Nullable="false"/>
    <Property Name="Permission" Type="Base.DAL.Entities.ApiPermission" Nullable="false"/>
    <Property Name="CreatedAt" Type="Edm.DateTime"/>
    <NavigationProperty Name="Domains" Relationship="Base.DAL.Entities.DomainEntity_Users" ToRole="DomainEntity_Users_Source" FromRole="DomainEntity_Users_Target"/>
</EntityType>

我注意到的主要是它为字符串和日期时间等常见类型添加了一个Edm前缀。但我的自定义枚举只是他们的完整命名空间。当我将自定义枚举的属性更改为int时,它会返回结果,但我真的想要使用这些枚举并将它们转换为整数并不是解决方案。

我正在发现它无法找到类型,并且不知道如何解析它,但这只是geussing。除此之外,我不知道如何解决它或我应该从这里去。在过去的几个小时里,我一直在为此而烦恼,没有结果。

1 个答案:

答案 0 :(得分:1)

我使用以下类来构建Edm模型:

public class ApiUserEntity // : BaseEntity
{
        public int Id { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string Email { get; set; }
        public string Salt { get; set; }

        public ApiUserRole Role { get; set; }

        public ApiPermission Permission { get; set; }
}

public enum ApiUserRole
{
        Admin,
        Guest
}

public enum ApiPermission
{
        Write,
        Read,
        WriteRead
}

这是元数据文档:

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:DataServices>
    <Schema Namespace="WebApplication1.Models" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityType Name="ApiUserEntity">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.Int32" Nullable="false" />
        <Property Name="Username" Type="Edm.String" />
        <Property Name="Password" Type="Edm.String" />
        <Property Name="Email" Type="Edm.String" />
        <Property Name="Salt" Type="Edm.String" />
        <Property Name="Role" Type="WebApplication1.Models.ApiUserRole" Nullable="false" />
        <Property Name="Permission" Type="WebApplication1.Models.ApiPermission" Nullable="false" />
      </EntityType>
      <EnumType Name="ApiUserRole">
        <Member Name="Admin" Value="0" />
        <Member Name="Guest" Value="1" />
      </EnumType>
      <EnumType Name="ApiPermission">
        <Member Name="Write" Value="0" />
        <Member Name="Read" Value="1" />
        <Member Name="WriteRead" Value="2" />
      </EnumType>
    </Schema>
    <Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityContainer Name="Container">
        <EntitySet Name="ApiUserEntitys" EntityType="WebApplication1.Models.ApiUserEntity" />
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

具有完整命名空间的自定义枚举类型是正确的。我认为你的问题是你的方法定义。请尝试将您的方法修改为:

[EnableQuery]
public IQueryable<ApiUserEntity> GetApiUsers()
{
    return _userService.GetUsers();
}

也就是说,不要同时为EnableQueryAttributeODataQueryOptions<ApiUserEntity> opts写一个方法。

修改后,这是我的样本测试:

GET~ / odata / ApiUserEntitys

   {
  "@odata.context":"http://localhost:40502/odata/$metadata#ApiUserEntitys","value":[
    {
      "Id":1,"Username":"UserName #1","Password":"Password #1","Email":"Email #1","Salt":"Salt E1","Role":"Admin","Permission":"WriteRead"
    },{
      "Id":2,"Username":"UserName #2","Password":"Password #2","Email":"Email #2","Salt":"Salt E2","Role":"Admin","Permission":"WriteRead"
    },{
      "Id":3,"Username":"UserName #3","Password":"Password #3","Email":"Email #3","Salt":"Salt E3","Role":"Admin","Permission":"WriteRead"
    },{
      "Id":4,"Username":"UserName #4","Password":"Password #4","Email":"Email #4","Salt":"Salt E4","Role":"Admin","Permission":"WriteRead"
    },{
      "Id":5,"Username":"UserName #5","Password":"Password #5","Email":"Email #5","Salt":"Salt E5","Role":"Admin","Permission":"WriteRead"
    }
  ]
}

希望它可以帮到你。感谢。