2014-01-07 33 views
0

我想用c#实现一个web服务。我有兴趣实现服务器而不是消费者。 Web服务必须由一个独立的软件运行,因为我没有像IIS这样的网络服务器来部署它。我知道我可以带一个wsdl文件,使用gsoap为它生成C代码,我在服务器端实现例程,并构建链接libgsoap的独立程序。没有网络服务器的独立c#webservice

现在我想用c#和.net平台来做同样的事情。

我用来研究它的wsdl文件与gsoap一样,你可以找到它here

下一步是下载它并运行wsdl -server cal.wsdl以获得calc.cs

在这一点上,我卡住了,因为我无法找到关于如何进行的文档。

如何实现扩展抽象类calc的程序?我通过运行wsdl获得的启动一个小型web服务器来执行所需的功能?你能指点我一些很好的文档吗?

新增

当我运行wsdl -server cal.wsdl我得到这个代码

/// <remarks/> 
/// <remarks> 
///gSOAP 2.7.9k generated service definition 
///</remarks> 
[System.Web.Services.WebServiceAttribute(Namespace="http://websrv.cs.fsu.edu/~engelen/calc.wsdl")] 
[System.Web.Services.WebServiceBinding(Name="calc", Namespace="http://websrv.cs.fsu.edu/~engelen/calc.wsdl")] 
public abstract partial class calc : System.Web.Services.WebService { 

    /// <remarks> 
///Service definition of function ns__add 
///</remarks> 
    [System.Web.Services.WebMethodAttribute()] 
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:calc", ResponseNamespace="urn:calc")] 
    [return: System.Xml.Serialization.SoapElement("result")] 
    public abstract double add(double a, double b); 

    /// <remarks> 
///Service definition of function ns__sub 
///</remarks> 
    [System.Web.Services.WebMethodAttribute()] 
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:calc", ResponseNamespace="urn:calc")] 
    [return: System.Xml.Serialization.SoapElement("result")] 
    public abstract double sub(double a, double b); 

    /// <remarks> 
///Service definition of function ns__mul 
///</remarks> 
    [System.Web.Services.WebMethodAttribute()] 
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:calc", ResponseNamespace="urn:calc")] 
    [return: System.Xml.Serialization.SoapElement("result")] 
    public abstract double mul(double a, double b); 

    /// <remarks> 
///Service definition of function ns__div 
///</remarks> 
    [System.Web.Services.WebMethodAttribute()] 
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:calc", ResponseNamespace="urn:calc")] 
    [return: System.Xml.Serialization.SoapElement("result")] 
    public abstract double div(double a, double b); 

    /// <remarks> 
///Service definition of function ns__pow 
///</remarks> 
    [System.Web.Services.WebMethodAttribute()] 
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:calc", ResponseNamespace="urn:calc")] 
    [return: System.Xml.Serialization.SoapElement("result")] 
    public abstract double pow(double a, double b); 
} 

这是一个抽象类,因为所有在服务器端的方法没有实现。因此,我期待着,就像我通常用gsoap做的那样,我将不得不扩展这个类并重写抽象方法,这很容易。

问题是,之后我不知道如何编写一个程序,该程序采用继承的类并启动Web服务器并在网络上公开Web服务。

+0

听起来就像你试图从wsdl生成web服务实现。这不可能。一个wsdl文件不包含逻辑,它只告诉客户端它需要与服务器进行通信的方法和类型。 – i3arnon

+0

是的,这就是为什么我在Linux/Unix中编写代码时使用gsoap生成C代码,编译前我还实现了服务器的例程,以便它知道在调用web服务时必须执行的操作。 –

+0

你问如何编写代码和C#并编译它? – i3arnon

回答

3

这并不复杂,但需要从你身边做一些工作。您可以使用WCF技术创建服务。

我想你会使用Visual Studio并为.NET创建一个应用程序。如果你的目标是单声道,你将不得不采取下面的例子。

1 - 创建一个控制台.NET项目并手动添加对System.ServiceModel和System.Runtime.Serialization的引用。

2 - 您应该将您的抽象类转换为接口。这将是您工作中最难的部分,因为您应该达到相同的WSDL。

例如:

[System.Web.Services.WebServiceAttribute(Namespace="http://websrv.cs.fsu.edu/~engelen/calc.wsdl")] 
[System.Web.Services.WebServiceBinding(Name="calc", Namespace="http://websrv.cs.fsu.edu/~engelen/calc.wsdl")] 
public abstract partial class calc : System.Web.Services.WebService { 
/// <remarks> 
///Service definition of function ns__add 
///</remarks> 
[System.Web.Services.WebMethodAttribute()] 
[System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:calc", ResponseNamespace="urn:calc")] 
[return: System.Xml.Serialization.SoapElement("result")] 
public abstract double add(double a, double b); 

皈依例如:

using System.ServiceModel; 
// other usings, namespace etc 

[ServiceContract(Namespace = "http://websrv.cs.fsu.edu/~engelen/calc.wsdl", Name = "calc")] 
public interface ICalcService 
{ 
    [OperationContract(Name = "add")] 
    [return: MessageParameter(Name = "result")] 
    [XmlSerializerFormatAttribute(Style=OperationFormatStyle.Rpc, Use=OperationFormatUse.Encoded)] 
    double add(double a, double b); 

    // the rest of methods 
} 

或者,你可以尝试使用SvcUtil工具来生成C#代理类:

svcutil http://www.genivia.com/calc.wsdl 

你会得到钙.cs作为结果,因此您可以从中提取服务和数据合同。

3 - 无论如何,你创建服务合同的接口后,你创造它的实现:

public class CalcServiceImpl : ICalsService 
{ 
    public double add(double a, double b) 
    { 
     return a + b; 
    } 

    // the rest 
} 

4 - 之后,你应该创建一个ServiceHost的实例。像这样:

ServiceHost host = new ServiceHost(typeof(CalcServiceImpl), new Uri("http://myhost/MyServices"))) 
host.AddServiceEndpoint(typeof(ICalcService), new BasicHttpBinding(), "CalcService"); 
host.Open(); 
Console.ReadKey(); 
host.Close(); 

当然,这是一个非常简单的例子,但我希望它会给你方向。

+0

谢谢你的回答,我明白我需要在wsdl文件上运行svcutil来获得代理类。我只是有一个更多的问题:一旦我运行svcutil calc.wsdl,你能确认我只需要实现接口calcPortType,然后我将它实例化为我nstep 4? –

+0

基本上是的,但正如我所说创建接口可能是一个难题,因为您的结果服务必须与使用原始WSDL生成的客户端兼容。例如,必须从接口删除[System.ServiceModel.OperationContractAttribute(Action =“”,ReplyAction =“*”)]属性,向ServiceContractAttribute添加参数Name =“calc”,应用其他属性[DataContractFormat(Style = OperationFormatStyle.Rpc)]到接口等。我也建议你使用app.config来提供服务配置。 – Ronnix