开发者

Using different classes with the same name as a return type in a c# webservice

开发者 https://www.devze.com 2023-04-02 00:36 出处:网络
I am creating a webservice that should return two complex types from the same class library that have the same class name (but live in different namespaces).

I am creating a webservice that should return two complex types from the same class library that have the same class name (but live in different namespaces). When I open the TestService.asmx in my browser I get an exception (see below). Is there a way to fix this (other than renaming the classes of course :D )

I tried decorating my methods with

[WebMethod(MessageName="MyNamespace1.SomeClass")]

and with

[return: XmlElement("SomeClass1", Namespace = "http://tempuri.org/NameSpace1")]

-

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace MyWebservice
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class TestService : System.Web.Services.WebService
    {

        public MyNamespace1.SomeClass GetSomeClass1()
        {
            return new MyNamespace1.SomeClass() { Name = "SomeClass1" };
        }

        public MyNamespace2.SomeClass GetSomeClass2()
        {
            return new MyNamespace2.SomeClass() { Name = "SomeClass1" };
        }

    }

}

namespace MyNamespace1
{
    public class SomeClass
    {
        public string Name { get; set; }
    }
}

namespace MyNamespace2
{
    public class SomeClass
    {
        public string Name { get; set; }
    }
}

throws this exception:

[InvalidOperationException: Die Typen 'MyNamespace2.SomeClass' und 'MyNamespace1.SomeClass' verwenden den XML-Typnamen 'SomeClass' im Namespace 'http://tempuri.org/'. Geben Sie mit XML-Attributen einen eindeutigen XML-Namen und/oder Namespace für den Typ an.]
   System.Xml.Serialization.XmlReflectionImporter.GetTypeMappi开发者_开发百科ng(String typeName, String ns, TypeDesc typeDesc, NameTable typeLib, Type type) +4071889
   System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter) +150
   System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +1604


Ok, I found the solution by trial and error. The key is to combine the [return: XmlRoot...] and [return: XmlElement...]` decoration to make it work.

    [WebMethod]
    [return: XmlRoot(Namespace = "http://tempuri.org/Namespace1")]
    [return: XmlElement(Namespace = "http://tempuri.org/Namespace1",
        ElementName = "SomeClass")]
    public MyNamespace1.SomeClass GetSomeClass1()
    {
        return new MyNamespace1.SomeClass() { Name = "SomeClass1" };
    }

    [WebMethod]
    [return: XmlRoot(Namespace = "http://tempuri.org/Namespace2")]
    [return: XmlElement(Namespace = "http://tempuri.org/Namespace2",
        ElementName = "SomeClass")]
    public MyNamespace2.SomeClass GetSomeClass2()
    {
        return new MyNamespace2.SomeClass() { Name = "SomeClass1" };
    }

Update: This also applies to method parameters. Just change return: to param: and you're done. (You can't add the XmlRoot to params, but that's not necessary anyway.

    [WebMethod]
    public void AddSomeClass1([param: XmlElement(
        Namespace = "http://tempuri.org/Namespace1",
        ElementName = "SomeClass")] MyNamespace1.SomeClass class1)
    {


    }

    [WebMethod]
    public void AddSomeClass2([param: XmlElement(
        Namespace = "http://tempuri.org/Namespace2",
        ElementName = "SomeClass")] MyNamespace2.SomeClass class2)
    {


    }


try adding the following attribute above your classes

[XmlRoot(Namespace = "http://tempuri.org/SubNameSpace")]

With a different value for the sub namespace.


For the people, who want to know what the syntax for VB is (since I lost some time trying to find out what the equivalent to the return: statement is):

<WebMethod> _
Public Function GetSomeClass1() As <XmlRoot(Namespace:="http://tempuri.org/Namespace1"), XmlElement("SomeClass", Namespace:="http://tempuri.org/Namespace1")> MyNamespace1.SomeClass
    ' Return Stuff
End Function
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号