ASP.NET MVC4中调用WEB API的四个方法

 

Web API控制器的编码

  接下来,我们对已经生成了框架的Web控制器进行完善其中的代码,代码如下:

   public class CustomersController : ApiController

  {

  // Select All

   public IEnumerable Get()

  {

  NorthwindEntities db = new NorthwindEntities();

  var data = from item in db.Customers

  orderby item.CustomerID

   select item;

  return data.ToList();

  }

  // Select By Id

   public Customer Get( string id)

  {

  NorthwindEntities db = new NorthwindEntities();

  var data = from item in db.Customers

  where item.CustomerID == id

   select item;

  return data.SingleOrDefault();

  }

  //Insert

   public void Post(Customer obj)

  {

  NorthwindEntities db = new NorthwindEntities();

  db.Customers.AddObject(obj);

  db.SaveChanges();

  }

  //Update

   public void Put( string id, Customer obj)

  {

  NorthwindEntities db = new NorthwindEntities();

  var data = from item in db.Customers

  where item.CustomerID == id

   select item;

  Customer old = data.SingleOrDefault();

  old.CompanyName = obj.CompanyName;

  old.ContactName = obj.ContactName;

  old.Country = obj.Country;

  db.SaveChanges();

  }

  //Delete

   public void Delete( string id)

  {

  NorthwindEntities db = new NorthwindEntities();

  var data = from item in db.Customers

  where item.CustomerID == id

   select item;

  Customer obj = data.SingleOrDefault();

  db.Customers.DeleteObject(obj);

  db.SaveChanges();

  }

  }

  其中,Get()方法返回了Customers表中的所有数据,是以LIST列表的形式返回的。customer表中的主键为CustomerId列,并且是字符串类型,因此,另外的一个get带参数的方法,是根据传入的ID参数返回了某一个customer的对象实例。

  Post()方法则接收一个Customer对象作为参数,并且将其新增到数据表中去,同样,Put()方法中,接收一个customerid,然后在数据表中找出该customer对象,为该customer对象的属性重新赋值,然后再保存;最后Delete方法根据传入的CustomerID参数删除数据表中的数据并保存。


  从浏览器中访问WEB API

  在通过普通页面作为客户端访问Web API前,首先在浏览器中通过输入地址的方法先测试一下,如下图:

 注意的是,访问API的方式为:localhost/api/customers,在实际中将要根据情况替换合适的端口,默认所有的WEB API都是通过/api根目录的方式访问的,该路由是在Global.asax下进行定义,如下:

   public static void RegisterRoutes(RouteCollection routes)

  {

  ...

  routes.MapHttpRoute(

  name: " DefaultApi ",

  routeTemplate: " api/{controller}/{id} ",

  defaults: new { id = RouteParameter.Optional }

  );

  ...

  }

  因此,现在由于我们的WEB API控制器是customers,因此如何要得到某个顾客的信息,可以如下的方式访问:

  /api/customers/ALFKI


  创建自定义JSON格式化器

  在通过浏览器去访问WEB API时,默认的显示方式是XML。Web API框架会自动根据访问客户端的不同从而返回不同的格式的数据。现在,大多数情况下,用户希望返回的格式数据是JSON形式。然而,在本文写作时,使用默认的Web API提供的JSON格式化处理器以及Entity Framework搭配工作时,会出现一些小BUG.The entities of the EF data model have IsReference property of DataContractAttribute set to True.EF EF数据模型的实体将DataContractAttribute中的IsReference属性设置为true,如下:

   ...
[Serializable()]
[DataContractAttribute(IsReference= true)]
public partial class Customer : EntityObject
{
...
}

  默认情况下,Web API使用的是DataContractJsonSerializer类进行JSON序列化。但默认的JSON序列化类不能处理这样的实体类,并且在运行期间抛出如下异常:

  The type 'WebAPIDemo.Models.Customer' cannot be serialized to JSON because its IsReference setting is 'True'. The JSON format does not support references because there is no standardized format for representing references. To enable serialization, disable the IsReference setting on the type or an appropriate parent class of the type.

  为了克服则个问题,可以创建一个自定义的JSON格式化器。幸运的是,有第三方的JSON序列化器给我们选择使用,比如Json.NET。在本文中,将会简单介绍使用JSON.NET去完成序列化,完整的代码可以在附件中下载。

  一个自定义的序列化器主要是继承了MediaTypeFormatter的基类。我们编写的这个JSON序列化类为JsonNetFormatter,在使用前要确认你的应用工程中已经引用了Json.NET的类库,如下图:


  下面我们来看下JsonNetFormatter的基础代码:

     public class JsonNetFormatter : MediaTypeFormatter
{
...
}

  可以通过重写MediaTypeFormatter中的一些方法如下:

  protected override bool CanReadType(Type type)
{
...
}

protected override bool CanWriteType(Type type)
{
...
}

protected override Task< object> OnReadFromStreamAsync(Type type, Stream stream,
                                              
        HttpContentHeaders contentHeaders,
                                            
          FormatterContext formatterContext)
{
...
}

protected override Task OnWriteToStreamAsync(Type type, object value, Stream stream,
                                  
          HttpContentHeaders contentHeaders,
                                  
          FormatterContext formatterContext,
                            
                TransportContext transportContext)
{
...
}

  具体的代码在附件中可以详细查看。一旦创建了JSON序列化器后,就需要告诉Web API框架去替换使用原先默认的JSON序列化框架。可以在global.asx中实现:

  protected void Application_Start()
{
    HttpConfiguration config = GlobalConfiguration.Configuration;
    JsonSerializerSettings settings = new JsonSerializerSettings();
    settings.Converters.Add( new IsoDateTimeConverter());
    JsonNetFormatter formatter = new WebAPIDemo.Http.Formatters.JsonNetFormatter(settings);
    config.Formatters.Insert( 0, formatter);

    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    BundleTable.Bundles.RegisterTemplateBundles();
}

  其中请注意粗体字部分,这里创建了JSON自定义器的实例,并且增加到以HttpConfiguration类的配制的序列化配制集合中。

  这样,我们就可以开始在客户端中调用WEB API,并使用自定义的JSON解析器进行处理


当页面加载时,使用GET()方法去调出customer表的所有数据,而当使用INSERT,UPDATE,DELETE功能时,是通过jQuery去调用web api的。下面我们学习下通过jQuery去调用WEB API。

  首先,我们设计每一行的HTML代码,如下:

  <table id= " customerTable " border= " 0 " cellpadding= " 3 ">
    <tr>
        <th>Customer ID</th>
        <th>Company Name</th>
        <th>Contact Name</th>
        <th>Country</th>
        <th>Actions</th>
    </tr>
    <tr>
        <td><input type= " text " id= " txtCustomerId " size= " 5 "/></td>
        <td><input type= " text " id= " txtCompanyName " /></td>
        <td><input type= " text " id= " txtContactName " /></td>
        <td><input type= " text " id= " txtCountry " /></td>
        <td><input type= " button " name= " btnInsert " value= " Insert " /></td>
    </tr>
</table>

  首先要引入jQuery类库:

   <script src= " ../../Scripts/jquery-1.6.2.min.js " type= " text/javascript "></script>

  然后在jQuery中,通过$.getJSON的方法,调用WEB API,代码如下:

  $(document).ready(function () {

  $.getJSON("api/customers", LoadCustomers);

  });

  熟悉jQuery的朋友肯定明白,$.getJson方法中第一个参数是调用服务的地址,第二个参数是回调方法,这个回调方法LoadCustomers中,将展示服务端web api返回的数据,代码如下:

function LoadCustomers(data) {
    $( " #customerTable ").find( " tr:gt(1) ").remove();
    $.each(data, function (key, val) {
        var tableRow = ' <tr>' +
                         ' <td>' + val.CustomerID + '</td>' +
                         ' <td><input type="text" value="' + val.CompanyName + '"/></td>' +
                         ' <td><input type="text" value="' + val.ContactName + '"/></td>' +
                         ' <td><input type="text" value="' + val.Country + '"/></td>' +
                         ' <td><input type="button" name="btnUpdate" value="Update" />
                             <input type= " button " name= " btnDelete " value= " Delete " /></td> ' +
                         ' </tr>';
        $( ' #customerTable').append(tableRow);
    });

    $( " input[name='btnInsert'] ").click(OnInsert);
    $( " input[name='btnUpdate'] ").click(OnUpdate);
    $( " input[name='btnDelete'] ").click(OnDelete);
}

  在上面的代码中,首先移除所有表格中的行(除了表头外),然后通过jQuery中的each方法,遍历web api返回给前端的数据,最后展现所有的数据行。然后在Insert,update,delete三个按钮中都绑定了相关的方法函数,下面先看update的代码:

     function OnUpdate(evt) {
    var cell;
    var customerId = $(this).parent().parent().children().get( 0).innerHTML;
    cell = $(this).parent().parent().children().get( 1);
    var companyName = $(cell).find( ' input').val();
    cell = $(this).parent().parent().children().get( 2);
    var contactName = $(cell).find( ' input').val();
    cell = $(this).parent().parent().children().get( 3);
    var country = $(cell).find( ' input').val();

    var data = ' {"id":"' + customerId + '", "obj":{"CustomerID":"' + customerId +
               ' ","CompanyName":"' + companyName + '","ContactName":"' +
               contactName + ' ","Country":"' + country + '"}}';

    $.ajax({
        type: ' PUT',
        url: ' /api/customers/',
        data: data,
        contentType: " application/json; charset=utf-8 ",
        dataType: ' json',
        success: function (results) {
            $.getJSON( " api/customers ", LoadCustomers);
            alert( ' Customer Updated !');
        }
    })
}

  在上面的代码中,首先从每行的各个文本框中获得要更新的值,然后组织成JSON数据,

  其数据格式为包含两项,其中一项包含customer的ID,另外一个是新的customer实体对象,因为WEB API的PUT方法需要的是两个参数。

  然后通过jQuery的$.ajax方法进行调用web api,注意这里的type指定为put方法,并且注意编码为UTF-8,然后在回调方法success中,再此使用$.getJSON方法,获得更新后的最新用户列表。

  而Insert,Delete的方法代码如下:

     function OnInsert(evt) {
    var customerId = $( " #txtCustomerId ").val();
    var companyName = $( " #txtCompanyName ").val();
    var contactName = $( " #txtContactName ").val();
    var country = $( " #txtCountry ").val();
    var data = ' {"obj":{"CustomerID":"' + customerId + '","CompanyName":"' + companyName +
               ' ","ContactName":"' + contactName + '","Country":"' + country + '"}}';

    $.ajax({
        type: ' POST',
        url: ' /api/customers/',
        data: data,
        contentType: " application/json; charset=utf-8 ",
        dataType: ' json',
        success: function (results) {
            $( " #txtCustomerId ").val( ' ');
            $( " #txtCompanyName ").val( ' ');
            $( " #txtContactName ").val( ' ');
            $( " #txtCountry ").val( ' ');
            $.getJSON( " api/customers ", LoadCustomers);
            alert( ' Customer Added !');
        }
    })

}
function OnDelete(evt) {
    var customerId = $(this).parent().parent().children().get( 0).innerHTML;
    var data = ' {"id":"' + customerId + '"}';
    var row = $(this).parent().parent();

    $.ajax({
        type: ' DELETE',
        url: ' /api/customers/',
        data: data,
        contentType: " application/json; charset=utf-8 ",
        dataType: ' json',
        success: function (results) {
            $.getJSON( " api/customers ", LoadCustomers);
            alert( ' Customer Deleted!');
        }
    })

}

  读者要注意的是,在实际应用中,可以使用含有GET,PUT,DELETE前缀的方法名,比如

  GetXXXX(), PutXXXX(), PostXXXX()都是可以的,XXX是自定义的名称,WEB API框架依然会调用对应的GET,PUT和POST方法。

ASP API 接口接收与返回 是一个轻型的、安全的、跨网际的、跨语言的、跨平台的、跨环境的、跨域的、支持复杂对象传输的、支持引用参数传递的、支持内容输出重定向的、支持分级错误处理的、支持会话的、面向服务的高性能远程过程调用协议。 该版本直接解压后就可以使用,其 属于公共文件。不论是客户端还是服务器端都需要这些文件。 是客户端文件,如果你只需要使用客户端,那么只要有上面那些公共文件和这个文件就可以使用了,使用时,直接在你的程序包含 phprpc_client.php 就可以,公共文件不需要单独包含。 这三个文件是服务器端需要的文件。 其 dhparams 目录包含的是加密传输时用来生成密钥的参数 dhparams.php 是用来读取 dhparams 目录文件的类。 phprpc_server.php 是服务器端,如果你要使用 PHP 来发布 PHPRPC 服务,只需要包含这个文件就可以了。公共文件和 dhparams.php 都不需要单独包含。 PHP 4.3+、PHP 5、PHP 6 客户端要求开启 socket 扩展。 服务器端需要有 IIS、Apache、lighttpd 等可以运行 PHP 程序的 Web 服务器。 如果服务器端需要加密传输的能力,必须要保证 session 配置正确。 <?php include('php/phprpc_server.php'); //加载文件 function hello($name) { return'Hello ' . $name; } $server = new PHPRPC_Server(); //创建服务端 $server->add(array('hello', 'md5', 'sha1')); //数组形式一次注册多个函数 $server->add('trim'); //单一注册 $server->start(); //开启服务 ?> <?php include ("php/phprpc_client.php"); //加载文件 $client = new PHPRPC_Client('http://127.0.0.1/server.php'); //创建客户端 并连接服务端文件 echo$client->Hello("word"); //调用方法 返回 hello word ?> -------------------------------------------------- --------------------------------------------------- ------------------------------ 服务端其他说明: <?php include('php/phprpc_server.php'); //加载文件 function hello($name) { return'Hello ' . $name; } class Example1 { staticfunction foo() { return'foo'; } function bar() { return'bar'; } } $server = new PHPRPC_Server(); //创建服务端 $server->add('foo', 'Example1'); //静态方法直接调用 $server->add('bar', new Example1()); //非静态方法 需要实例化 //注册别名调用 $server->add('hello', NULL, 'hi'); //第三参数是函数的别名 客户端通过别名来调用函数 $server->add('foo', 'Example1', 'ex1_foo'); $server->add('bar', new Example1(), 'ex1_bar'); $server->setCharset('UTF-8'); //设置编码 $server->setDebugMode(true); //打印错误 $server->setEnableGZIP(true); //启动压缩输出虽然可以让传输的数据量减少,但是它会占用更多的内存和 CPU,因此它默认是关闭的。 $server->start(); //开启服务 ?> -------------------------------------------------- --------------------------------------------------- ---------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值