强制参数作为服务合同属性
Force parameter as Service contract attribute
我需要为非常具体的 SOAP 布局编写服务合同(端点不在我们的控制之下)。本质上,我需要生成以下 soap 请求:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<auth message-id="1">
<login>
<UserName>goLocalTeam</UserName>
<Password>yeay!</Password>
</login>
</auth>
</soapenv:Body>
</soapenv:Envelope>
我创建了以下合约:
[ServiceContract(Namespace="", SessionMode=SessionMode.NotAllowed)]
public interface IPrototype
{
[OperationContract(Action="auth")]
string auth([MessageParameter(Name = "message-id")]int messageId, Login login);
}
[DataContract(Namespace="")]
public class Login
{
[DataMember]
public string userName { get; set; }
[DataMember]
public string Password { get; set; }
}
但是,当我构建客户端并调用时,message-id
参数呈现为 <auth>
中的节点,而不是属性。
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">auth</Action>
</s:Header>
<s:Body>
<auth>
<message-id>0</message-id>
<login>
<userName>yay</userName>
<Password>yoy</Password>
</login>
</auth>
</s:Body>
</s:Envelope>
知道如何让 WCF 将简单类型参数从节点切换到属性吗?
使用 XmlSerializerFormat
属性而不是 DataContract
。
看看 MSDN 以了解如何使用它,但基本上你用 XmlAttribute
和 XmlElement
标记成员,所以它看起来像:
[ServiceContract(Namespace="", SessionMode=SessionMode.NotAllowed)]
public interface IPrototype
{
[OperationContract(Action="auth")]
string Auth(AuthRequest authRequest);
}
[MessageContract(IsWrapped = false)] // notice the unwrapping
public class AuthRequest
{
[XmlAttribute]
public int message-id { get; set; }
[XmlElement]
public Login Login { get; set; }
}
[MessageContract]
public class Login
{
[XmlElement]
public string userName { get; set; }
[XmlElement]
public string Password { get; set; }
}
好的,我解决了它,部分归功于 user3906922,使用 xml 序列化器格式。我只需要更深入地构建消息:
[ServiceContract(Namespace="", SessionMode=SessionMode.NotAllowed)]
public interface IPrototype
{
[OperationContract(Action = "auth")]
[XmlSerializerFormat]
authResponse auth(authRequest auth);
}
[MessageContract(IsWrapped = false)]
public class authRequest
{
[MessageBodyMember]
public authRequestBody auth { get; set; }
}
[MessageContract(IsWrapped = true, WrapperName = "auth")]
public class authRequestBody
{
[XmlAttribute(AttributeName = "message-id"), MessageBodyMember]
public int messageId { get; set; }
[MessageBodyMember]
public Login login { get; set; }
}
[MessageContract]
public class Login
{
[MessageBodyMember]
public string userName { get; set; }
[MessageBodyMember]
public string Password { get; set; }
}
我需要为非常具体的 SOAP 布局编写服务合同(端点不在我们的控制之下)。本质上,我需要生成以下 soap 请求:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<auth message-id="1">
<login>
<UserName>goLocalTeam</UserName>
<Password>yeay!</Password>
</login>
</auth>
</soapenv:Body>
</soapenv:Envelope>
我创建了以下合约:
[ServiceContract(Namespace="", SessionMode=SessionMode.NotAllowed)]
public interface IPrototype
{
[OperationContract(Action="auth")]
string auth([MessageParameter(Name = "message-id")]int messageId, Login login);
}
[DataContract(Namespace="")]
public class Login
{
[DataMember]
public string userName { get; set; }
[DataMember]
public string Password { get; set; }
}
但是,当我构建客户端并调用时,message-id
参数呈现为 <auth>
中的节点,而不是属性。
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">auth</Action>
</s:Header>
<s:Body>
<auth>
<message-id>0</message-id>
<login>
<userName>yay</userName>
<Password>yoy</Password>
</login>
</auth>
</s:Body>
</s:Envelope>
知道如何让 WCF 将简单类型参数从节点切换到属性吗?
使用 XmlSerializerFormat
属性而不是 DataContract
。
看看 MSDN 以了解如何使用它,但基本上你用 XmlAttribute
和 XmlElement
标记成员,所以它看起来像:
[ServiceContract(Namespace="", SessionMode=SessionMode.NotAllowed)]
public interface IPrototype
{
[OperationContract(Action="auth")]
string Auth(AuthRequest authRequest);
}
[MessageContract(IsWrapped = false)] // notice the unwrapping
public class AuthRequest
{
[XmlAttribute]
public int message-id { get; set; }
[XmlElement]
public Login Login { get; set; }
}
[MessageContract]
public class Login
{
[XmlElement]
public string userName { get; set; }
[XmlElement]
public string Password { get; set; }
}
好的,我解决了它,部分归功于 user3906922,使用 xml 序列化器格式。我只需要更深入地构建消息:
[ServiceContract(Namespace="", SessionMode=SessionMode.NotAllowed)]
public interface IPrototype
{
[OperationContract(Action = "auth")]
[XmlSerializerFormat]
authResponse auth(authRequest auth);
}
[MessageContract(IsWrapped = false)]
public class authRequest
{
[MessageBodyMember]
public authRequestBody auth { get; set; }
}
[MessageContract(IsWrapped = true, WrapperName = "auth")]
public class authRequestBody
{
[XmlAttribute(AttributeName = "message-id"), MessageBodyMember]
public int messageId { get; set; }
[MessageBodyMember]
public Login login { get; set; }
}
[MessageContract]
public class Login
{
[MessageBodyMember]
public string userName { get; set; }
[MessageBodyMember]
public string Password { get; set; }
}