如何动态更改类后面的Web服务代码?

时间:2013-11-28 19:54:54

标签: c# web-services asmx

我遇到了不同版本的Web服务的问题。

由于Web服务有多个版本,因此有时会更改参数和/或添加和删除WebMethod。

我想拥有一个asmx文件,但是根据客户端安装(它们运行的​​版本),能够在运行时更改asmx背后的代码。

不是每个版本都有不同的asmx,只需要一个asmx文件,动态地可以使用准确版本加载代码。在这种情况下,我有一个V1Methods.cs,V2Methods.cs,V10Methods.cs

<%@ WebService Language="C#"  Class="DynamicClass" %>

如果客户正在运行Version2,则类后面的asmx代码应为V2Methods.cs,依此类推。

有可能吗?

2 个答案:

答案 0 :(得分:3)

总之不,这是不可能的。我打算建议使用webservice作为一个外观,但通过它的声音,每个版本的方法签名是不同的,这将使这更难。

如果客户端应用程序依赖于您的Web服务的特定版本,您不能只使用不同的名称(即servicev1.asmx,servicev2.asmx等)部署您的服务的所有版本,并向您的客户端添加一些配置告诉它要打电话给谁?

答案 1 :(得分:1)

好的 - 我有一个可能的解决方案,但它不是因为优雅而获奖,但我只是测试了它并且它有效。

您可以公开一个返回对象的WebMethod并获取一个params object []参数,允许您将任何您喜欢的内容传递给它(或者什么都没有)并返回您想要的任何内容。这使用'anyType'类型编译为合法的WSDL。

如果您可以根据传递给此方法的参数的数量和数据类型来识别要调用的实际方法,则可以调用适当的方法并返回所需的任何值。

服务: -

[WebMethod]
public object Method(params object[] parameters)
{
    object returnValue = null;

    if (parameters != null && parameters.Length != 0)
    { 
        if (parameters[0].GetType() == typeof(string) && parameters[1].GetType() == typeof(int))
        {
            return new ServiceImplementation().StringIntMethod(parameters[0].ToString(), Convert.ToInt32(parameters[1]));
        }
        else if (parameters[0].GetType() == typeof(string) && parameters[1].GetType() == typeof(string))
        {
            return new ServiceImplementation2().StringStringMethod(parameters[0].ToString(), parameters[1].ToString());
        }
    }

    return returnValue;
}

我的测试服务实现类: -

public class ServiceImplementation
{
    public string StringIntMethod(string someString, int someInt)
    {
        return "StringIntMethod called";
    }
}

public class ServiceImplementation2
{
    public float StringStringMethod(string someString, string someOtherString)
    {
        return 3.14159265F;
    }
}

使用示例: -

    var service = new MyTestThing.MyService.WebService1();

    object test1 = service.Method(new object[] { "hello", 3 });
    Console.WriteLine(test1.ToString());

    object test2 = service.Method(new object[] { "hello", "there" });
    Console.WriteLine(test2.ToString());

我测试了这个并且它有效。如果您感兴趣,“Method”生成的WSDL: -

POST /test/WebService1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/Method"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Method xmlns="http://tempuri.org/">
      <parameters>
        <anyType />
        <anyType />
      </parameters>
    </Method>
  </soap:Body>
</soap:Envelope>

如果你想知道,是的,我在工作中感到无聊,我有心情帮助别人:)