【问题标题】:Can I consume a server-paged OData result in ASP.NET MVC?我可以在 ASP.NET MVC 中使用服务器分页的 OData 结果吗?
【发布时间】:2013-06-09 20:20:50
【问题描述】:

我想使用服务器分页的 OData 结果。

也就是说,JSON 代码包含一个元素

"__next": "http://server/odata.svc/table?$skiptoken=guid'4dda1cd9-7eff-423f-a314-08edf26a22e8'"

如何在 ASP.NET MVC 中执行此操作?我看到很多使用 OData 的示例,但没有一个处理分页数据。

我对 OData 和 MVC 都很陌生,所以请在答案中尽可能明确。 ;-)

【问题讨论】:

    标签: asp.net-mvc odata data-paging


    【解决方案1】:

    在 .NET 中使用 OData 的主要方式是使用 WCF 数据服务客户端库。在 Visual Studio 中,您可以右键单击一个项目,然后选择“添加服务引用”以开始使用。 “添加服务引用”在后台使用 WCF 数据服务客户端库。有关如何使用客户端库的一般信息,请在此处查看 MSDN 文档:http://msdn.microsoft.com/en-us/library/cc668772.aspx

    但请注意:您发布的 JSON(使用 "__next")是旧的 OData JSON 格式,有时称为“详细 JSON”。 WCF 数据服务客户端不支持这种格式。它只支持 Atom 和新的 JSON 格式。只要您的服务器能够支持 Atom 或新的 v3 JSON,这对您来说应该不是问题。

    至于您的实际问题,您可以在 QueryOperationResponse 对象上使用 .GetContinuation() 方法。例如:

    // "DemoService" is the auto-generated subclass of DataServiceContext created when you run "Add Service Reference"
    DemoService context = new DemoService(new Uri(<url to the service root>));
    var firstPage = context.Customers.Execute() as QueryOperationResponse<Customer>;
    var token = firstPage.GetContinuation();
    if (token != null)
        var secondPage = context.Execute<Customer>(token);
    

    显然,您可能希望将其变成一个循环,但这应该让您对 API 的使用有一个基本的了解。有关详细信息,请参阅 MSDN 上的此页面:http://msdn.microsoft.com/en-us/library/ee358711.aspx

    【讨论】:

    • 感谢 Jen,这对您有很大帮助!现在,您的示例一次收集所有结果页面,但是对于 Web 应用程序,向访问者提供继续链接不是更好吗?是否有任何现成的东西可以将续传地址绑定到视图中的分页链接?问题当然是延续链接不应该直接链接到 OData 流,而是链接到新的视图页面。
    • 这是一个很好的问题,但我没有很好的答案(部分原因是我对数据绑定不太熟悉)。我不知道除了 GetContinuation() 之外的任何延续机制,因此任何数据绑定的优点都必须是您在 GetContinuation() 之上编写的自定义代码。
    • 再想一想,我的猜测是没有现成的分页解决方案连接到 OData 延续,特别是因为延续是仅向前的。用户期望向前和向后分页。
    【解决方案2】:

    如果您使用 MVC 和 OData,我强烈建议您使用 Web API 来执行此操作,而不要弄乱 WCF 的所有 WCF 配置复杂性。这是您的控制器希望使用 MVC Web API 实现的功能:(非常简单且干净)。

    public class ProductController : EntitySetController<Product, int>
    {
        private readonly IUnitOfWork _unitOfWork;
    
        public ProductController(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }
    
        public override IQueryable<Product> Get()
        {
            return _unitOfWork.Repository<Product>().Query().Get();
        }
    
        protected override Product GetEntityByKey(int key)
        {
            return _unitOfWork.Repository<Product>().FindById(key);
        }
    
        protected override Product UpdateEntity(int key, Product update)
        {
            update.State = ObjectState.Modified;
            _unitOfWork.Repository<Product>().Update(update);
            _unitOfWork.Save();
            return update;
        }
    
        public override void Delete([FromODataUri] int key)
        {
            _unitOfWork.Repository<Product>().Delete(key);
            _unitOfWork.Save();
        }
    
        protected override void Dispose(bool disposing)
        {
            _unitOfWork.Dispose();
            base.Dispose(disposing);
        }
    }
    

    您会看到这篇文章,了解完整的演练http://blog.longle.net/2013/06/18/mvc-4-web-api-odata-entity-framework-kendo-ui-grid-datasource-with-mvvm

    【讨论】:

      猜你喜欢
      • 2013-03-12
      • 2015-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多