下手將堆棧跟蹤,這表明在異常發生的地方聖
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)
a第二等等,我們得到這個方法:
// 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
類型映射獲取設置爲true
的Any
屬性值,但沒有得到一個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
成員不爲空。所以引發異常的情況不會發生。
相關問題在這裏; http://stackoverflow.com/questions/349769/returning-an-xelement-from-a-web-service - 似乎它可能是一個錯誤? –
@ChrisMcAtackney是的,我已經讀過這個問題,這個鏈接是從其中一個答案中斷開的,其餘的並沒有解決問題。 –
爲什麼不返回一個字符串呢? –