2012年3月2日

[WCF] Server did not recognize the value of HTTP Header SOAPAction:[some namespace]

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.

沒有留言:

About Me