现有.NETC#网站中RESTAPI的设计实践
我想让我们的用户登陆web服务器,将XML发布到我们的计算web服务器(处理XML数据)。登陆和计算web服务器仅通过internet连接,因此最好在计算web服务器上安装REST API,以便发布XML数据进行处理 老实说,我们都是软件工程师,但我们的能力在于算法处理,而不是web管道或ASP.NET本身。我环顾四周,看到WCF(Windows通信基金会)被踢了很多次。我担心WCF对于我们的情况可能过于复杂/设计过度 那么,对于我来说,让现有的基于web表单的处理网站接受发布的XML最简单的方法是什么?我想我需要注册一个URI(在web.config中?)作为API接口,在该URI上有一个处理程序并检索XML字符串-我只是不知道实现步骤:(.所以一个玩具示例或一个指向教程的指针就太棒了!) 顺便说一句,一旦我在处理服务器上有了XML字符串,我就成功了 谢谢现有.NETC#网站中RESTAPI的设计实践,c#,asp.net,xml,rest,post,C#,Asp.net,Xml,Rest,Post,我想让我们的用户登陆web服务器,将XML发布到我们的计算web服务器(处理XML数据)。登陆和计算web服务器仅通过internet连接,因此最好在计算web服务器上安装REST API,以便发布XML数据进行处理 老实说,我们都是软件工程师,但我们的能力在于算法处理,而不是web管道或ASP.NET本身。我环顾四周,看到WCF(Windows通信基金会)被踢了很多次。我担心WCF对于我们的情况可能过于复杂/设计过度 那么,对于我来说,让现有的基于web表单的处理网站接受发布的XML最简单的方
Sid如果您只想要尽可能薄的层,而不想弄乱管道或计算wcf,请创建一个asp.net web项目,然后右键单击并添加项选择一个httphandler,如果它给出从响应中提取xml字符串的命令。items[strings key]。将其作为ashx?key=您的xml字符串的url发布。好的,因此我阅读了一些文档以回答我自己的问题。基本上WCF REST已经发生了很大的变化。早期版本的设置非常复杂,但在最近的版本(.NET 4和WCF REST starter kit)中,配置开销要小得多 为了快速运行WCF REST,我基本上做了3件事
<%@ Application Codebehind="~/App_Code/Global.asax.cs" Inherits="MyBLL.Global" Language="C#" %>
步骤2a
如您所见,我将接口(抽象类)和实际实现拆分为两个单独的文件,以实现清晰的分离
TestInterface.cs
using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
[ServiceContract]
interface TestInterface
{
[OperationContract]
string TestAsXML(string extra);
[OperationContract]
string TestAsJSON(string extra);
}
步骤2b
TestService.cs
using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TestService : TestInterface
[WebInvoke(UriTemplate = "Test/{username}", Method = "GET", ResponseFormat = WebMessageFormat.Xml)]
public string TestAsXML(string username)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
return String.Format("Hello {0}!", String.IsNullOrWhiteSpace(username) ? "world" : username);
}
[WebInvoke(UriTemplate = "Test/{username}?format=json", Method = "GET", ResponseFormat = WebMessageFormat.Json)]
public string TestAsJSON(string username)
{
// NOTE, if we GET this from a browsers, it will most likely have
// "Accept: text/html, application/xhtml+xml, */*" in the HTTP header
// So the framework will return XML instead. Try from Fiddler2 instead or
// write your own WCF client or from AJAX
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json";
return String.Format("Hello {0}!", String.IsNullOrWhiteSpace(username) ? "world" : username);
}
步骤3
对于上面的“测试”示例,所有内容都在URI本身之上(由于GET),因此您不需要下面的内容。实际上,一旦您想要使用POST等,您将需要在HTTP正文中发送对象。交换数据时,使用“数据协定”来利用WCF的功能,如下所示
在这里,我将在HTTP主体中发送一个类,该类中依次包含一个字符串和一个int
TestInput.cs
using System;
using System.Web;
using System.Runtime.Serialization;
// "" needed to clear out ugly xmlns namespace tags to make it plain old XML (POX)
// If you want them, ether take it out or specify on your own
[DataContract(Name = "TestInput", Namespace = "")]
public class TestInput
{
// NOTE: If Order property is skipped, the data will be serialized
// alphabetically per variable names!!
// This can kill services, so better to be explicit
[DataMember(Order = 0)]
int SomeNumber;
// NOTE: If Name property is used XML will have UserName instead of internalUserName
[DataMember(Name="UserName", Order = 1)]
string internalUserName;
}
1) 如果我把XML字符串(它实际上是一个大文件)塞进URL中,它不是会得到而不是POST吗?POST的一个原因是因为它对我来说不是幂等的……2)我想你指的是提取XML字符串的请求对象,而不是响应对象?如果我将XML字符串作为隐藏的表单字段发送,那么看起来我可以将其读取为
XMLstr=context.Request.form[indexHiddenXMLField]
但我怀疑这样做是错误的,因为HTTP请求将看起来像内容类型:application/x-www-form-urlencoded Content Length:31 HiddenXMLField=
我认为内容类型应该反映XML(text/XML?),并且主体应该是真正的XML。这是一种预感-我可能是错的,因为我从未设计过真正的RESTful API3)如何消除.ashx扩展以便server.com\API\incoming.ashx=>server.com\API\incoming(或者可能在最后?)。。。。。我不得不把它分成3条评论来适应。很抱歉我严格地说的是最简单的直接方法,没有任何干扰。正确的方法是使用WCF web服务。虽然在我的方法中,要获得状态,只需使用静态资源(文件、数据库或内存中的文本静态资源)并注意线程安全。对于URL,您只需通过IIS管理器UI转到文件夹的属性,并将incoming.ashx设为默认文档
using System;
using System.Web;
using System.Runtime.Serialization;
// "" needed to clear out ugly xmlns namespace tags to make it plain old XML (POX)
// If you want them, ether take it out or specify on your own
[DataContract(Name = "TestInput", Namespace = "")]
public class TestInput
{
// NOTE: If Order property is skipped, the data will be serialized
// alphabetically per variable names!!
// This can kill services, so better to be explicit
[DataMember(Order = 0)]
int SomeNumber;
// NOTE: If Name property is used XML will have UserName instead of internalUserName
[DataMember(Name="UserName", Order = 1)]
string internalUserName;
}