tutorial powerapps español ejemplos crear con aplicaciones .net odata asp.net-web-api asp.net-web-api-odata odata-v4

.net - powerapps - Cómo obtener Web API OData v4 para usar DateTime



powerapps ejemplos (11)

Ambos el siguiente trabajo con ODATA 4

  1. esta es la última actualización que veo con .Net 4.7 y Microsoft.Aspnet.ODATA 5.3.1

    $ filter = DateofTravel lt cast (2018-05-15T00: 00: 00.00Z, Edm.DateTimeOffset)

  2. esto también funciona, debe ser en este aaaa-mm-ddThh: mm: ss.ssZ

    $ filter = DateofTravel lt 2018-02-02T00: 00: 00.00Z

Tengo un modelo de datos bastante grande que quiero exponer utilizando Web API OData utilizando el protocolo OData V4.

Los datos subyacentes se almacenan en una base de datos de SQL Server 2012. Esa base de datos tiene muchas columnas DateTime.

Mientras lo conectaba recibí el error de que System.DateTime no es compatible.

Así que aquí está mi pregunta, ¿qué puedo hacer para que mis columnas DateTime se vean en el feed de OData?

NOTA: No puedo regresar y cambiar todas mis columnas a las columnas DateTimeOffset.

Traté de cambiar el tipo de columna en Entity Framework edmx, pero me dio este error:

La asignación de miembros especificada no es válida. El tipo ''Edm.DateTimeOffset [Nullable = False, DefaultValue =, Precision =]'' del miembro ''MyPropertyHere'' en el tipo ''MyProject.MyEntity'' no es compatible con ''SqlServer.datetime [Nullable = False, DefaultValue =, Precision = 3] ''del miembro'' MyColumnName ''en el tipo'' MyDataModel.Store.MyEntity ''.

(Básicamente, Syas dice que DateTime no es compatible con DateTimeOffset).

¿Acaso el equipo de Web API OData simplemente dejó fuera a todos los que necesitan usar el tipo de DateTime de SQL Server?

Actualización: he encontrado soluciones para esto, pero requieren actualizar el Modelo EF para que funcionen. Prefiero no tener que actualizar varios cientos de propiedades individualmente si puedo evitarlo.

Actualización: Este problema me ha hecho darme cuenta de que existen grandes fallas en la manera en que Microsoft administra sus productos OData. Hay muchos problemas, pero este es el más evidente. Hay grandes características que faltan en la API web OData. Transactions y el Transactions son dos de ellos. Estos dos elementos (que están en la especificación OData y estaban en Servicios de datos de WCF antes de que Microsoft los matara) son fundamentales para cualquier sistema real.

Pero en lugar de dedicar tiempo a esos puntos críticos en los que faltan funcionalidades incluidas en la Especificación OData, deciden dedicar su tiempo a eliminar la funcionalidad que fue muy útil para muchos desarrolladores. Representa la mala gestión para priorizar la eliminación de las características de trabajo sobre la adición de características muy necesarias.

Traté de discutir esto con el representante de Web API OData, y al final, obtuve un problema / boleto abierto que luego se cerró unos días después. Ese fue el final de lo que estaban dispuestos a hacer.

Como dije, hay muchos más problemas (no relacionados con DateTime, así que no los voy a enumerar aquí) con la administración de Web API OData. He sido un gran defensor de OData, pero los problemas evidentes con la administración de Web API OData nos han obligado a mí y a mi equipo / empresa a abandonarlo.

Afortunadamente, la API web normal se puede configurar para usar la sintaxis OData. Es más trabajo configurar sus controladores, pero al final funciona bien. Y es compatible con DateTime. (Y parece tener una administración que al menos puede evitar decisiones increíblemente malas).


Como uso una biblioteca para odata con angular, la investigué allí:

https://github.com/devnixs/ODataAngularResources/blob/master/src/odatavalue.js

Ahí puedes ver (javascript)

var generateDate = function(date,isOdataV4){ if(!isOdataV4){ return "datetime''" + date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2)+'':''+("0" + date.getSeconds()).slice(-2) + "''"; }else{ return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2)+'':''+("0" + date.getSeconds()).slice(-2) + "Z"; } };

Y la prueba espera (cfr. here )

$httpBackend.expectGET("/user(1)?$filter=date eq 2015-07-28T10:23:00Z")

Entonces este debería ser tu "formateo"

2015-07-28T10:23:00Z


Desafortunadamente, https://aspnetwebstack.codeplex.com/SourceControl/network/forks/johncrim/datetimefixes fork, dado por doesn`t realmente soporte DateTime.

Está el nuevo fork https://aspnetwebstack.codeplex.com/SourceControl/network/forks/kj/odata53datetime?branch=odata-v5.3-rtm basado en OData v5.3 RTM, donde las propiedades DateTime en entidades y tipos complejos son compatibles con las respuestas del servidor, las solicitudes POST / PUT / PATCH del cliente, las cláusulas $ orderby y $ filters, los parámetros de funciones y las devoluciones. Comenzamos a usarlo en el código de producción y respaldaremos este fork, hasta que el soporte de DateTime regrese en futuros lanzamientos oficiales.


Después de haber pasado un día frustrante tratando de hacer esto mismo, me encontré con la única forma en que podía hacer que funcionara. Queríamos poder filtrar por rangos de fechas usando OData y Web API 2.2, que no es un caso de uso poco común. Nuestros datos están en SQL Server y se almacenan como DateTime y estamos usando EF en la API.

Versiones:

  • Microsoft.AspNet.WebApi.OData 5.7.0
  • Microsoft.AspNet.Odata 5.9.0
  • Microsoft.OData.Core 6.15.0
  • Microsoft.OData.Edm 6.15.0
  • Microsoft.Data.OData 5.7.0

Fragmento de la entidad:

[Table("MyTable")] public class CatalogueEntry { [Key] public Guid ContentId { get; set; } [StringLength(15)] public string ProductName { get; set; } public int EditionNumber { get; set; } public string Purpose { get; set; } public DateTime EditionDate { get; set; } }

WebApiConfig

public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapODataServiceRoute("ProductCatalogue", "odata", GetImplicitEdm()); // Web API routes config.MapHttpAttributeRoutes(); config.Filters.Add(new UnhandledExceptionFilter()); var includeVersionHeaders = ConfigurationManager.AppSettings["IncludeVersionHeaders"]; if (includeVersionHeaders != null && bool.Parse(includeVersionHeaders)) { config.Filters.Add(new BuildVersionHeadersFilter()); } config.SetTimeZoneInfo(TimeZoneInfo.Utc); } private static IEdmModel GetImplicitEdm() { ODataModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet<CatalogueEntry>("ProductCatalogue"); return builder.GetEdmModel(); } }

Fragmento del controlador:

public class ProductCatalogueController : EntitySetController<CatalogueEntry, string> { [EnableQuery] public override IQueryable<CatalogueEntry> Get() { return _productCatalogueManager.GetCatalogue().AsQueryable(); } protected override CatalogueEntry GetEntityByKey(string key) { return _productCatalogueManager.GetCatalogue().FirstOrDefault(c => c.ContentId.ToString() == key); } }

Aquí está el bit mágico: vea la parte inferior de esta página de MSDN bajo el encabezado ''Hacer referencia a diferentes tipos de datos en expresiones de filtro'' y encontrará una nota que dice:

Los valores de DateTime deben estar delimitados por comillas simples y precedidos por la palabra datetime , como datetime''2010-01-25T02: 13: 40.1374695Z '' .

http://localhost/Product-Catalogue/odata/ProductCatalogue?$filter=EditionDate lt datetime''2014-05-15T00:00:00.00Z''

Hasta ahora tenemos esto funcionando en Postman y ahora estamos construyendo el cliente que debería funcionar con este requisito para incluir ''datetime'' en el valor real. Estoy buscando usar Simple.OData.Client en un controlador MVC, pero incluso podemos decidir llamar directamente a la API desde el lado del cliente de JavaScript, dependiendo de la cantidad de refactorización que tengamos que hacer. También me gustaría que Swagger UI funcione usando Swashbuckle.OData, pero esto también está demostrando ser complicado. Una vez que haya hecho todo lo que tengo tiempo, publicaré una actualización con información útil para los que siguen porque me resultó muy frustrante que fuera tan difícil averiguar cómo hacer algo que aparentemente es un requisito simple. .


Estas soluciones y la de http://damienbod.wordpress.com/2014/06/16/web-api-and-odata-v4-crud-and-actions-part-3/ , tampoco funcionan. Funcionan solo de una manera, lo que significa que la invocación de odata datetimeoffset con el comando de filtro falla porque no forma parte del modelo.

Ya no puede filtrar ni ordenar por estos campos u obtener este error

/ Aas / Activities? $ Top = 11 & $ orderby = CreatedAt

Da este error:

"code":"","message":"An error has occurred.","innererror":{ "message":"The ''ObjectContent`1'' type failed to serialize the response body for content type ''application/json; odata.metadata=minimal''.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{ "message":"The specified type member ''CreatedAt'' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.","type":"System.NotSupportedException","stacktrace":"

Pero esto funciona porque se trata indirectamente:

/ Aas / AppUsers% 28102% 29 / AppUserActivities? $ Expand = Case & $ filter =% 28Reminder% 20ne% 20null% 20and% 20IsComplete% 20eq% 20null% 29 & $ top = 15 & $ orderby = Recordatorio & $ count = true

Recordatorio e Iscompleto son fecha y datetiem de la actividad a través de AppUserActivities.

Esto es extraño que eso funcione. ¿Alguien tiene una solución?

Me conecto a MySQL. No hay un descuento de fecha y hora.

Y todos se preguntan por qué nadie quiere desarrollar las tecnologías de Microsoft.


Finalmente, Web API OData v4 ahora admite el tipo DateTime en la versión 5.5. Obtenga el último paquete nuget y no olvide configurar esto:

config.SetTimeZoneInfo(TimeZoneInfo.Utc);

de lo contrario, la zona horaria de la propiedad dateTime se consideraría como zona horaria local.

Más información: ASP.NET Web API for OData V4 Docs DateTime support


Hasta el momento, DateTime no forma parte del estándar OASIS OData V4 y Web API no admite el tipo DateTime mientras es compatible con el tipo DateTimeOffset.

Sin embargo , OData Team está trabajando ahora para soportar el tipo DataTime. Espero que puedas usar el tipo DateTime en la próxima versión de la API web. Si no puede esperar al próximo lanzamiento, escribí un ejemplo basado en el blog . Espero que te ayude. Gracias.

Modelo

public class Customer { private DateTimeWrapper dtw; public int Id { get; set; } public string Name { get; set; } public DateTime Birthday { get { return dtw; } set { dtw = value; } } [NotMapped] public DateTimeOffset BirthdayOffset { get { return dtw; } set { dtw = value; } } } public class DateTimeWrapper { public static implicit operator DateTimeOffset(DateTimeWrapper p) { return DateTime.SpecifyKind(p._dt, DateTimeKind.Utc); } public static implicit operator DateTimeWrapper(DateTimeOffset dto) { return new DateTimeWrapper(dto.DateTime); } public static implicit operator DateTime(DateTimeWrapper dtr) { return dtr._dt; } public static implicit operator DateTimeWrapper(DateTime dt) { return new DateTimeWrapper(dt); } protected DateTimeWrapper(DateTime dt) { _dt = dt; } private readonly DateTime _dt; }

Contexto DB

public DbSet<Customer> Customers { get; set; }

EdmModel

ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet<Customer>("Customers"); var cu = builder.StructuralTypes.First(t => t.ClrType == typeof(Customer)); cu.AddProperty(typeof(Customer).GetProperty("BirthdayOffset")); var customer = builder.EntityType<Customer>(); customer.Ignore(t => t.Birthday); var model = builder.GetEdmModel(); config.MapODataServiceRoute("odata", "odata", model);

Controlador

Agregue el controlador OData de forma normal.

Prueba

Carga útil




Una solución alternativa es parchear el proyecto para que DateTime vuelva a permitirse; eso es lo que hice, puede obtener el código aquí si lo desea:

https://aspnetwebstack.codeplex.com/SourceControl/network/forks/johncrim/datetimefixes

También impulsé un paquete NuGet para que sea fácil de usar, puedes obtener el paquete usando la información aquí:

http://www.nuget.org/packages/Patches.System.Web.OData/5.3.0-datetimefixes

... No sé si está bien para mí publicar un paquete NuGet que contenga una biblioteca de Microsoft parcheada, espero que sea más fácil pedir perdón que permiso.

Tenga en cuenta que el elemento de trabajo para restaurar oficialmente la capacidad de utilizar DateTime en OData 4 se rastrea aquí: https://aspnetwebstack.codeplex.com/workitem/2072 Vote por el problema si desea verlo; aunque parece que está programado para 5.4-beta, por lo que debería venir uno de estos días.


public class Customer { private DateTimeWrapper dtw; public int Id { get; set; } public string Name { get; set; } public DateTime Birthday { get { return dtw; } set { dtw = value; } } [NotMapped] public DateTimeOffset BirthdayOffset { get { return dtw; } set { dtw = value; } } } var customer = builder.EntityType<Customer>(); customer.Ignore(t => t.Birthday); customer.Property(t => t.BirthdayOffset).Name = "Birthday";