I have the following class generated from svcutl.. using a wsdl. Using the wsdl, xsd's provided by the third party svcutil generated a class file.
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://someURL/2008")]
public partial class DocImgIdxType_Type
{
private string valueField;
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
public partial class DocImgIdx_CType
{
private DocImgIdxType_Type docImgIdxTypeField;
/// <remarks/>
public DocImgIdxType_Type DocImgIdxType
{
get
{
return this.docImgIdxTypeField;
}
set
{
this.docImgIdxTypeField= value;
}
}
The soap XMl gets generated in this way.
<d4p1:DocImgIdx_CType>
<d4p1:docImgIdxTypeField>
<d4p1:valueField>Document Type</d4p1:valueField>
</d4p1:docImgIdxTypeField>
</d4p1:DocImgIdx_CType>
But the service is expecting a XML which looks like this
<DocImgIdx>
<DocImgIdxType>Document Type</DocImgIdxType>
</DocImgIdx>
Why is the response being generated with docImgIdxTypeField private member of the DocImgIdxType_Type class?. How do I remove valueField tags.. I have tried using [System.Xml.Serialization.XmlElementAttribute("..")] but not there yet. Can this be done using formatter or do I need custom message encoder? If there is a straightforward way to change the response I would like to do that.
Related
I have created WCF service. It is working fine but our client want response in some specific form. I have shared 2 responses
My Code :
[ServiceContract]
public interface IService
{
[OperationContract]
MyClass GetMyData();
// TODO: Add your service operations here
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class MyClass
{
int _id ;
string _name ;
[DataMember]
public int ID
{
get { return _id; }
set { _id = value; }
}
[DataMember]
public string Name
{
get { return _name; }
set { _name = value; }
}
}
Your "Client Expectation" is a XSD file. They are meant to validate SOAP responses, not to be one.
There are plenty of services which can validate your XML response based on your XSD.
If you client wants a XSD response, maybe you'll have to look for a tool to do that. I think this might help.
[CollectionDataContract(Namespace = "CISICPD")]
[KnownType(typeof(List<CISICPD.LeeDictionary>))]
public class LeeDictionary : Dictionary<string, object>
{
}
[DataContract(Namespace = "CISICPD")]
[KnownType(typeof(List<CISICPD.LeeDictionary>))]
public class TestResponse
{
[DataMember]
public List<LeeDictionary> Results;
public TestResponse() { Results = new List<LeeDictionary>(); }
[OnDeserializing]
private void OnDeserialize(StreamingContext c) { Results = new List<LeeDictionary>(); }
}
if the above is used in a service reference the generated reference.cs simply ignores the knowntypes specified above.
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="TestResponse", Namespace="CISICPD")]
[System.SerializableAttribute()]
public partial class TestResponse : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
I specified the LeeDictionary so i could set my own namespace (thought it might be namespace issues), changing it to Dictionary<string,object> is just the same. The problem comes when the dictionary itself contains another dictionary and complains that the type is not known.
If I add the knowntype line to the reference.cs it then all works but I cant see why it wont put it in when generating the references?
I want to expose as WCF service two set of classes that have the same name. However, when I add the service reference, it only returns one set of the class.
[ServiceContract(Name = "Service1")]
[XmlSerializerFormat]
public interface IService1
{
[OperationContract]
[ServiceKnownType(typeof(S1.Retangle))]
[ServiceKnownType(typeof(S1.Square))]
[ServiceKnownType(typeof(S2.Retangle))]
[ServiceKnownType(typeof(S2.Square))]
string GetShape(Shape shape);
}
//All types are only example
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute()]
public abstract class Shape
{
public int Width { get; set; }
public int Height { get; set; }
public string TypeName { get; set; }
}
namespace S1
{
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute()]
public class Retangle : Shape
{ }
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute()]
public class Square : Shape
{ }
}
namespace S2
{
//[DataContract]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "Namespace=http://tempuri.org/S2")] //can be changed
public class Retangle : Shape
{ }
//[DataContract]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "Namespace=http://tempuri.org/S2")] //can be changed
public class Square : Shape
{ }
}
Any idea would be very much appreciated.
WCF will generate your objects in its own namespace for use client side but your not forced to use these - you can equally well use your own original objects in the namespaces they were defined by either:
1. Compiling them in a dll and linking to that for both client and sever.
2. If you dont want overhead of shared dll just compile them directly into both server and client.
In the generated proxy code you just need to replace the WCF namespace tags with your own org namespaces so they resolve to your objects and the client side WCF generated ones are ignored.
When I try to import a WSDL (http://ns.hr-xml.org/schemas/org_hr-xml/3_0/Services/Web_Services/WSDL/TimeCard.wsdl) via WCF Test Client I get the "
WCF Operation not supported in WCF Test Client"
because it uses type " error message as shown on screenshot.
The contract looks like below, I'm not sure why I'm getting above error message. Could some one please guide me to right direction:
[System.ServiceModel.OperationContractAttribute(Action="ChangeTimeCard", ReplyAction="*")]
[System.ServiceModel.FaultContractAttribute(typeof(HRXMLTimeCard.HRXML_Candidate_3_1.ConfirmBODType), Action="ChangeTimeCard", Name="ConfirmBOD", Namespace="http://www.openapplications.org/oagis/9")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(BinaryObjectType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(AmountType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(QuantityType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(PreferenceABIEType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(AddressBaseType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(NameType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(PersonNameBaseType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(TimePeriodABIEType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(TextType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(CodeType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(StatusBasisType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(VerbType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(ResponseCodeType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(IdentifierType))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(BusinessObjectDocumentType))]
HRXMLTimeCard.HRXML_Candidate_3_1.ProcessTimeCardResponse ChangeTimeCard(HRXMLTimeCard.HRXML_Candidate_3_1.ChangeTimeCardRequest request);
And this is the ChangeTimeCardRequest class:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class ChangeTimeCardRequest {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.hr-xml.org/3", Order=0)]
public HRXMLTimeCard.HRXML_Candidate_3_1.ChangeTimeCardType ChangeTimeCard;
public ChangeTimeCardRequest() {
}
public ChangeTimeCardRequest(HRXMLTimeCard.HRXML_Candidate_3_1.ChangeTimeCardType ChangeTimeCard) {
this.ChangeTimeCard = ChangeTimeCard;
}
}
Below is the ChangeTimeCardType:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.225")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.hr-xml.org/3")]
public partial class ChangeTimeCardType : BusinessObjectDocumentType {
private ChangeTimeCardDataAreaType dataAreaField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public ChangeTimeCardDataAreaType DataArea {
get {
return this.dataAreaField;
}
set {
this.dataAreaField = value;
this.RaisePropertyChanged("DataArea");
}
}
}
Also, if wsdl doesn't work in WCF Test Client, does it mean it won't work for all clients ie. Java or php?
I think your problem here is that WCF doesn't understand the type HRXMLTimeCard.HRXML_Candidate_3_1.ChangeTimeCardType. Where is the code for the HRXMLTimeCard.HRXML_Candidate_3_1.ChangeTimeCardType class?
Did you try without any serialization parameters ? (ex: removing [System.Xml.Serialization.XmlElementAttribute(Order=0)])
I am trying to capture links that were added to a work item in TFS by catching WorkItemChangedEvent via TFS services. Here is the relevant XML part of the message that comes through:
<AddedRelations><AddedRelation><WorkItemId>8846</WorkItemId></AddedRelation></AddedRelations>
This is declared as a field in WorkItemChangedEvent class that should be deserialized into object upon receiving the event:
public partial class WorkItemChangedEvent
{
private string[] addedRelations;
/// <remarks/>
[XmlArrayItemAttribute("WorkItemId", IsNullable = false)]
public string[] AddedRelations
{
get { return this.addedRelations; }
set { this.addedRelations = value; }
}
}
I cannot figure out why the AddedRelations does not get deserialized properly.
I can only suspect that the object structure does not match the XML schema.
I have changed the structure of my WorkItemChangedEvent class a little bit to match the XML:
public partial class WorkItemChangedEvent
{
private AddedRelation[] addedRelations;
/// <remarks/>
[XmlArrayItemAttribute("AddedRelation", IsNullable = false)]
public AddedRelation[] AddedRelations
{
get { return this.addedRelations; }
set { this.addedRelations = value; }
}
[GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[SerializableAttribute()]
[DebuggerStepThroughAttribute()]
[DesignerCategoryAttribute("code")]
[XmlTypeAttribute(Namespace = "")]
public partial class AddedRelation
{
#region Fields
private string workItemId;
#endregion
/// <remarks/>
public string WorkItemId
{
get { return this.workItemId; }
set { this.workItemId = value; }
}
}
}
I still think that there must be some logic behind the original solution since it was designed by TFS authors (MS)? Anyway I am glad it works now and that I answered my question first ;]