Compartir a través de


Este artículo proviene de un motor de traducción automática.

OData y AtomPub

Cómo crear un servidor de AtomPub mediante el uso de servicios de datos de WCF

Chris Sells

Descargar el ejemplo de código

Si no está familiarizado con él, el protocolo de datos abierto (OData) es una cosa de belleza. OData (se describe en detalle en odata.org de ) se basa en el valor basado en HTTP de Atom para publicar los datos; AtomPub para crear, actualizar y eliminar datos; y Entity Data Model (EDM) de Microsoft para definir los tipos de datos.

Si dispone de un cliente de JavaScript, puede obtener los datos de back directamente en JSON en lugar del formato Atom, y si tiene cualquier otra forma, como Excel, Microsoft .NET Framework, PHP, AJAX y mucho más: hay bibliotecas de cliente para formar las solicitudes de OData y consumir OData respuestas. Si está utilizando .NET Framework en el servidor, Microsoft también proporciona una biblioteca de fácil de usar que se llama a los servicios de WCF de datos para exponer los tipos de .NET Framework o las bases de datos compatibles con Microsoft Entity Framework como OData orígenes. Esto facilita la tarea exponer los datos a través de Internet en un método basado en estándares y HTTP.

Dicho eso, hay algunas cosas que usted desea hacer con OData que no son bastante forma parte de la experiencia de out-of-box, por ejemplo, para integrar OData existente basado en Atom y AtomPub lectores y escritores. Eso es lo que vamos a probar.

Un Blog Simple

Por ejemplo, imagine let’s que estoy construyendo un sistema sencillo de creación de blogs (y, de hecho, se basa este trabajo me volver a escribir el sistema de administración de contenido en sellsbrothers.com). Soy un ventilador grande de la compatibilidad de primero del modelo de 2010 de Visual Studio, por lo que he creado un proyecto de ASP.NET MVC 2.0, se agrega un EDM de ADO.NET archivo denominado MyBlogDB.edmx y disponer de una entidad de correo, como se muestra en de figura 1.

image: A Post Entity Created in Visual Studio 2010

Figura 1 de entidad de correos A creadas en Visual Studio de 2010

Software de creación de blogs más complicado que desea realizar el seguimiento de más datos, pero los campos de figura 1 son los aspectos básicos. Cuando haga clic en la superficie del diseñador, puedo elegir generar bases de datos de modelo, que muestra el archivo SQL que se va a crear para mí (MyBlogDB.sql en este caso) y la instrucción SQL que se van a generar para crear la base de datos. Al hacer clic en Finalizar creará el archivo SQL y enlazar la base de datos a las entidades que se ha creado en el diseñador EDM. De figura 2 muestra los bits importantes de la instrucción SQL.

La figura 2 del código SQL resultantes de “ generar la base de datos del modelo ”

...
USE [MyBlogDB];
GO
...
-- Dropping existing tables
IF OBJECT_ID(N'[dbo].[Posts]', 'U') IS NOT NULL
    DROP TABLE [dbo].[Posts];
GO
...
-- Creating table 'Posts'
CREATE TABLE [dbo].[Posts] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [Title] nvarchar(max)  NOT NULL,
    [PublishDate] datetime  NULL,
    [Content] nvarchar(max)  NOT NULL
);
GO
...
-- Creating primary key on [Id] in table 'Posts'
ALTER TABLE [dbo].[Posts]
ADD CONSTRAINT [PK_Posts]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

Básicamente, sólo nos estamos creando una tabla de la entidad, como se esperaba y los campos de asignación de tipos de SQL. Tenga en cuenta que la PublishDate se establece en NULL, que no sea la predeterminada. Explícitamente elegí esa configuración en el diseñador EDM porque quería ser Aceptar no debe tener una fecha de publicación (algunas herramientas no proporcionan una forma predeterminada).

Para ejecutar este SQL y crear la base de datos es sólo cuestión de con el botón secundario en la instrucción SQL en el editor de texto de Visual Studio y elegir la ejecución de SQL. Le pedirá la información de conexión y el nombre de la base de datos. Debido a que se trata de una base de datos, deseará escribir el nombre nuevo, por ejemplo, MyBlogDB y haga clic en Aceptar para crearlo cuando se le pida. Cuando se creó la base de datos, puede explorar en el Explorador de servidores en la conexión que Visual Studio ha creado sólo para usted.

Para facilitar las pruebas, puede agregar datos directamente en la tabla haciendo clic en publicaciones y eligiendo mostrar datos de tabla, lo que proporcionará una cuadrícula pequeña, como se muestra en de figura 3.

image: The Show Table Data Grid Makes Testing Easier

La figura 3 de la cuadrícula de datos de la tabla de presentación facilita la realización de pruebas

Éste no la mejor experiencia en el mundo, pero en la edición es mejor que escribir instrucciones SQL hasta que tenemos una solución de edición de extremo a extremo hacia arriba y ejecutar (viene, continúe leyendo!).

Ahora que tenemos algunos datos, podemos hacerlo un poco de ASP.NET de codificación para mostrarla mediante la actualización HomeController.cs (lectura más información acerca de MVC en asp.net/mvc/ de ):

...
namespace ODataBloggingSample.Controllers {
  [HandleError]
  public class HomeController : Controller {
    MyBlogDBContainer blogDB = new MyBlogDBContainer();

    public ActionResult Index() {
      return View(blogDB.Posts);
    }

    public ActionResult About() {
      return View();
    }
  }
}

Aquí todos lo hice fue crear una instancia de la clase MyBlogDBContainer, que es la clase derivada de ObjectContext nivel superior creada a partir de nuestro archivo MyBlogDB.edmx para hacernos acceso nuestra base de datos nueva. (Si no está familiarizado con Entity Framework, debe: consulte msdn.com/data/aa937723 de ). Cuando se llama al método de índice de la clase HomeController, un usuario solicita la página principal de nuestra aplicación Web nueva, que se desea utilizar para mostrar nuestras nuevas entradas de blog, por lo que dirigir la colección de entradas de la base de datos a una instancia de la vista de Home/Index.aspx, que se ha modificado de este modo:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
    Inherits="System.Web.Mvc.ViewPage<IEnumerable<ODataBloggingSample.Post>>" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <% foreach (var post in Model) { %>
      <h1><%= post.Title %></h1>
      <div><%= post.Content %></div>
      <p><i>Posted <%= post.PublishDate %></i></p>
    <% } %>
</asp:Content>

A continuación, hemos cambiado la clase base para tener una colección del tipo de correos a generar (junto con la clase MyBlogDBContainer) para modelar nuestra tabla de entradas de blog. También se reemplaza el contenido con una instrucción foreach para mostrar el título de cada entrada, contenido y la fecha de publicación de la página de inicio.

Eso es lo único que necesitamos. Ahora cuando se ejecuta el proyecto (Depurar | Iniciar depuración), se inicia el explorador y se muestran las entradas de blog (un solo registra, a menos que haya colocado más que en la base de datos), como se muestra en de figura 4.

image: The Completed Web Page

La figura 4 de la página de Web completada

Ahora, dijimos que todos los elementos hasta este punto para que se podría saber esto: La razón que OData es fabuloso por lo tanto, es que, con un gesto del mouse (ratón) y dos batidos de mi teclado, se puede exponer una interfaz de programación completada a los datos que puedo tener acceso desde JavaScript, .NET Framework, PHP y mucho más. Para ver esta magia sucede, haga clic en el proyecto en el Explorador de soluciones, seleccione Agregar | nuevo elemento, elija el servicio de WCF de datos, elija un nombre (usé odata.svc) y haga clic en Agregar. Lo que obtendrá es un esqueleto de código en un archivo (odata.svc.cs en este caso), que se omite la seguridad de que ahora, nos gustaría realizar el siguiente aspecto:

using System.Data.Services;
using System.Data.Services.Common;
using ODataBloggingSample;

namespace ODataBloggingSample {
  public class odata : DataService<MyBlogDBContainer> {
    public static void InitializeService(DataServiceConfiguration config) {
      config.SetEntitySetAccessRule("*", EntitySetRights.All);
      config.DataServiceBehavior.MaxProtocolVersion =  
        DataServiceProtocolVersion.V2;
    }
  }
}

Tenga en cuenta que nos hemos iniciada en MyBlogDBContainer, nuestra clase de acceso de nivel superior de la base de datos, como el parámetro de plantilla a la clase DataService, que es el núcleo de servicios de datos de WCF en el servidor (consulte msdn.com/data/bb931106 de ). La clase DataService permite exponer fácilmente la base de datos a través de HTTP basado en el verbo de crear, leer, actualizar y eliminar operaciones (CRUD) que define en el protocolo OData. El tipo pasado a la DataService se examina para las propiedades públicas que exponen las colecciones. En nuestro ejemplo, la clase de contexto del objeto generado por el Entity Framework contiene la colección de elementos para exponer en el que se ajusta perfectamente a la Bill:

...
namespace ODataBloggingSample {
  ...
  public partial class MyBlogDBContainer : ObjectContext {
    ...
    public ObjectSet<Post> Posts {...}
   ...
  }

  ...
  public partial class Post : EntityObject {
    ...
    public global::System.Int32 Id { get { ... } set { ... } }
    public global::System.String Title { get { ... } set { ... } }
    public Nullable<global::System.DateTime> PublishDate { 
      get { ... } set { ... } }
    public global::System.String Content { get { ... } set { ... } }
    ...
  }
}

Tenga en cuenta que la MyBlogDBContainer generado expone un ObjectSet (que es simplemente un tipo de colección) llamada a entradas de blog que contiene las instancias del tipo de contabilización. Además, se define el tipo de contabilización para proporcionar la asignación entre los ID, Title, PublishDate y las propiedades de contenido a las columnas de base en la tabla de entradas de blog que creamos anteriormente.

Con odata.svc en su lugar, se puede navegar hasta el documento de servicio que expone nuestras propiedades de colección de contexto de objeto con el nombre del archivo de extremo de servicio de datos en la dirección URL, por ejemplo, localhost:54423/odata.svc:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<service xml:base="http://localhost:54423/odata.svc/" xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
    <workspace>
     <atom:title>Default</atom:title>
      <collection>
        <atom:title>Posts</atom:title>
      </collection>
    </workspace>
</service>

Todo este archivo se define mediante la especificación de AtomPub (ietf.org/rfc/rfc5023.txt ). Lleva un nivel más profundo, podemos ver nuestras entradas que se expone como un conjunto de entradas de Atom en localhost:54423/odata.svc/Posts, tal como se muestra en de figura 5.

La figura 5 de entradas de blog expuesto como un conjunto de entradas de Atom

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<feed xml:base="http://localhost:54423/odata.svc/"
  xmlns:d="https://schemas.microsoft.com/ado/2007/08/dataservices"
  xmlns:m=
    "https://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
  xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Posts</title>
  <id>http://localhost:54423/odata.svc/Posts</id>
  <updated>2010-03-15T00:26:40Z</updated>
  <link rel="self" title="Posts" href="Posts" />
  <entry>
    <id>http://localhost:54423/odata.svc/Posts(1)</id>
    <title type="text" />
    <updated>2010-03-15T00:26:40Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="Post" href="Posts(1)" />
    <category term="MyBlogDB.Post"
      scheme=
        "https://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:Id m:type="Edm.Int32">1</d:Id>
        <d:Title>My first blog post</d:Title>
        <d:PublishDate m:type=
          "Edm.DateTime">2010-03-14T00:00:00</d:PublishDate>
        <d:Content>Hi! How are you?</d:Content>
      </m:properties>
    </content>
  </entry>
</feed>

Este archivo es casi por completo de vainilla sin formato Atom (ietf.org/rfc/rfc4287.txt ) excepto para los identificadores URI basada en Microsoft, que se utilizan para colocar la funcionalidad de OData en Atom. En concreto, deberá observar el elemento “ propiedades ” dentro del elemento “ contenido ”. Estas propiedades se reconocerá como las mismas definidas anteriormente en la entidad de correo y la tabla de mensajes correspondiente. Estos datos se encuentran en la envoltura que define Atom y expone a través de los comentarios CRUD, que por sí mismos definen AtomPub y
permite la creación, lectura, actualización y eliminación mediante los métodos HTTP POST, GET, PUT y DELETE, respectivamente. El problema es que esto no es bastante normal-vainilla-Atom suficiente. Por ejemplo, si se navega a odata.svc/Posts en un lector de Atom, como Internet Explorer 8, el título y contenido Don provienen correctamente, tal como se muestra en de figura 6.

image: Viewing Blog Posts in Atom Reader Shows That Title and Content Are Missing

La figura 6 de Visualización de entradas de Blog en Atom Reader muestra que faltan título y objetos

Puede ver que los datos no existe (tenga en cuenta la fecha es correcta y se muestra la categoría), pero el título y el contenido de ninguna parte para verse. Porque los lugares donde Internet Explorer busca título y contenido: el “ título ” y “ contenidos ” elementos en cada entrada, lógicamente, no contienen lo que espera a que no existe. El elemento de título de “ ” está en blanco y el elemento “ content ” tiene un formato que Internet Explorer no reconoce. El formato que realmente desea que Internet Explorer para ver el siguiente aspecto:

<feed ...>
  <title type="text">Posts</title>
  <id>http://localhost:54423/atompub.svc/Posts</id>
  <updated>2010-03-15T00:42:32Z</updated>
  <link rel="self" title="Posts" href="Posts" />
  <entry>
    <id>http://localhost:54423/atompub.svc/Posts(1)</id>
    <title type="text">My first blog post</title>
    <updated>2010-03-15T00:42:32Z</updated>
    ...
    <content type="html">Hi! How are you?</content>
    <published>2010-03-14T00:00:00-08:00</published>
  </entry>
</feed>

Observe que el elemento de título de “ ” tiene lo que solía ser enterrado en la propiedad Título del elemento en el elemento “ contenido ”, “ propiedades ” OData “ contenido ” elemento se ha sobrescrito con la propiedad de contenido y se ha agregado el elemento “ publicado ” desde el valor de propiedad PublishDate. Cuando estos datos se ven en Internet Explorer, obtenemos algo muy similares a lo que nos gustaría tener, como se muestra en de figura 7.

image: Tweaking the XML Format Results in Correct Display of the Title and Content

La figura 7 de ajustar el formato XML de resultados en pantalla correcta del título y objetos

Debo mencionar que es sólo para la compatibilidad con herramientas de creación de blogs que nos interesa incluso. Internet Explorer no está esperando ver una lista de clientes o una factura, está esperando ver los títulos y publicar contenido HTML y de las fechas. A veces tiene sentido realizar esta asignación de listas de clientes y facturas, en cuyo caso Microsoft dispone de una característica de servicios de WCF de datos denominado “ fuentes descriptivo ” (consulte blogs.msdn.com/astoriateam/archive/ 2008/09/28/making-feeds-friendly.aspx de ). No muy hace todo lo que, sin embargo (en concreto, no reasignar el elemento de contenido de “ ” Atom), ya que el equipo de servicios de WCF de datos desea Asegúrese de que incluso “ descriptivo ” fuentes todavía funcionan con distintas bibliotecas de cliente. El objetivo es hacer que las fuentes OData descriptivo, no abandone OData en favor de AtomPub/Atom.

En este caso, sin embargo, nos estamos abandonar OData y sólo utiliza servicios de WCF de datos como el extremo AtomPub, lo que requiere una asignación entre Atom y OData, tal como se muestra en de figura 8.

image: Mapping Between Atom and OData

La figura 8 de la asignación entre Atom y OData

El truco es que, ¿cómo obtenemos esta asignación a suceder? Obviamente tenemos los datos, pero es necesario volver a asignarlo a las propiedades de Atom para que los lectores de Atom (y escritores) donde se guarda los datos inmediatamente. La razón para ello es por lo que los servicios de WCF de datos todavía puede realizar la asignación para los tipos de .NET Framework, o bien, mediante Entity Framework, nuestras bases de datos. Lo único que debemos hacer es una asignación de a la puerta poco de Atom/AtomPub de OData.

El ejemplo de código que acompaña este artículo tiene algo de código para insertar en la canalización WCF que permite a exactamente este tipo de transformación de datos de mensaje. Puede leer del corazón contenido (consulte ODataBlogging.cs), pero voy a mostrarle cómo usarlo.

En primer lugar, cree un nuevo extremo de servicios de WCF de datos, al igual que hizo antes, pero con un nombre diferente (usé atompub.svc). Enlazar la clase de contexto del objeto de nivel superior y exponga cualquier entidad establece que, al igual que, igual que antes, pero también etiqueta el servicio de clase con el ODataBloggingServiceBehavior, por ejemplo:

...
using ODataBlogging;

namespace ODataBloggingSample {
  [ODataBloggingServiceBehavior(typeof(MyBlogDBContainer))]
  [EntityAtomMapping("Posts", "PublishDate", "published")]
  public class atompub : DataService<MyBlogDBContainer> {
    public static void InitializeService(DataServiceConfiguration config) {
      config.SetEntitySetAccessRule("*", EntitySetRights.All);
      config.DataServiceBehavior.MaxProtocolVersion = 
        DataServiceProtocolVersion.V2;
    }
  }
}

Esto es la asignación de AtomPub/Atom que se incluyen en, por ejemplo, “ puesto, ” “ contenidos ” y “ publicados ” elementos, el correspondiente OData dar formato a través del elemento anidado “ propiedades ” dentro del elemento “ contenido ”. De forma predeterminada, si coinciden los nombres de las entidades (omitir el caso), a continuación, la asignación (y conversión de tipos) sólo sucederá. Por ejemplo, cuando una entidad se expone que contiene una propiedad de título (por ejemplo, la entidad de correos), se asigna al elemento de título de “ ” Atom.

Por otro lado, si no hay ninguna asignación automática, se puede reemplazar dicho comportamiento proporcionando una asignación explícita que se basa en el nombre de la entidad, como hemos hecho a la propiedad PublishDate para objetos de la colección de entradas de “ ” se asignan a la propiedad átomo “ publicada ”. Estos dos atributos son suficientes para activar nuestro OData avance en una fuente Atom, lo que nos proporciona la vista completa de los datos tal como se muestra en de figura 7.

Esta asignación no es unidireccional; admite todos los métodos HTTP, por lo que puede utilizar el protocolo AtomPub para crear, actualizar y eliminar elementos de la colección de elementos para exponer así como los lee. Esto significa que puede configurar una herramienta como Windows Live Writer (WLW), que es compatible con AtomPub como un API de blog, y utilizarlo para la edición de texto enriquecido de sus publicaciones. Por ejemplo, dado el extremo de atompub.svc en WLW, podría elegir Blogs | agregar la cuenta de blog y rellene las opciones siguientes en los cuadros de diálogo siguientes:

  • ¿Qué servicio de blog utiliza? Otro servicio de blog
  • Dirección Web de tu blog: http:// < servidor >>: << puerto >> /atompub.svc
  • Nombre de usuario: < nombreDeUsuario >> (es necesario y debe implementarse en su extremo AtomPub mediante técnicas estándar de HTTP)
  • Contraseña: < contraseña >>
  • Tipo de blog que estás utilizando: Átomo de protocolo de publicación
  • Dirección URL del documento de servicio: http:// < servidor >>: << puerto >> /atompub.svc
  • Sobrenombre de blog: << lo que desee >>

Haga clic en Finalizar y tiene un editor de texto enriquecido para la administración de las entradas de blog, como se muestra en de figura 9.

image: Atom/OData Mapping Facilitates Building a Rich Text Editor to Manage Your Blog Posts

La figura 9 de asignación Atom/OData facilita la creación de un editor de texto enriquecido para administrar los mensajes del Blog

Aquí nos hemos tomado el motor de servicios de datos, que es compatible con todas las funciones CRUD por las propiedades de embalaje en el elemento “ contenido ” Atom y ha hecho un poco de asignación para que se admiten sin formato Atom vieja y AtomPub, demasiado.

La biblioteca de ejemplo poco que utiliza para realizar este trabajo (que creé con Phani Raj, ingeniero de software de Microsoft en el equipo de servicios de WCF de datos), es el mínimo de la semana y que nunca va a ser todo lo que necesita para crear un blog real. Ésta es una lista de la parte superior de la cabeza de cosas que todavía necesita realmente admite sólo Atom y AtomPub:

  • Asignación de los subelementos del elemento del autor de Atom, como, por ejemplo, nombre, el identificador uri y el correo electrónico.
  • Las imágenes de control (aunque WLW permite para FTP, por lo puede ser suficiente).
  • Exposición de las capacidades que WLW reconoce estas características.

Si está interesado en Insertar este experimento aún más, Joe Cheng, un miembro del equipo WLW, ha escrito una serie de entradas de blog acerca del soporte técnico de AtomPub en WLW que inspiró en primer lugar de este trabajo: jcheng.wordpress.com/2007/10/15/How-WLW-Speaks-AtomPub-Introduction.

Que disfrute.

Chris Sells es un administrador de programas de Microsoft en la división de la plataforma Business. Ha escrito varios libros, como los realizados por coautores “ programación WPF ” (O’Reilly Media, 2007), “ Windows Forms 2.0 programación ” (Addison-Wesley Professional, 2006) y “ ATL Internals ” (Addison-Wesley Professional, 1999). En su tiempo libre, aloja varias conferencias y hace que sea una plagas de sí mismo en listas de discusión de equipo de producto de Microsoft. Obtener más información sobre ventas y sus distintos proyectos, están disponibles en sellsbrothers.comde .

Gracias al siguiente experto técnico para este artículo: Pablo Castro