代码之家  ›  专栏  ›  技术社区  ›  GBegen

我是否可以控制数组及其项的XML元素名作为异步.Net ASMX web方法的返回值?

  •  1
  • GBegen  · 技术社区  · 15 年前

    考虑下面的.NET ASMX Web服务和两种Web方法。

    using System;
    using System.Runtime.Remoting.Messaging;
    using System.Web.Services;
    using System.Xml.Serialization;
    
    namespace DemoWebService
    {
     public class
     ArrayItem
     {
      public int
      Value1;
    
      public int
      Value2;
     };
    
     [WebService(Namespace = "http://begen.name/xml/namespace/2009/09/demo-web-service/")]
     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
     public class DemoService :
      WebService
     {
      [WebMethod]
      [return: XmlArray("Items")]
      [return: XmlArrayItem("Item")]
      public ArrayItem []
      GetArray()
      {
       return BuildArray();
      }
    
      [WebMethod]
      public IAsyncResult
      BeginGetArrayAsync(AsyncCallback callback, object callbackData)
      {
       BuildArrayDelegate fn = BuildArray;
       return fn.BeginInvoke(callback, callbackData);
      }
    
      [WebMethod]
      [return: XmlArray("Items")]
      [return: XmlArrayItem("Item")]
      public ArrayItem []
      EndGetArrayAsync(IAsyncResult result)
      {
       BuildArrayDelegate fn = (BuildArrayDelegate)((AsyncResult)result).AsyncDelegate;
       return fn.EndInvoke(result);
      }
    
      private delegate ArrayItem []
      BuildArrayDelegate();
    
      private ArrayItem []
      BuildArray()
      {
       ArrayItem [] retval = new ArrayItem[2];
       retval[0] = new ArrayItem();
       retval[0].Value1 = 1;
       retval[0].Value2 = 2;
       retval[1] = new ArrayItem();
       retval[1].Value1 = 3;
       retval[1].Value2 = 4;
    
       return retval;
      }
     }
    }
    

    GetArray和GetArraySync web方法都返回 ArrayItem

    通过将[XmlArray]和[XmlArrayItem]属性应用于 GetArray() 方法,我已经能够控制.Net用于序列化返回值的XML元素,并得到如下结果:

    <?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>
        <GetArrayResponse xmlns="http://begen.name/xml/namespace/2009/09/demo-web-service/">
          <Items>
            <Item>
              <Value1>int</Value1>
              <Value2>int</Value2>
            </Item>
            <Item>
              <Value1>int</Value1>
              <Value2>int</Value2>
            </Item>
          </Items>
        </GetArrayResponse>
      </soap:Body>
    </soap:Envelope>
    

    EndGetArrayAsync() 方法,但它们似乎不会像对同步对象那样影响响应 GetArray() 方法。在本例中,响应如下所示:

    <?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>
        <GetArrayAsyncResponse xmlns="http://begen.name/xml/namespace/2009/09/demo-web-service/">
          <GetArrayAsyncResult>
            <ArrayItem>
              <Value1>int</Value1>
              <Value2>int</Value2>
            </ArrayItem>
            <ArrayItem>
              <Value1>int</Value1>
              <Value2>int</Value2>
            </ArrayItem>
          </GetArrayAsyncResult>
        </GetArrayAsyncResponse>
      </soap:Body>
    </soap:Envelope>
    

    在本例中,返回值的默认XML元素名为“GetArrayAsyncResult”,数组项的XML元素名来自C#类名“ArrayItem”。

    有没有办法让异步web方法尊重应用于End*方法返回值的[XmlArray]和[XmlArrayItem]属性?

    2 回复  |  直到 15 年前
        1
  •  0
  •   Community CDub    8 年前

    See this question...

    您需要将XmlType()属性添加到数组中使用的类中,然后仅在定义数组的类成员上指定XmlArray()属性。

        2
  •  0
  •   GBegen    15 年前

    [return: *] 属性放置在 End*() 异步实现的方法。

    我找到了一种解决方法,使WSDL与web方法的同步和异步版本基本相同,从而使SOAP响应使用我希望用于数组的XML元素名称。

    我需要换个房间 完*() 方法不具有返回值,而是使用输出参数返回数组。这个 [XmlArrayItem] 属性,而不是方法的返回值。这是修订版 EndGetArrayAsync() 方法实现我想要的。

        [WebMethod]
        public void
        EndGetArrayAsync(IAsyncResult result, [XmlArrayItem("Item")] out ArrayItem [] Items)
        {
            BuildArrayDelegate fn = (BuildArrayDelegate)((AsyncResult)result).AsyncDelegate;
            Items = fn.EndInvoke(result);
        }