without webapi pagesize microsoft framework c# entity-framework odata asp.net-web-api

c# - webapi - odata web api without entity framework



Propiedad de solo lectura OData (3)

Ahora hay una manera suave de hacer esto: construir un contrato entre el cliente y el servidor utilizando anotaciones.

En el vocabulario básico del estándar V4 , hay un término tal:

<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>

En Web API OData, en WebConfig.cs, escribe dicho código para agregar dicha anotación a su propiedad:

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)));

Luego en tus datos, se verá algo como esto:

<Annotations Target="V4Service.Models.Person/FullName"> <Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/> </Annotations>

A través de los pasos anteriores, el servicio anuncia que la propiedad FullName en la entidad Person es calculada por el servicio. Luego, en los métodos de controlador para solicitudes POST y PATCH, puede tener su propia lógica de ignorar cualquier valor enviado por el cliente para la propiedad FullName y calcular la suya propia.

No estoy seguro de qué cliente está utilizando. Si está utilizando OData Client para .NET , nuestro soporte para obtener valores de anotación estará en nuestra próxima versión. Si no le importa usar EdmLib directamente, el soporte de recuperación de valor de anotación ya se ha agregado.

Tengo una aplicación WebAPI 2.2 con OData V4. También estoy usando EF 6.1.

En una de mis entidades tengo una propiedad calculada:

public class Person { public string FirstName { get; set; } public string LastName { get; set; } // Calculated Property - No setter public string FullName { get { return FirstName + " " + LastName; } }

Para poder proporcionar la propiedad calculada a mis clientes, debo registrarme en el Modelo 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(); }

Entonces, cuando obtengo mis datos en el lado del cliente, cada objeto tiene la propiedad Calculado.

Sin embargo, cuando trato de Crear (POST) un nuevo elemento o Actualizar (PUT) uno existente, mi acción no reconoce el elemento y genera un error que dice que no encuentra el "método establecido" para la propiedad.

Leí un par de publicaciones sobre propiedades de solo lectura en OData (aparentemente no se admite) pero no encuentro la forma de usar OData con propiedades calculadas.

¿Algún consejo de cómo superar esta situación?


Podría usar una propiedad computada de la base de datos en lugar de una propiedad computada de la clase.

Este artículo describe las propiedades computadas de la base de datos y EF. Una diferencia que veo en su código de ejemplo en comparación con el artículo es que no tiene ningún establecedor en su propiedad. Si configura su propiedad para utilizar los accesores automáticos con un conjunto privado

public string FullName { get; private set; }

Luego cree la columna en la base de datos como una columna calculada.

ALTER TABLE dbo.Users ADD FullName AS FirstName + '' '' + LastName

Como una ventaja adicional, podrá consultar esta propiedad utilizando odata y Linq.


Tiene razón, OData no admite read-only properties en este momento.

Sin embargo, soporta read-only entities .

O bien, puede engañar a OData agregando un setter que no hace nada a su property .

public string FullName { get { return FirstName + " " + LastName; } set { // do nothing } }

Así es como configura una entity como de solo lectura:

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); } }