代码之家  ›  专栏  ›  技术社区  ›  Grinn Amber

继承的属性不会出现在ASMX文件的SOAP示例中

  •  9
  • Grinn Amber  · 技术社区  · 15 年前

    我有两个类:WebServiceRequest和OrderRequest。每个类都有属性。OrderRequest继承自WebServiceRequest-类似于:

        public class WebServiceRequest
        {
            private string mAuthenticationToken;
    
            public string AuthenticationToken
            {
                get { return mAuthenticationToken; }
                set { mAuthenticationToken = value; }
            }
            ...
    }
    

    public class OrderRequest : WebServiceRequest
    {
    
        private string mVendorId;
        public string VendorId
        {
            get { return mVendorId; }
            set { mVendorId = value; }
        }
        ...
    }
    

    OrderRequest通过WebMethod公开。在查看公开orderrequest(即mywebservice.asmx)的asmx文件的WSDL时,WSDL),这两个属性都是可见的-应该是可见的。但是,当您查看公开orderrequest的Web方法的SOAP示例时,只有vendorid属性可见,而不是继承的authenticationToken属性。怎么回事?

    注: 我将此问题作为一个bug发布在MS Connect上: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=520200

    3 回复  |  直到 8 年前
        1
  •  4
  •   Grinn Amber    15 年前

    即使在微软确认我的问题是一个bug之后,我还是设法把这些废话重新放到了解决方案中。( https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=520200 )我放弃了,把约翰的回答标为接受了。解决方案如下:

    http://code.msdn.microsoft.com/WsdlHelpGenerator/Release/ProjectReleases.aspx?ReleaseId=412

    转到那里,下载文件,然后在web.config文件的system.web部分下添加以下行:

    <webServices>
     <wsdlHelpGenerator href="CustomWsdlHelpGenerator.aspx"/>
    </webServices>
    

    href属性应指向项目中文件的相对位置。谢谢你的帮助,约翰。

        2
  •  2
  •   Community CDub    8 年前

    不需要使用 [XmlInclude] .

    您似乎认为这是一个问题,因为帮助页面的外观(当您点击.asmx URL时,在浏览器中会得到什么)。不要那样做。相反,查看实际返回的内容。


    更新: 这个 OP 创建了一个 Connect bug 关于这个问题。此错误在2010年11月1日被解决为“无法修复”:

    我们已经确认 属性不显示在SOAP中 浏览器上的示例,即 确实是产品中的一个缺陷。

    此时,该区域位于 进入维护模式 ,没有活动的工作 是有计划的。

        3
  •  1
  •   AceJordin    8 年前

    @格林恩的链接死了,谷歌customwsdlhelpgenerator.aspx没有发现任何有用的东西。但我发现了:

    Improving the ASP.NET Webservice Help Generator

    它使用@grin引用的方法,并使用XSL转换WSDL数据以反映继承。

    从链接:

    获取已安装的默认描述生成器default wsdlhelpgenerator.aspx(在我的计算机上,它位于C:\windows\microsoft.net\framework\v2.0.50727\config中),并将其另存为WebService的Web目录中的wsdlhelpgenerator.aspx。打开web.config并放置…

    <webServices>
      <wsdlHelpGenerator href="WsdlHelpGenerator.aspx" />
    </webServices>
    

    …在“<system.web>”部分中。

    打开wsdlhelpgenerator.aspx,将这两个方法直接添加到页面加载方法的下面:

    protected override void OnPreLoad(EventArgs e) {
       base.OnPreLoad(e);
    
       // transform any service description stored within HttpContext
       // cf. Page_Load: try "wsdlsWithPost" first and fall back to "wsdls"
       string key = Context.Items["wsdlsWithPost"] != null ?
                   "wsdlsWithPost" : "wsdls";
    
       serviceDescriptions = (ServiceDescriptionCollection)Context.Items[key];
       TransformServiceDescriptions(ref serviceDescriptions);
       Context.Items[key] = serviceDescriptions;
     }
    
    void TransformServiceDescriptions(ref ServiceDescriptionCollection descriptions) {
    
       // modify each description by an XSLT processor
       ServiceDescriptionCollection transformed = new ServiceDescriptionCollection();
       System.Xml.Xsl.XslCompiledTransform xslt =
           new System.Xml.Xsl.XslCompiledTransform();
       xslt.Load(Server.MapPath("WsdlHelp.xsl"));
    
       foreach (ServiceDescription desc in descriptions)
       {
         // load original WSDL data
         MemoryStream ms1 = new MemoryStream(), ms2 = new MemoryStream();
         desc.Write(ms1);
    
         // process WSDL data using WsdlHelp.xsl
         ms1.Position = 0;
         xslt.Transform(new System.Xml.XPath.XPathDocument(ms1), null, ms2);
    
         // replace current WSDL data with the transformed stream
         ms2.Position = 0;
         transformed.Add(ServiceDescription.Read(ms2));
    
         ms1.Dispose();
         ms2.Dispose();
       }
       descriptions = transformed;
    }
    

    最后,要使此代码正常工作,请将转换文件wsdlhelp.xsl放入Web服务的Web目录中。它可能看起来如下:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
            xmlns:s="http://www.w3.org/2001/XMLSchema">
      <xsl:output
        method="xml"
        indent="no"
        encoding="utf-8"
        omit-xml-declaration="no"
      />
      <!-- recursively dissolve any schema extension elements to the base structure -->
    
      <xsl:template match="/" xml:space="default">
        <xsl:apply-templates />
      </xsl:template>
    
      <xsl:template match="*" priority="0.5" xml:space="default">
        <xsl:copy>
          <xsl:copy-of select="attribute::*" />
          <xsl:choose>
            <xsl:when test="child::*" />
            <xsl:otherwise>
              <xsl:value-of select="." />
            </xsl:otherwise>
          </xsl:choose>
          <xsl:apply-templates select="child::*" />
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="s:complexType" priority="1.0">
        <xsl:element name="s:complexType" namespace="http://www.w3.org/2001/XMLSchema">
          <xsl:copy-of select="attribute::*" />
          <xsl:element name="s:sequence">
            <xsl:copy-of select=".//s:sequence/*" />
            <xsl:if test="./s:complexContent/s:extension">
              <xsl:comment> schema extension expanded: <xsl:value-of
                select="./s:complexContent/s:extension/@base"/> </xsl:comment>
              <xsl:call-template name="fetch-sequence">
                <xsl:with-param name="typename"
                  select="substring-after(./s:complexContent/s:extension/@base,':')" />
              </xsl:call-template>
            </xsl:if>
          </xsl:element>
        </xsl:element>
      </xsl:template>
    
      <xsl:template name="fetch-sequence">
        <xsl:param name="typename" />
        <xsl:copy-of select="//s:complexType[@name = $typename]//s:sequence/*" />
        <xsl:if test="//s:complexType[@name = $typename]/s:complexContent/s:extension">
          <xsl:call-template name="fetch-sequence">
            <xsl:with-param name="typename"
              select="substring-after(//s:complexType[@name = $typename]
                    /s:complexContent/s:extension/@base,':')" />
          </xsl:call-template>
        </xsl:if>
      </xsl:template>
    
    </xsl:stylesheet>