使用ASP.NET WebAPI 3 OData Controller进行KendoUI Grid Batch编辑

时间:2016-03-09 08:07:41

标签: c# asp.net-web-api kendo-grid odata

我想使用ASP.NET WebAPI OData Controller使用KendoUI网格的批量编辑功能。到目前为止,我已经能够进行简单的CRUD操作,但我无法弄清楚如何进行批量创建/更新/删除操作。在批处理模式下,网格会发送一个操作请求,并将所有受影响的记录作为列表发送。

例如,服务器上用于非批处理操作的代码如下所示:

    public IHttpActionResult Post(Entity entity)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        DataStore.Create(new List<Entity >() { entity});

        return Created(entity);
    }

客户端传输部分如下所示:

 create: {
          url: ConfigData.BaseUrl + "api/ChartOfAccounts",
          type: "post",
          dataType: 'json'
         }

但是对于批量编辑模式,服务器端的签名应该类似于

 public IHttpActionResult Post(List<Entity> entities)

然而,我无法使其发挥作用。可以在带有OData的ASP.NET WebAPI中使用上述签名吗?

我应该使用自定义操作还是有其他方法来处理此问题?剑道论坛不太有帮助。

2 个答案:

答案 0 :(得分:1)

您应考虑使用批量请求,而不是创建自定义操作。在批处理请求中,您可以将多个操作组合到一个HTTP请求中,OData将在一次调用中处理所有请求。您不必更改现有的OData服务代码,也不需要执行以下操作。

public IHttpActionResult Post(List<Entity> entities)

要启用批量请求,只需为批量请求添加新路由,如下所示 -

HttpServer server = new HttpServer(configuration);
configuration.Routes.MapHttpBatchRoute(
    routeName:"batch",
    routeTemplate:"api/$batch",
    batchHandler:new DefaultHttpBatchHandler(server));
configuration.Routes.MapHttpRoute("api", "api/{controller}/{id}", new { id = RouteParameter.Optional });

启用批处理请求后,您可以在单个POST请求中组合所有实体,OData将逐个处理它们。请详细了解请求正文的外观 -
http://www.odata.org/documentation/odata-version-3-0/batch-processing/

答案 1 :(得分:1)

Grid绑定到OData时没有内置的批量编辑支持。这可以使用第三方库来实现。对于下面的示例,我将使用Batch.js by Pavel Volgarev

  

请注意,我还使用了Kendo UI DataSource的实验transport.submit成员。这已经包含了很长一段时间,但将在6月即将发布的服务版本中正式发布。

Kendo UI Dojo

中提供了一个可运行的示例但没有功能后端的示例
<div id="grid"></div>
<script>
  $(document).ready(function () {
    // The methods below create an entry in the requests array for the given operation
    function queueCreated(requests, items) {
      for (var i = 0; i < items.length; i++) {
        requests.push({
          url: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Customers",
          type: "POST",
          data: items[i]
        });

        // Assign temporary IDs as placeholders
        items[i].ContactID = kendo.guid();
      }
    }

    function queueUpdated(requests, items) {            
      for (var i = 0; i < items.length; i++) {
        requests.push({
          url: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Customers/" +
          items[i].CustomerID,
          type: "PUT",
          data: items[i]
        });
      }            
    }

    function queueDestroyed(requests, items) {            
      for (var i = 0; i < items.length; i++) {
        requests.push({
          url: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Customers/" +
          items[i].CustomerID,
          type: "DELETE"
        });
      }            
    }

    $("#grid").kendoGrid({
      dataSource: {
        type: "odata",
        batch: true,
        transport: {
          // Not an official feature, but it's close to being one
          submit: function(e) {
            var requests = [];

            // We get all batched operations in e.data
            queueCreated(requests, e.data.created);
            queueUpdated(requests, e.data.updated);
            queueDestroyed(requests, e.data.destroyed);

            // Check out the network tab on "Save Changes"
            $.ajaxBatch({
              // Not that this service doesn't actually support batching :(
              url: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Batch",
              data: requests
            })
              .done(function() {
              e.success(e.data.created, "create");
              e.success([], "update");
              e.success([], "destroy");
            })
              .fail(function() {
              e.error({});
            });
          },
          read: function(e) {
            var data = kendo.data.transports.odata.parameterMap(e.data, "read");
            $.ajax({
              url: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Customers",
              dataType: "jsonp",
              data: data,
              jsonp: "$callback"
            })
              .done(e.success)
              .fail(e.error);
          }
        },
        schema: {
          model: {
            id: "CustomerID",
            fields: {
              "ContactName": { type: "string" }
            }
          }
        },
        pageSize: 20
      },
      height: 550,
      editable: "incell",
      toolbar: ["save", "create"],
      groupable: true,
      sortable: true,
      pageable: {
        refresh: true,
        pageSizes: true,
        buttonCount: 5
      },
      columns: [{
        field: "ContactName",
        title: "Contact Name",
        width: 240
      }, {
        field: "ContactTitle",
        title: "Contact Title"
      }, {
        field: "CompanyName",
        title: "Company Name"
      }, {
        field: "Country",
        width: 150
      }, {
        command: ["destroy"]
      }]
    });
  });
</script>