如何更改我的 wsdl 的地址位置

问题描述 投票:0回答:5

我的 wsdl 在地址位置放置了错误的域,如何修复它?

- <wsdl:service name="XWebService">
- <wsdl:port name="XServiceSoap" binding="tns:XWebServiceSoap">
  <soap:address location="https://machine.wrongdomain.com.br/webservices/MapleStoryWebService.asmx" /> 
  </wsdl:port>
- <wsdl:port name="XWebServiceSoap12" binding="tns:XWebServiceSoap12">
  <soap12:address location="https://machine.wrongdomain.com.br/webservices/XWebService.asmx" /> 
  </wsdl:port>
- <wsdl:port name="XWebServiceHttpGet" binding="tns:XWebServiceHttpGet">
  <http:address location="https://machine.wrongdomain.com.br/webservices/MapleStoryWebService.asmx" /> 
  </wsdl:port>
- <wsdl:port name="XWebServiceHttpPost" binding="tns:XWebServiceHttpPost">
  <http:address location="https://machine.wrongdomain.com.br/webservices/XWebService.asmx" /> 
  </wsdl:port>
  </wsdl:service>

真正的域名就像https://machine.goodDomain.com.br

c# web-services visual-studio-2008 iis-6 asmx
5个回答
4
投票

该地址取自用于访问 WSDL 的 URL。如果它与您想要实际提供服务的服务器不同,那么您可以通过创建一个扩展 SoapExtensionReflector 的类来更改它。以下是有关如何更改 URL 的示例文章:

http://blogs.msdn.com/kaevans/archive/2005/11/16/493496.aspx


2
投票

另一种选择是使用 IIS URL 重写模块 (http://www.iis.net/downloads/microsoft/url-rewrite)

首先 - 捕获 XWebService.asmx?WSDL 的输出并将其保存为 HTML 文件(例如 wsdl.htm)。

编辑此文件并将位置更改为备用地址

...来自 thishost.domain.com:

- <wsdl:port name="XWebServiceHttpPost" binding="tns:XWebServiceHttpPost">
  <http:address location="http://thishost.domain.com/XWebService.asmx" /> 
  </wsdl:port>

...至 thathost.domain.com:

- <wsdl:port name="XWebServiceHttpPost" binding="tns:XWebServiceHttpPost">
  <http:address location="http://thathost.domain.com/XWebService.asmx" /> 
  </wsdl:port>

在 IIS 中 - 在网站/虚拟功能视图中找到 URL 重写图标。然后单击 添加规则 并选择 入站规则 - 空白规则

使用规则 - 适当命名并设置将接收 WSDL 请求的 Web 服务 URL 的模式匹配。对于正则表达式:

(.*)XWebservice.asmx

对于条件,将 {QUERY_STRING}WSDL 以及 {REQUEST_METHOD}GET 匹配。

对于Action - 将其设置为Rewrite(因此这对客户端来说是透明的)并选择我们之前保存的文件(wsdl.htm)。

这还会向 web.config 的 system.webServer 部分添加一个新的 rewrite 部分

<system.webServer>
    <rewrite>
        <rules>
            <rule name="WSDL Rewrite" stopProcessing="true">
                <match url="(.*)XWebService.asmx" />
                <conditions>
                    <add input="{QUERY_STRING}" pattern="WSDL" />
                    <add input="{REQUEST_METHOD}" pattern="GET" />
                </conditions>
                <action type="Rewrite" url="wsdl.htm" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>

1
投票

为什么不手动将 WSDL 文件中的地址编辑为应有的地址呢?

如果 WSDL 是由其他工具生成的,请告诉我们它是如何生成的,也许我们可以提供帮助。否则,没有法律禁止修改生成的文件以满足您的需要。如果原始用户环境的 WSDL 的问题只是 URL 错误,那么直接修改 URL 是完全合法的。


0
投票

最初的反应是正确的。 WSDL 中的默认 URL 取决于用于访问 WSDL 的 URL。

我的团队过去处理更改服务 URL 的方式(例如,从开发环境过渡到测试或生产环境)是使用 wsdl.exe 为您的 Web 服务生成代码代理(代理实际上是通过以下方式创建的)也可以是 Web 或服务引用,但默认情况下不会显示在 Visual Studio 中),您可以编辑生成的代理类以从 (??) 任何您想要存储它的位置(数据库、配置文件等)读取服务的 URL。


0
投票

解决方案很少,我会按照从简单到准确的顺序进行排序。 :)

  1. 不用担心 WSDL 中的 URL。 只需在客户端使用
    Url
    属性
    ,就像在这种情况下:
    public class MyWebService : RemoteService
    {
        public MyWebService() : base()
        {
            Url = ConfigurationManager.AppSettings["MyServiceCustomUrl"];
        }
    }

明显的缺点:很可能您将无法使用生成的 html(我的意思是为 Web 方法生成的表单)正确测试服务。

  1. 使用自定义
    wsdlHelpGenerator

我没有测试这个解决方案,但乍一看,如果您基于原始的 DefaultWsdlHelpGenerator.aspx 创建自己的解决方案,它看起来很简单(您可以在 C:\Windows\Microsoft.NET\Framework* 文件夹中找到它) ,就我而言,它是 C:\Windows\Microsoft.NET\Framework 4.0.30319\Config\DefaultWsdlHelpGenerator.aspx)。

  1. 使用
    soapExtensionReflectorTypes
    。它将允许您使用 HttpSoap 协议地址执行任何操作。

创建一个处理程序(下面的示例将 http 更改为 https):

    public class HttpsReflector : SoapExtensionReflector
    {
        public override void ReflectMethod()
        {
            // nothing to override
        }

        public override void ReflectDescription()
        {
            ServiceDescription description = ReflectionContext.ServiceDescription;
            foreach (System.Web.Services.Description.Service service in description.Services)
            {
                foreach (Port port in service.Ports)
                {
                    foreach (ServiceDescriptionFormatExtension extension in port.Extensions)
                    {
                        if (extension is SoapAddressBinding binding)
                        {
                            binding.Location = binding.Location.Replace("http://", "https://");
                        }
                    }
                }
            }
        }
    }

在 web.config 中注册:

  <system.web>
    <webServices>
      <soapExtensionReflectorTypes>
        <!-- Required to replace http in addresses for HttpSoap protocol -->
        <add type="MyWebServices.WsdlFixHttp.HttpsReflector, MyWebServices"/>
      </soapExtensionReflectorTypes>
    </webServices>
  </system.web>

缺点:无法控制 HttpPost/HttpGet 协议。

  1. 实现IIS重写模块。它将允许您修改服务产生的任何输出。可以与#3一起使用。

创建2个类,流装饰器:

    public class StreamWatcher : Stream
    {
        private readonly Stream _base;
        private readonly MemoryStream _memoryStream = new MemoryStream();

        public StreamWatcher(Stream stream)
        {
            _base = stream;
        }

        public override void Flush()
        {
            _base.Flush();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _base.Read(buffer, offset, count);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            _memoryStream.Write(buffer, offset, count);
            _base.Write(buffer, offset, count);
        }

        public override string ToString()
        {
            return Encoding.UTF8.GetString(_memoryStream.ToArray());
        }

        public override bool CanRead => _base.CanRead;

        public override bool CanSeek => _base.CanSeek;

        public override bool CanWrite => _base.CanWrite;

        public override long Seek(long offset, SeekOrigin origin) => _base.Seek(offset, origin);

        public override void SetLength(long value) => _base.SetLength(value);

        public override long Length => _base.Length;

        public override long Position
        {
            get => _base.Position;
            set => _base.Position = value;
        }
    }

和模块:

    public class WsdlFixHttpModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.EndRequest += (s, e) => OnEndRequest(s, e);
            context.BeginRequest += (s, e) => OnBeginRequest(s, e);
        }

        private void OnBeginRequest(object sender, EventArgs e)
        {
            HttpContext httpContext = HttpContext.Current;
            if (httpContext.Request.Url.Query.Equals("?WSDL", StringComparison.InvariantCultureIgnoreCase)
                || IsAsmxGetRequest(httpContext))
            {
                httpContext.Response.Filter = new StreamWatcher(httpContext.Response.Filter);
            }
        }

        private void OnEndRequest(object sender, EventArgs e)
        {
            HttpContext httpContext = HttpContext.Current;
            string oldValue = "", newValue = "";
            bool replacementRequired = false;

            if (httpContext.Request.Url.Query.Equals("?WSDL", StringComparison.InvariantCultureIgnoreCase))
            {
                oldValue = ":address location=\"http://";
                newValue = ":address location=\"https://";
                replacementRequired = true;
            }
            else if (IsAsmxGetRequest(httpContext))
            {
                oldValue = "<form target=\"_blank\" action='http://";
                newValue = "<form target=\"_blank\" action='https://";
                replacementRequired = true;
            }

            if (replacementRequired)
            {
                string wsdl = httpContext.Response.Filter.ToString();
                wsdl = wsdl.Replace(oldValue, newValue);
                httpContext.Response.Clear();
                httpContext.Response.Write(wsdl);
                httpContext.Response.End();
            }
        }

        private static bool IsAsmxGetRequest(HttpContext httpContext)
        {
            return httpContext.Response.ContentType == "text/html"
                   && httpContext.Request.CurrentExecutionFilePathExtension.Equals(".asmx", StringComparison.InvariantCultureIgnoreCase)
                   && httpContext.Request.HttpMethod == "GET";
        }

        public void Dispose()
        {
        }
    }

然后在web.config中注册模块:

  <system.webServer xdt:Transform="Insert">
    <modules>
      <!-- Required to replace http in addresses for HttpPost/HttpGet protocols -->
      <add name="WsdlFixHttpModule" type="MyWebServices.WsdlFixHttp.WsdlFixHttpModule, MyWebServices"/>
    </modules>
  </system.webServer>

请注意,上面的注册是集成模式,经典模式需要在里面注册

system.web

因此,在我们的遗留项目中,我使用了 3+4 方法,但如果我想再次这样做,我会尝试使用#2 方法。 :)

© www.soinside.com 2019 - 2024. All rights reserved.