REST WCF数据服务的简单示例
本文关键字:简单 服务 WCF 数据 REST | 更新日期: 2023-09-27 18:27:14
我需要开发两个站点之间的数据传输,并相信使用我们的.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.svc
的code-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)
。
如果需要处理授权,请从AuthenticationHttp头行获取用户名和密码,其中包含:Request.Params["HTTP_AUTHORIZATION"]
,它是base64编码的。然后,您将需要使用HTTPS的安全连接,HTTPS在传输(TCP)级别加密整个HTTP数据包,包括HTTP标头。
要返回HTTP状态代码和/或错误消息,只需在页面中添加一个常规的asp文本控件。如果您希望RESTful返回数据结构,也可以通过篡改Response
对象来替换整个http响应。
使用Telerik fiddler
工具,可以很容易地制作一个HTTP数据包来测试您的简单REST服务器页面。
为了让客户端使用更好的URL访问您的页面,您需要使用一些URL重写。这包括下载和安装重写模块,并将规则添加到web.config中
当然,使用一个好的框架会很好,但基本实现是研究REST的一个很好的方法,并且已经比我所在行业中经常看到的旧的FTP数据交换方法有了很大的改进。
感谢Mason,他帮助我认识到WCF DS只是众多框架中的一个。