I have a web service as the following :
1: [WebService(Namespace = "http://app.trend.com/services/flowService/xml")]
2: [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
3: public class Processor : System.Web.Services.WebService {
4: [WebMethod]
5: public Step GetStepInfo(string msgInstId, string stepId) {...}
6: //...
7: }
For the Step class returned by this GetStepInfo() method, the definition is as the following :
1: [Serializable]
2: public class Step : BaseStep {
3: public StepNode() { }
4:
5: public string ID { get; set; }
6:
7: public string Name { get; set; }
8: //...
9: }
And BaseStep:
1: [Serializable]
2: public class BaseStep{
3: public string Comments { get; set; }
4: }
To consume this web service via WCF client, for some design concerns, I need to create a channel to operate the service, not just reference the service and invoking the method generated by the system. So I created a IProcessor interface and start to create certain methods…etc.
These is what I created and how I invoke the service :
1: [ServiceContract(Namespace = "http://app.trend.com/services/flowService/xml")]
2: public interface IProcessor{
3: //[OperationContract(Action = "http://app.trend.com/services/flowService/xml/GetStepInfo", ReplyAction="*")]
4: [OperationContract]
5: Trend.BPM.APPs.XmlFlowEngine.StepNode GetStepInfo(string msgInstId, string stepId);
6:
7: //[System.ServiceModel.OperationContractAttribute(Action = "http://app.trend.com/services/flowService/xml/StartCase", ReplyAction = "*")]
8: [OperationContract]
9: bool StartCase(string flowName, string msgId, string currentStepID, string owner, string action, string comments, string paramatersXml);
10:
11: //[System.ServiceModel.OperationContractAttribute(Action = "http://app.trend.com/services/flowService/xml/ReleaseCase", ReplyAction = "*")]
12: [OperationContract]
13: string ReleaseCase(string msgId, string stepID, string owner, string action, string comments, string paramaterXML);
14:
15: //[System.ServiceModel.OperationContractAttribute(Action = "http://app.trend.com/services/flowService/xml/GetNextApproverEx", ReplyAction = "*")]
16: [OperationContract]
17: bool GetNextApproverEx(string msgId, string flowName, string currentStep, string currentApprover, string category, out string nextApprover, out string newStep);
18: }
And how I invoke the service:
1: ChannelFactory<IXmlFlowEngine> channel = new ChannelFactory<IXmlFlowEngine>(new BasicHttpBinding(BasicHttpSecurityMode.None));
2: var svc = channel.CreateChannel(new EndpointAddress(url));
Everything looks good until I actually run the program, I got the following error:
Server did not recognize the value of HTTP Header SOAPAction:http://app.trend.com/services/flowService/xml/IProcessor/GetStepInfo
I have this error because WCF serializer does not recognize the namespace and could not serialize/deserialize the message to objects. So I add namespace to my interface and Setp/StepBase class as following
1: [ServiceContract(Namespace = "http://app.trend.com/services/flowService/xml", Name = "IProcessor")]
2: public interface IXmlFlowEngine {
3: [OperationContract(Action = "http://app.trend.com/services/flowService/xml/GetStepInfo", ReplyAction="*")]
4: Trend.BPM.APPs.XmlFlowEngine.StepNode GetStepInfo(string msgInstId, string stepId);
5:
6: [System.ServiceModel.OperationContractAttribute(Action = "http://app.trend.com/services/flowService/xml/StartCase", ReplyAction = "*")]
7: bool StartCase(string flowName, string msgId, string currentStepID, string owner, string action, string comments, string paramatersXml);
8:
9: [System.ServiceModel.OperationContractAttribute(Action = "http://app.trend.com/services/flowService/xml/ReleaseCase", ReplyAction = "*")]
10: string ReleaseCase(string msgId, string stepID, string owner, string action, string comments, string paramaterXML);
11:
12: [System.ServiceModel.OperationContractAttribute(Action = "http://app.trend.com/services/flowService/xml/GetNextApproverEx", ReplyAction = "*")]
13: bool GetNextApproverEx(string msgId, string flowName, string currentStep, string currentApprover, string category, out string nextApprover, out string newStep);
14: }
And explicitly specify the Name property on each class member
1: [Serializable]
2: [DataContract(Name="Step",Namespace="http://app.trend.com/services/flowService/xml")]
3: public class Step : XmlFlowNode {
4: public StepNode() { }
5: [DataMember(Name="ID",EmitDefaultValue=false)]
6: public string ID { get; set; }
7: }
1: [Serializable]
2: [DataContract(Name="StepBase",Namespace="http://app.trend.com/services/flowService/xml")]
3: public class StepBase{
4: [DataMember(Name="Comments",EmitDefaultValue=false)]
5: public string Comments { get; set; }
6: }
And this fixed the issue.
沒有留言:
張貼留言