OData只读属性

use*_*088 20 c# entity-framework odata asp.net-web-api

我有一个带OData V4的WebAPI 2.2应用程序.我也在使用EF 6.1.

在我的一个实体中,我有一个计算属性:

public class Person {
  public string FirstName { get; set; }
  public string LastName { get; set; }
  // Calculated Property - No setter
  public string FullName { 
    get {
      return FirstName + " " + LastName;
    }
} 
Run Code Online (Sandbox Code Playgroud)

为了向我的客户提供计算属性,我需要在OData模型中注册

    public static IEdmModel GetModel()
    {
        ODataModelBuilder builder = new ODataConventionModelBuilder();
        builder.Namespace = "NavigationServices";
        builder.EntityType<Person>;   
        builder.EntityType<Person>().Property(a => a.FullName); // Calculated Property
        ....

        return builder.GetEdmModel();
    }
Run Code Online (Sandbox Code Playgroud)

因此,当我在客户端获取数据时,每个对象都具有Calculated属性.

但是,当我尝试创建(POST)新元素或更新(PUT)现有元素时,我的操作无法识别该元素并生成错误,表明它没有找到该属性的"set方法".

我读了几篇关于OData中只读属性的帖子(显然不支持),但是我没有找到一种方法来使用OData和计算属性.

关于如何克服这种情况的一些建议?

Yi *_*SFT 7

现在有一种简单的方法可以做到这一点,即使用注释在客户端和服务器之间建立合同.

V4标准核心词汇表中,有一个这样的术语:

<Term Name="Computed" Type="Core.Tag" DefaultValue="true" AppliesTo="Property">
    <Annotation Term="Core.Description" String="A value for this property is generated on both insert and update"/>
</Term>
Run Code Online (Sandbox Code Playgroud)

在Web API OData中,在WebConfig.cs中,您编写此类代码以将此类注释添加到您的属性中:

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
var model = builder.GetEdmModel() as EdmModel;
model.SetVocabularyAnnotation(
    new EdmAnnotation(model.EntityContainer.FindEntitySet("People").EntityType().FindProperty("FullName"),
    new EdmTerm("Org.OData.Core.V1", "Computed", EdmPrimitiveTypeKind.Boolean),
    new EdmBooleanConstant(true)));
Run Code Online (Sandbox Code Playgroud)

然后在您的数据中,它看起来像这样:

<Annotations Target="V4Service.Models.Person/FullName">
    <Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/>
</Annotations>
Run Code Online (Sandbox Code Playgroud)

通过上述步骤,服务通告服务计算实体上的FullName属性Person.然后在POST和PATCH请求的控制器方法中,您可以拥有自己的逻辑,忽略客户端为FullName属性发送的任何值并计算您自己的值.

我不确定您使用的是哪个客户端.如果您正在使用OData Client for .NET,我们对获取注释值的支持将在我们的下一个版本中.如果您不介意直接使用EdmLib,则已添加注释值检索支持.


Mih*_*scu 6

你说得对,OData目前不支持read-only properties

但是,它支持read-only entities.

或者,您可以OData通过添加一个setter对您的property.

public string FullName
{ 
    get
    {
        return FirstName + " " + LastName;
    }
    set
    {
        // do nothing
    }
}
Run Code Online (Sandbox Code Playgroud)

这是您将 a 设置entity为只读的方式:

public class Northwind : DataService<NorthwindEntities>
{
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(DataServiceConfiguration config)
    {
        config.SetEntitySetAccessRule("Customers", EntitySetRights.AllRead);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Shivkumar 我刚刚在 web api 中尝试过这个,并且与空的 setter 以相同的方式工作。 (2认同)