简体   繁体   English

如何动态更改类后面的WebService代码?

[英]How to change WebService code behind class dynamically?

I'm facing an issue with different versions of a Web Service. 我遇到了不同版本的Web服务的问题。

Because there are several versions of the Web service, sometimes the parameters are changed and/or WebMethods are added and removed. 因为Web服务有多个版本,所以有时会更改参数和/或添加和删除WebMethod。

I want to have a single asmx file, but depending on the client installation (the version they are running), be able to change the code behind of the asmx at runtime. 我希望有一个asmx文件,但是根据客户端安装(它们正在运行的版本),能够在运行时更改asmx的代码。

Instead of having different asmx per version, just have one asmx file that dynamically can load the code behind with the accurate version. 不用每个版本具有不同的asmx,而只需拥有一个可以动态加载正确版本代码的asmx文件。 In this case I do have a V1Methods.cs, V2Methods.cs, V10Methods.cs 在这种情况下,我确实有一个V1Methods.cs,V2Methods.cs,V10Methods.cs

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

If the customer is running Version2, the asmx code behind class should be V2Methods.cs and so on. 如果客户正在运行Version2,则类后面的asmx代码应为V2Methods.cs,依此类推。

Is it possible? 可能吗?

In short no, that is not possible. 简而言之,这是不可能的。 I was going to suggest using the webservice as a facade but by the sounds of it the method signatures on each version are different, which would make that more difficult. 我本来建议将Web服务用作外观,但听起来听起来每个版本的方法签名都不相同,这将使此操作更加困难。

If the client application is dependent on a particular version of your webservice, can't you just deploy all versions of your service with different names (ie servicev1.asmx, servicev2.asmx etc), and add some config to your client to tell it which one to call ? 如果客户端应用程序依赖于您的Web服务的特定版本,您是否不能仅使用不同的名称(即servicev1.asmx,servicev2.asmx等)部署所有版本的服务,并向客户端添加一些配置以告知它叫哪个?

OK - I have a possible solution for you that is not award-winning for elegance but I've just tested it and it works. 好的-我为您提供了一个可能的解决方案,该解决方案并未因优雅而获奖,但我已经对其进行了测试,并且可以正常工作。

You can expose one WebMethod that returns object and takes a params object[] parameter, allowing you to pass whatever you like to it (or nothing) and return whatever you want. 您可以公开一个WebMethod,该WebMethod返回object并接受params object []参数,从而使您可以将所需的任何内容传递给它(或不传递任何内容)并返回所需的任何内容。 This compiles to legal WSDL using the 'anyType' type. 这将使用“ anyType”类型编译为合法的WSDL。

If you can identify which actual method to call based on the number and datatype of parameters passed to this method, you can call the appropriate method and return whatever value you want. 如果您可以根据传递给该方法的参数的数量和数据类型确定要调用的实际方法,则可以调用适当的方法并返回所需的任何值。

The service: - 服务: -

[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;
}

My test service implementation classes: - 我的测试服务实现类:-

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;
    }
}

An example of use: - 使用示例:-

    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());

I've tested this and it works. 我已经对此进行了测试,并且可以正常工作。 If you're interested, the WSDL that "Method" generates: - 如果您感兴趣,“方法”生成的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>

Incase you're wondering, yes I am bored at work and I'm in the mood for helping people :) 如果您想知道,是的,我在工作中很无聊,并且我很乐于帮助人们:)

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

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