gpt4 book ai didi

c# - 从 .ASMX Web 服务返回 XElement

转载 作者:行者123 更新时间:2023-11-30 16:17:15 25 4
gpt4 key购买 nike

我最近更新了一个 .ASMX Web 服务,它在其中返回一个 XElement 并遇到了这个错误消息:

Cannot use wildcards at the top level of a schema

现在这个错误是由下面的代码产生的;

public class FooBarService : System.Web.Services.WebService
{
[WebMethod]
public XElement Foo(string Bar)
{
return null;
}
}

但是,如果我更改代码以接受 XElement 而不是 String

public class FooBarService : System.Web.Services.WebService
{
[WebMethod]
public XElement Foo(XElement Bar)
{
return null;
}
}

然后 Web 服务不会抛出错误。

那么,为什么接受 XElement 并返回 XElement 的方法有效,而其他方法却无效?

最佳答案

开始的地方是堆栈跟踪,它指示异常发生的地方:

at System.Xml.Serialization.XmlSchemaExporter.ExportElement(ElementAccessor accessor)
at System.Xml.Serialization.XmlSchemaExporter.ExportTypeMapping(XmlTypeMapping xmlTypeMapping)
at System.Web.Services.Description.MimeXmlReflector.ReflectReturn()
at System.Web.Services.Description.HttpProtocolReflector.ReflectMimeReturn()
at System.Web.Services.Description.HttpPostProtocolReflector.ReflectMethod()

通过使用 ILSpy我们可以观察触发异常的条件:

// System.Xml.Serialization.XmlSchemaExporter
private XmlSchemaElement ExportElement(ElementAccessor accessor)
{
if (!accessor.Mapping.IncludeInSchema && !accessor.Mapping.TypeDesc.IsRoot)
{
return null;
}
if (accessor.Any && accessor.Name.Length == 0)
{
throw new InvalidOperationException(Res.GetString("XmlIllegalWildcard"));
}
// truncated method body
}

进一步浏览代码:

// System.Web.Services.Description.MimeXmlReflector
internal override bool ReflectReturn()

// System.Xml.Serialization.XmlReflectionImporter
private ElementAccessor
ImportElement(TypeModel model,
XmlRootAttribute root,
string defaultNamespace,
RecursionLimiter limiter)

等等,我们得到这个方法:

// System.Xml.Serialization.XmlReflectionImporter
private static ElementAccessor
CreateElementAccessor(TypeMapping mapping, string ns)
{
ElementAccessor elementAccessor = new ElementAccessor();
bool flag = mapping.TypeDesc.Kind == TypeKind.Node;
if (!flag && mapping is SerializableMapping)
{
flag = ((SerializableMapping)mapping).IsAny;
}
if (flag)
{
elementAccessor.Any = true;
}
else
{
elementAccessor.Name = mapping.DefaultElementName;
elementAccessor.Namespace = ns;
}
// truncated
}

似乎 XElement 类型映射将 Any 属性值设置为 true 但没有获得 DefaultElementName.

该问题的一个简单解决方法是创建一个派生类:

public class FooBarService : System.Web.Services.WebService
{
[WebMethod]
public MyXElement Foo(string bar)
{
return null;
}
}
public class MyXElement : XElement
{
public MyXElement()
: base(XName.Get("default")) { }
}

这将在堆栈中调用:

System.Web.Services.Description.SoapProtocolReflector.ReflectMethod()

而不是 HttpPostProtocolReflector.ReflectMethod() 方法和正确分配的名称:

messagePart.Name = members[0].MemberName;

为了回答您的问题,当您将 XElement 作为参数分配时方法调用起作用的原因是因为类型映射是通过其他方法和 name 成员不为空。因此引发异常的条件不会发生。

关于c# - 从 .ASMX Web 服务返回 XElement,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17484396/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com