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

发布于 2024-08-09 15:55:46 字数 1064 浏览 2 评论 0原文

我的 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

My wsdl put a wrong domain in address location, How to fix it?

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

The true domain is like https://machine.goodDomain.com.br

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

墨小沫ゞ 2024-08-16 15:55:46

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

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

The address is taken from the URL used to access the WSDL. If it's different than the server you want to actually serve from, then you could change it by creating a class that extends SoapExtensionReflector. Here's a sample article on how to change the URL:

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

蓝海 2024-08-16 15:55:46

另一种选择是使用 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 匹配。

对于操作 - 将其设置为重写(因此这对客户端来说是透明的)并选择我们之前保存的文件(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>

Another option is to use the IIS URL Rewrite module (http://www.iis.net/downloads/microsoft/url-rewrite)

First up - capture the output from XWebService.asmx?WSDL and save it as an HTML file (e.g. wsdl.htm).

Edit this file and change the location to the alternative address

... from thishost.domain.com:

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

...to thathost.domain.com:

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

In IIS - find the URL Rewrite icon in the website/virtual Feature View . Then click Add Rule(s) and choose Inbound Rule - Blank rule.

With the rule - name it appropriately and set the pattern match for the webservice URL that will receive the WSDL request. For RegEx:

(.*)XWebservice.asmx

For the conditions match {QUERY_STRING} to WSDL and {REQUEST_METHOD} to GET.

For the Action - set it to Rewrite (so this is transparent to the client) and choose the file that we saved it as earlier (wsdl.htm).

This also adds a new rewrite section to the system.webServer section of the web.config

<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>
你列表最软的妹 2024-08-16 15:55:46

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

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

Why not just manually edit the address in the WSDL file to what it should be?

If the WSDL is generated by some other tool, then let us know how it is being generated and perhaps we can help. Otherwise, there is no law against modifying the generated file to suit your needs. If all that is wrong with the WSDL for the original users's environment is that the URL is wrong then it is perfectly legitimate to modify the URL directly.

蓝梦月影 2024-08-16 15:55:46

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

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

The initial response is correct. The default URL in the WSDL is dependent upon the URL used to access the WSDL.

The way my team handled changing service URLs in the past (for instance, transitioning from a development to a testing or production environment) is to use wsdl.exe to generate a code proxy for your web service (a proxy is actually created by making a web or service reference as well, but is not displayed in Visual Studio by default), you can edit the generated proxy class to read the service's URL from (??) wherever you want to store it - database, config file etc.

财迷小姐 2024-08-16 15:55:46

解决方案很少,我将从简单到准确进行排序。 :)

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

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

  1. 使用自定义wsdlHelpGenerator

我没有测试这个解决方案,但乍一看,如果您基于原始的 DefaultWsdlHelpGenerator.aspx 创建自己的解决方案,它看起来就足够简单了(您可以在 C:\Windows\Microsoft.aspx 中找到它)。 NET\Framework* 文件夹,在我的例子中是 C:\Windows\Microsoft.NET\Framework\v4.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 方法。 :)

There are few solution, I will sort them from simplicity to accuracy. :)

  1. Don't worry about URLs in WSDL. Just use Url property on a client side, like in that case:
    public class MyWebService : RemoteService
    {
        public MyWebService() : base()
        {
            Url = ConfigurationManager.AppSettings["MyServiceCustomUrl"];
        }
    }

Obvious drawback: most probably you will not able to test the service properly using generated html (I mean generated forms for web methods).

  1. Use custom wsdlHelpGenerator.

I didn't test this solution, but at a glance it looks simply enough if you create your own based on original DefaultWsdlHelpGenerator.aspx (you can find it in C:\Windows\Microsoft.NET\Framework* folders, in my case it was C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\DefaultWsdlHelpGenerator.aspx).

  1. Use soapExtensionReflectorTypes. It will allow you to do anything with your HttpSoap protocol addresses.

Create a handler (sample below will change http to 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://");
                        }
                    }
                }
            }
        }
    }

Register it in 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>

A drawback: no control over HttpPost/HttpGet protocols.

  1. Implement IIS rewrite module. It will allow you to modify any output produced by your service. Can be used together with #3.

Create 2 classes, stream decorator:

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

and the module:

    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()
        {
        }
    }

Then register the module in 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>

Please note, the registration above is for integration mode, for classic one you need to register it inside system.web.

So, in our legacy project I used 3+4 approach, but if I'd want to do that again, I will try to use #2 approach instead. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文