好吧,我正在尝试开发一个肥皂客户端,它希望将其自定义的soapheader(即usercred)序列化,但是这样做之后,我得到了这个错误
System.Runtime.Serialization.InvalidDataContractException:'Type'ConsoleApp1.Program + usercred'无法从未标记DataContractAttribute或SerializableAttribute的类型继承。考虑使用DataContractAttribute或SerializableAttribute标记基本类型System.Web.Services.Protocols.SoapHeader
,或将它们从派生类型中删除。'
有点希望soapheader也可以序列化plz帮助
答案 0 :(得分:0)
有几种方法可以在汤请求中添加自定义汤头。
例如,您可以使用HTTPRequest创建汤请求,您可以在其中构建汤信封。 Client to send SOAP request and receive response
public override string Process(string UserName,string Password)
{
string uri = "https://serviceURL";
HttpWebRequest req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(uri));
req.ContentType = "application/soap+xml; charset=utf-8";
req.Method = "POST";
string soapRequest = BuildSoapRequest(UserName,Password);
StreamWriter stm = new StreamWriter(req.GetRequestStream(), Encoding.UTF8);
stm.Write(soapRequest);
stm.Close();
try
{
HttpWebResponse wr = (HttpWebResponse)req.GetResponse();
StreamReader srd = new StreamReader(wr.GetResponseStream());
string response = srd.ReadToEnd();
return ExtractResponse(response);
}
catch (WebException e)
{
string error = "";
HttpWebResponse errRsp = (HttpWebResponse)e.Response;
if (errRsp != null)
{
using (StreamReader rdr = new StreamReader(errRsp.GetResponseStream()))
{
string line;
while ((line = rdr.ReadLine()) != null)
{
error += line;
}
}
}
throw new Exception(e.Message + "<br/> " + error);
}
catch (Exception e)
{
throw e;
}
}
private string BuildSoapRequest(string UserName,string Password)
{
StringBuilder soapRequest = new StringBuilder();
soapRequest.Append("<soap:Envelope xmlns:cor=\"http://www.caqh.org/SOAP/WSDL/CORERule2.2.0.xsd\" xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:tem=\"http://tempuri.org/\">");
soapRequest.Append("<soap:Header>");
soapRequest.Append("<wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">");
soapRequest.Append("<wsse:UsernameToken>");
soapRequest.Append("<wsse:Username>" + UserName + "</wsse:Username>");
soapRequest.Append("<wsse:Password>" + Password + "</wsse:Password>");
soapRequest.Append("</wsse:UsernameToken>");
soapRequest.Append("</wsse:Security>");
soapRequest.Append("</soap:Header>");
soapRequest.Append("<soap:Body>");
soapRequest.Append("</soap:Body>");
soapRequest.Append("</soap:Envelope>");
return soapRequest.ToString();
}
private static string ExtractResponse(string soap)
{
}
如果您正在使用WCF服务,则可以在请求中添加自定义行为。 Custom Endpoint Behavior not being used in WCF Client with Service Reference
public class CustomClientBehavior : IEndpointBehavior
{
string _username;
string _password;
public CustomClientBehavior(string username, string password)
{
_username = username;
_password = password;
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
CustomInspector inspector = new CustomInspector(_username, _password);
clientRuntime.MessageInspectors.Add(inspector);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
public class CustomClientBehaviorExtensionElement : BehaviorExtensionElement
{
string _username;
string _password;
public CustomClientBehaviorExtensionElement(string username, string password)
{
_username = username;
_password = password;
}
public override Type BehaviorType
{
get { return typeof(CustomClientBehavior); }
}
protected override object CreateBehavior()
{
return new CustomClientBehavior(_username, _password);
}
}
public class CustomInspector : IClientMessageInspector
{
string _username;
string _password;
public CustomInspector(string username, string password)
{
_username = username;
_password = password;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
return;
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
request.Headers.Clear();
string headerText = "<wsse:UsernameToken xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">" +
"<wsse:Username>{0}</wsse:Username>" +
"<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">" +
"{1}</wsse:Password>" +
"</wsse:UsernameToken>";
headerText = string.Format(headerText, _username, _password);
XmlDocument MyDoc = new XmlDocument();
MyDoc.LoadXml(headerText);
XmlElement myElement = MyDoc.DocumentElement;
System.ServiceModel.Channels.MessageHeader myHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", myElement, false);
request.Headers.Add(myHeader);
return Convert.DBNull;
}
}
测试客户端应类似于
TestService.Client objClient = new TestService.Client();
objClient.Endpoint.Behaviors.Add(new CustomClientBehavior(UserName, Password));