I have several WCF service contracts, all of which contain exactly the same method StopOperation, having the same signature:
[ServiceContract]
public interface IMyServiceA
{
[FaultContract(typeof(ServiceAError))]
[OperationContract]
void StopOperation(TaskInformation taskInfo);
// other specific methods
}
What I'd like to be able to do is to extract StopOperation into an interface, IStoppable, and have all my services inherit this operation. However, I have a problem with the FaultContract definition, as it defines a concrete fault type.
Is it possible to have FaultContract refer to an abstract ErrorBase type, and have the concrete ones specified by KnownContract somehow? Kind of like:
[ServiceContract]
public interface IStoppable
{
[FaultContract(typeof(ErrorBase))]
[OperationContract]
void StopOperation(TaskInformation taskInfo);
}
No matter where I tried specifying KnownContract, it didn't seem to take.
Have you tried using a generic type ?
For instance:
[ServiceContract]
public interface IStoppable<T> where T : ErrorBase
{
[FaultContract(typeof(T))]
[OperationContract]
void StopOperation(TaskInformation taskInfo);
}
Then you'd say
[ServiceContract]
public interface IMyServiceA : IStoppable<ServiceAError>
{
// other specific methods
}
Haven't tested this, but I don't see any reason why this shouldn't work.
Related
I am using Stream object inside my wcf Contracts so forced to use MessageContract instead of DataContract.
[MessageContract]
public class Document
{
[MessageBodyMember(Order = 1)]
public System.IO.Stream FileData;
}
[MessageContract]
public class A : Document
{
[MessageBodyMember]
public string input;
}
[MessageContract]
public class B : Document
{
[MessageBodyMember]
public string someProp;
}
[ServiceContract]
public interface ISomeService
{
[OperationContract]
Document SomeMethod(Document file);
}
I want the consumer of this service to create object of either A or B and call the service with it. On the service side, I can type cast it to proper object then perform some action.
Problem is I cannot specified KnownType with MessageContract and inherited contracts cannot be exposed to client until they are used in service or declared with KnownType.
I tried google it but couldn't find anything related to KnownType with MessageContract.
As suggested in comment... i updated my message contract with KnownType but they are still not exposed to client through service reference...
[MessageContract]
[KnownType(typeof(FileSystemStoredDocument))]
[KnownType(typeof(FileBoundStoredDocument))]
[KnownType(typeof(SharepointStoredDocument))]
public class Document : DocumentInfo, IDisposable
{
}
Can any one help me what's wrong here?
Note: ALL KnownType are inherited from Document
Message contracts describe exactly how the message should look like. They do support inheritance, but you must specify the exact message contract you're using in a specific operation.
If you check the body parts of the message:
ContractDescription.GetContract(typeof(ISomeService)).Operations[0].Messages[0].Body.Parts
You'll see exactly one part - a Stream object. That's in contrast to data contracts, where the body contains a part of the type Object. So you see why KnownType wouldn't work here.
(The ContractDescription class is used, among other things, to generate WSDL. See the WsdlExporter class.)
What you can do is create a hierarchy of data contracts that would be contained in the message contract, e.g.
[MessageContract]
public class Document
{
[MessageHeader]
public DocumentProperties Properties;
[MessageBodyMember(Order = 1)]
public System.IO.Stream FileData;
}
[DataContract]
[KnownType(typeof(A))]
[KnownType(typeof(B))]
public abstract class DocumentProperties { }
[DataContract]
public class A : DocumentProperties
{
[DataMember]
public string input;
}
[DataContract]
public class B : DocumentProperties
{
[DataMember]
public string someProp;
}
Note that you you cannot have more than one body member if you want to pass a Stream, so the rest of the properties must be in headers.
I am using a wcf web service as the persistence layer for a backbone.js application.
[OperationContract]
[WebGet]
public IEnumerable<AnalysisParameterSet> AnalysisParameters()
{
// implementation
}
[OperationContract]
[WebInvoke(Method = "POST")]
public void AnalysisParameters(IEnumerable<AnalysisParameterSet> parameterSets)
{
// implementation
}
I would like to create two methods on the service with the same name, but different signatures, one for GET and one for POST.
However wcf is complaining that there are 2 methods with the same name. I am aware I could use the name property of the OperationContract to differentiate them. This is not ideal as backbone prefers for the methods to share the same name.
Can i use the same method name for both GET and POST?
If I can't do this in WCF. How would I modifiy backbone.js to use a different method for post and Get.
I believe what you want is something like:
[OperationContract]
[WebGet(UriTemplate = "/AnalysisParameters")]
public IEnumerable<AnalysisParameterSet> GetAnalysisParameters()
{
// implementation
}
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/AnalysisParameters")]
public void PostAnalysisParameters(IEnumerable<AnalysisParameterSet> parameterSets)
{
// implementation
}
Depending on the http method (post/get), one or the other function will be called.
I'm trying to create a method using the object type within my WCF WebService, but I get the following error :
Interface :
[ServiceContract]
public interface IService1
{
[OperationContract]
object GetTwoX(object yo);
}
Class :
public class Service1 : IService1
{
static public Dictionary<string, List<OPUSInfo>> cache;
public object GetTwoX(object yo)
{
return yo;
}
}
Does somebody know how to pass Object type in ?
You can definitely create a method which takes and/or returns object, but as the error says, don't expect the simplistic Test Client to be able to do anything. Use a full-featured service testing application like SoapUI to do that.
I have a very strange problem.
I have a working WCF service.
[ServiceContract]
public interface IService
{
[OperationContract]
int AddResult(int result, string name);
[OperationContract]
int list(int count);
}
In another class I have the implementation of this service. And it works.
But when I change the method "list" like this:
[ServiceContract]
public interface IService
{
[OperationContract]
int AddResult(int result, string name);
[OperationContract]
List<string> list(int count);
}
When I add service reference from targeted project (it is a Windows Phone application) I receive several errors and warnings. The key idea of them is that the service cannot be loaded (or endpoints can not be loaded).
The difference between two methods is very small - List instead of int type. But it is crucial.
Why it is so? Why I can not use List?
did you try to encapsulate your List collection into a proxy class? You could try something like:
[DataContract]
public class MyData
{
[DataMember]
public List<string> list { get; set; }
}
[ServiceContract]
public interface IService
{
[OperationContract]
int AddResult(int result, string name);
[OperationContract]
MyData list(int count);
}
Also, take a look at this link, I think that it might be what you are looking for.
UPDATE
As per discussed on the comments section of this thread, the problem was not located in the WCF service itself, but on the client that was being generated in #user1460819 Windows Phone app.
This problem was solved after the WCF Service binding was changed to "basicHttpBinding", the WCF reference on the client side was regenerated and the whole project was rebuilt.
I have built a WCF service library, I have added reference to few 3rd party dll's. This is my interface
[ServiceContract]
public interface IService1
{
[OperationContract]
3rdpartyreturntype GetObj(System.Windows.Controls.Control txtcontrol);
}
// Use a data contract as illustrated in the sample below to add composite types to service operations
[DataContract]
public class nclass
{
[DataMember]
public System.Windows.Controls.Control txtcontrol
{
get { return txtcontrol; }
set { txtcontrol = value; }
}
[DataMember]
public 3rdpartyreturntype nobj
{
get { return vuiobj; }
set { vuiobj = value; }
}
[DataMember]
public System.Windows.Input.TouchDevice tchdev
{
get { return tchdev; }
set { tchdev = value; }
}
}
and I have implemented the above interface. When I run the service I get the below error, can anyone help me out?
type 'System.Windows.Input.TouchDevice' cannot be serialized. Consider
marking it with the DataContractAttribute attribute, and marking all
of its members you want serialized with the DataMemberAttribute
attribute.
if you want a complex type like a class to be serialized you have to declare each of its members as data member and class as datacontract.
In this case touch device is the complex type(class) so you need to mark all of its members as datamembers and class as datacontract.
but as i can see from type that it belongs to system.windows.input the class may not be serialized. hence you cannot use this as a data member.
If you are using only a set of members belonging to touchDevice class, you can create your own class which will map only the set of touchdevice members which can be serialized. and decorate this new class with datacontract and datamember attributes.
It would appear that the type "System.Windows.Input.TouchDevice" is itself not marked as serializable or a DataContract.
Instead of trying to pass the TouchDevice and the Control directly like that, maybe you can just pass the properties you care about. I'm guessing in the case of the TextControl you just care about the Text value. And for the TouchDevice, maybe the source and target control name?