Primeiro você deve baixar o Update para o Visual Studio 2012 no link abaixo.
http://www.asp.net/vnext/overview/fall-2012-update
Este update contém algumas novidades, entre elas a integração entre o Entity Framework (Iqueryable) e o a WebApi (OData).
Segundo passo-> Criar uma classe Usuario que servira como modelo para efetuarmos o CRUD.
using
System;
using
System.Collections.Generic;
public
partial
class
Usuario
{
public
int
Id {
get
;
set
; }
public
string
Nome {
get
;
set
; }
public
string
Telefone {
get
;
set
; }
public
string
Email {
get
;
set
; }
public
string
Senha {
get
;
set
; }
}
Segundo passo -> Criar o DBContext do Entity Framework que servira de acesso a dados.
public
partial
class
Model1Container : DbContext
{
public
Model1Container()
:
base
(
"name=Model1Container"
)
{
}
public
DbSet UsuarioSet {
get
;
set
; }
}
Terceiro Passo -> Adicionar a string de conexão no web.config. O nome da string de conexão deve ser a mesma que está em seu DBContext, no nosso caso Model1Container.
<
add
name
=
"Model1Container" providerName="System.Data.SqlClient"
connectionString
=
"Data Source=DANIMAR-PC\SQLEXPRESS;Initial Catalog=Banco_Dados_Teste;Integrated Security=True"
/>
Quarto Passo -> Habilitar o Migrations atraves do Package Manager Console, o Migrations permite que o banco de dados seja criado automaticamente. Também podemos fazer o processo manualmente, mas neste caso vamos usar o automatico. Digite o comando no console.
Enable-Migrations –EnableAutomaticMigrations
Quinto Passo -> Adicionar o controller de Usuario que servirá como API para os métodos de Inserir e Listar usuários. Após isto iremos utilizar através de javascript os métodos deste controller.
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Net;
using
System.Net.Http;
using
System.Web.Http;
using
System.Web.Http.OData;
using
System.Web.Http.OData.Query;
namespace
ApiTeste.Controllers
{
public
class
UsuarioController : ApiController
{
private
Models.Model1Container db =
new
Models.Model1Container();
[HttpGet]
public
ODataResult Get(ODataQueryOptions options)
{
var results = (options.ApplyTo(db.UsuarioSet)
as
IQueryable);
var count = results.Count();
var limitedResults = results.Take(5).ToArray();
return
new
ODataResult(limitedResults,
null
, count);
}
// POST api/Teste
public
HttpResponseMessage PostUsuario(ApiTeste.Models.Usuario usuario)
{
if
(ModelState.IsValid)
{
db.UsuarioSet.Add(usuario);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, usuario);
response.Headers.Location =
new
Uri(Url.Link(
"DefaultApi"
,
new
{ id = usuario.Id }));
return
response;
}
else
{
return
Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
}
}
Aqui está a página que faz o uso da API.
<
div
id
=
"body"
>
<
section
class
=
"featured"
>
<
div
class
=
"content-wrapper"
>
<
hgroup
class
=
"title"
>
<
h1
>Lista de usuários do sistema!</
h1
>
</
hgroup
>
<
p
>
<
button
data-bind
=
"click: abrirCriacaoUsuario"
>Criar Novo Usuário</
button
>
</
p
>
</
div
>
</
section
>
<
section
class
=
"content-wrapper main-content clear-fix"
>
@using (Html.BeginForm("PostUsuario", "Usuario", FormMethod.Post, new { id = "formularioUsuario", style = "display:none;", data_bind = "submit: SalvarUsuario, with: Usuario" }))
{
<
div
>
<
label
>Nome:</
label
>
<
input
type
=
"text"
data-bind
=
"value:Nome"
/>
</
div
>
<
div
>
<
label
>Telefone:</
label
>
<
input
type
=
"text"
data-bind
=
"value:Telefone"
/>
</
div
>
<
div
>
<
label
>E-mail:</
label
>
<
input
type
=
"text"
data-bind
=
"value:Email"
/>
</
div
>
<
div
>
<
label
>Senha:</
label
>
<
input
type
=
"text"
data-bind
=
"value:Senha"
/>
</
div
>
<
div
>
<
button
type
=
"submit"
>Salvar Dados</
button
>
<
button
type
=
"reset"
data-bind
=
"click:$parent.cancelarInsercao"
>Cancelar</
button
>
</
div
>
}
<
hr
/>
<
span
>Nome</
span
><
input
type
=
"text"
data-bind
=
"value: filtro"
/><
button
data-bind
=
"click:buscarUsuarios"
>Pesquisar</
button
>
<
table
>
<
thead
>
<
tr
>
<
th
data-bind
=
"click: ordenarPorNome"
>Nome</
th
>
<
th
data-bind
=
"click: ordenarPorTelefone"
>Telefone</
th
>
<
th
data-bind
=
"click: ordenarPorEmail"
>E-mail</
th
>
</
tr
>
</
thead
>
<
tbody
data-bind
=
"foreach: ListaUsuarios"
>
<
tr
>
<
td
data-bind
=
"text:Nome"
></
td
>
<
td
data-bind
=
"text:Telefone"
></
td
>
<
td
data-bind
=
"text:Email"
></
td
>
</
tr
>
</
tbody
>
</
table
>
<
a
href
=
"#"
data-bind
=
"click:anterior"
>Página anterior</
a
>
<
a
href
=
"#"
data-bind
=
"click:proximo"
>Próxima página</
a
>
</
section
>
</
div
>
<
style
type
=
"text/css"
>
th
{
cursor: pointer;
}
</
style
>
@section scripts {
<
script
src
=
"~/Scripts/knockout-2.1.0.js"
></
script
>
<
script
type
=
"text/javascript"
>
$(document).ready(function () {
function UsuarioEntidade(data) {
this.Id = ko.observable(data.Id);
this.Nome = ko.observable(data.Nome);
this.Telefone = ko.observable(data.Telefone);
this.Email = ko.observable(data.Email);
this.Senha = ko.observable(data.Senha);
}
function Modelo() {
var self = this;
self.Usuario = ko.observable(new UsuarioEntidade({}));
self.ListaUsuarios = ko.observableArray([]);
self.order = ko.observable('Nome');
self.pagina = ko.observable(0);
self.filtro = ko.observable('');
self.buscarUsuarios = function () {
var url = '/Api/Usuario/Get?$orderby=' + self.order() + '&$skip=' + self.pagina() * 5;
if(self.filtro()!='')
url += "&$filter=startswith(Nome, '" + self.filtro() + "') eq true";
$.getJSON(url, null, function (data) {
var mapeado = $.map(data.Items, function (obj) { return new UsuarioEntidade(obj); });
self.ListaUsuarios(mapeado);
});
};
self.SalvarUsuario = function () {
var elemento = ko.toJSON(self.Usuario());
jQuery.ajax({
url: '/Api/Usuario/PostUsuario',
type: "POST",
data: elemento,
dataType: "json",
contentType: 'application/json; charset=utf-8',
success: function (result) {
debugger;
self.buscarUsuarios();
}
});
};
self.ordenarPorNome = function () {
self.order("Nome");
self.buscarUsuarios();
}
self.ordenarPorTelefone = function () {
self.order("Telefone");
self.buscarUsuarios();
}
self.ordenarPorEmail = function () {
self.order("Email");
self.buscarUsuarios();
}
self.proximo = function () {
self.pagina(self.pagina() + 1);
self.buscarUsuarios();
}
self.anterior = function () {
self.pagina(self.pagina() - 1);
if (self.pagina() <
0
)
self.pagina(0);
self.buscarUsuarios();
}
self.cancelarInsercao
=
function
() {
$('#formularioUsuario').slideUp();
};
self.abrirCriacaoUsuario
=
function
() {
self.Usuario(new UsuarioEntidade({}));
$('#formularioUsuario').slideDown();
};
}
var
model
=
new
Modelo();
ko.applyBindings(model);
model.buscarUsuarios();
});
}
A parte mais importante do código anterior é esta:
self.ListaUsuarios = ko.observableArray([]);
self.order = ko.observable('Nome');
self.pagina = ko.observable(0);
self.filtro = ko.observable('');
self.buscarUsuarios = function () {
var url = '/Api/Usuario/Get?$orderby=' + self.order() + '&$skip=' + self.pagina() * 5;
if(self.filtro()!='')
url += "&$filter=startswith(Nome, '" + self.filtro() + "') eq true";
$.getJSON(url, null, function (data) {
var mapeado = $.map(data.Items, function (obj) { return new UsuarioEntidade(obj); });
self.ListaUsuarios(mapeado);
});
};
Nas primeiras linhas temos nossas variaveis:
ListaUsuarios -> Guarda o resultado da consulta a API. Como ela é uma variavel observable do knockout cada vez que modificarmos, o html será gerado automaticamente.
order -> Guarda a ordem dos resultados.
pagina -> guarda a página atual.
filtro -> guarda o filtro para a consulta.
Dentro do método buscarUsuarios primeiro criamos a url com os parâmetros. Os parâmetros devem obedecer a definição ODATA.
A WebApi irá automaticamente converter nossos parâmetros para a variável do nosso método no controller (ODataQueryOptions options)
A web api atualmente suporta $orderby, $top, $skip e $filter. Vale a pena olhar a ultima documentação para verificar mas opções suportadas.
Você pode baixar o exemplo completo aqui
Obrigado.