繁体   English   中英

REST WCF数据服务的简单示例

[英]Simple example with REST WCF Data Service

我需要开发两个站点之间的数据传输,并相信使用我们的.Net环境,RESTful实现将比使用FTP (ugh)更好。 但是,很难找到简单的示例,并且REST基础已被ADO.NET或许多巧妙的细节所遮盖,因此我试图使自己变得非常简单。 尽管如此,我仍需要一些原则和实施方面的帮助才能使其正常工作。

在VisualStudio Web项目中,我创建了一个新项WCF Data Service和一个数据类。 这是App_Code \\ WidgetRecord.cs:

//using System;
using System.Collections.Generic;//List
using System.Linq;//Where
//using System.Web;
using System.ServiceModel;//ServiceContract, OperationContract
using System.Runtime.Serialization;//DataContract
using System.Diagnostics;//Debug.WriteLine()

/// <summary>
/// Declare operations for a service
/// </summary>
[ServiceContract]
public interface IScandataService
{
    [OperationContract]
    List<WidgetRecord> List();

    [OperationContract]
    WidgetRecord Get(string Id);

    [OperationContract]
    int Put(string Id, string Desc);
}//end interface

/// <summary>
/// Fake database storage for testing the WCF Data Service
/// </summary>
public static class Database
{
    /// <summary>
    /// Fake database table
    /// </summary>
    public static List<WidgetRecord> WidgetTable = new List<WidgetRecord>() { 
    new WidgetRecord("0001", "red"), 
    new WidgetRecord("0002", "blue") };
}

/// <summary>
/// Implement operations for a service.
/// Representation of a table of widgets identified by scanned barcodes
/// </summary>
[DataContract]
public class WidgetRecord : IScandataService
{
    /// <summary>
    /// Row column: the id which could be a scanned barcode
    /// </summary>
    public string Id { get; set; }

    /// <summary>
    /// Row column: widget description.
    /// (Other columns could be a timestamp, location etc)
    /// </summary>
    public string Desc { get; set; }

    /// <summary>
    /// Dummy initializer, needed for ....(??)
    /// </summary>
    public WidgetRecord()
    {
    return;
    }

    /// <summary>
    /// Initializer to populate the fake database storage.
    /// Creates a new widget record.
    /// </summary>
    /// <param name="Id"></param>
    public WidgetRecord(string Id, string Desc)
    {
    this.Id = Id;
    this.Desc = Desc;
    return;
    }

    /// <summary>
    /// List all stored widgets
    /// </summary>
    /// <returns></returns>
    [OperationContract]
    public List<WidgetRecord> List()
    {
    return Database.WidgetTable;
    }

    /// <summary>
    /// Get info on an existing widget
    /// </summary>
    /// <param name="Id"></param>
    /// <returns></returns>
    [OperationContract]
    public WidgetRecord Get(string Id)
    {
    WidgetRecord sd = Database.WidgetTable.Where(n => n.Id == Id).FirstOrDefault();
    if (sd == null)
        Debug.WriteLine(string.Format("Found: {0} - {1}", sd.Id, sd.Desc));
    else
        Debug.WriteLine(string.Format("Not found: id={0}", Id));
    return sd;
    }

    /// <summary>
    /// Add a new widget to the database
    /// </summary>
    /// <param name="Id"></param>
    /// <param name="Desc"></param>
    /// <returns></returns>
    [OperationContract]
    public int Put(string Id, string Desc)
    {
    Database.WidgetTable.Add(new WidgetRecord(Id, Desc));
    Debug.WriteLine(string.Format("Put: {0} - {1}", Id, Desc));
    return 0;
    }
}//end class

在其他资源中,我经常看到带有字段成员的[DataContract]partial class ,以及带有方法的另一个类。 我不明白为什么要分开。 我只是想将ServiceContract接口用作数据类的基类。 无论如何,我的带有字段和方法的类可以正常构建。

我在WcfDataService.svccode-behind引用了上述类,即App_Code\\WcfDataService.cs

//using System;
using System.Data.Services;//IDataServiceConfiguration, EntitySetRights, ServiceOperationRights, DataServiceProtocolVersion
//using System.Data.Services.Common;
//using System.Collections.Generic;
//using System.Linq;
//using System.ServiceModel.Web;

public class WcfDataService : DataService<WidgetRecord>
{
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(IDataServiceConfiguration config)
    {
    // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
    // Examples:
    config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
    config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
    //config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    return;
    }
}//end class

所有这些都可以构建和运行,但是基本上什么也没做。

http://localhost:56794/website_for_rest/wcfDataService.svc/
-->
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<service xmlns="http://www.w3.org/2007/app" 
    xmlns:app="http://www.w3.org/2007/app" 
    xmlns:atom="http://www.w3.org/2005/Atom" 
    xml:base="http://localhost:56794/website_for_rest/WcfDataService.svc/">
    <workspace>
        <atom:title>Default</atom:title>
    </workspace>
</service>

我无法在URL中添加命令:

http://localhost:56794/website_for_rest/wcfDataService.svc/List
-->
page not found

我是否需要在web.config添加一些内容? VS给了我一个126行的web.config ,我不知道在哪里添加什么。

任何帮助表示赞赏。

答案(至少对我而言)是,最简单的REST示例不使用WCF数据服务,后者是简化REST的框架。 但是,如果您有大量数据和要执行的许多操作,则仅需要简化REST。 首先,为了进行简单的数据传输,您可以在没有框架的情况下进行REST。 而当您需要一个框架时,有很多选择,例如,请参阅此几十个框架的列表 首先,SOAP是较老的一种,并且由于过于复杂而失宠。 与Web服务相同。 显然,WCF数据服务(意在继承WS)将被Web API取代。

这种框架的问题在于它们可能会产生新的问题。 对我来说,必须升级我的工具是一个缺点,因为带有.Net3.5的VS2010不支持Web API。 升级是一件好事,但是如果它干扰了我正在从事的大型项目,那不是一件好事。 还是WCF数据服务对我来说还不清楚,它具有我不掌握的各种智能绑定,请参阅我的问题。 WCF DS存在许多示例,但已与ADO.NET结合使用,以帮助您处理大量表。

与Microsoft环境(VS,.Net,Asp)保持一致,从纯REST开始很容易。 只需创建一个空网页,例如Default.aspx ,然后在其Page_Load()开始编写REST功能。

要查看GET,PUT,POST等请求是否已到达,请查看Request.RequestType

要获取HTTP正文中的数据: Request.BinaryRead(Request.ContentLength)

如果您需要处理授权,请从Authentication Http标头行中获取用户名和密码,并带有: Request.Params["HTTP_AUTHORIZATION"] ,它是base64编码的。 然后,您将需要与HTTPS进行安全连接,以在传输(TCP)级别对整个HTTP数据包(包括HTTP标头)进行加密。

要返回HTTP状态代码和/或错误消息,只需在页面上添加常规的asp文本控件即可。 如果要RESTful返回数据结构,也可以用Response对象来替换整个http响应。

使用Telerik fiddler工具,可以很容易地制作一个HTTP数据包来测试您的简单REST服务器页面。

为了使客户可以使用更好的URL访问您的页面,您需要使用一些URL重写。 这涉及下载和安装重写模块,以及向您的web.config添加规则。 通过详细的解释和示例,这似乎是一个很好的来源。

当然,使用一个好的框架会很好,但是准系统的实现是研究REST的一种好方法,并且已经比旧的FTP交换数据的方法有了很大的改进,这在我的行业中仍然很常见。

感谢Mason,他帮助我意识到WCF DS只是众多框架之一。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM