Cannot use System.Object type within WCF WebService - wcf

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.

Related

KnownType for MessageContract in WCF

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.

WCF service with ninject extension

i got problem with my wcf service with ninject extension. When my service doesnt have parameterless constructor when im trying to call it i got error that im missing it, when i got parameterless constructor:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class ContractService: IContractService
{
public ContractService()
: this(new AddressService(), new TelephoneService())
{
}
[Inject]
public ContractWCFService(IAddressService addressService, ITelephoneService telephoneService)
{
_addressService = addressService;
_telephoneService = telephoneService;
}...
}
then, parameterless one is called and i think the second one with attribute [Inject] should be called.
Edit : NinjectWebCommon:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ServiceHost>().To<NinjectServiceHost>();
kernel.Bind<IAddressService>().To<AddressService>().InHttpRequestScope();
kernel.Bind<TelephoneService>().To<TelephoneService>().InHttpRequestScope();
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InHttpRequestScope();
kernel.Bind(typeof(EFModel)).ToSelf().InHttpRequestScope();
IoC.Initialize((StandardKernel)kernel);
}
Any ideas?
For passing parameters / managing your instance with ninject, you should combine Instance Provider
and / or specific ninject extenstion.
This post can be also helpful: Passing parameters to a WCF ServiceHost type with Ninject 2

WCF - call method from service implementation

What I'm trying to do is the following:
1) I have the following WCF service contract:
[ServiceContract]
public interface IUploadService
{
[OperationContract]
ServiceData Upload(Request request);
}
[DataContract]
public class Request
{
[DataMember]
public long AbnNumber;
[DataMember]
public string Email;
}
2) This contract is implemented like this.
public class UploadService : IUploadService
{
public bool Upload(Request request)
{
// Some code
}
}
In the "Some code" section I would like to call a validation class to validate the clients request, so something like this:
var result = validation.ValidateRequest(request);
So my question is: Is it a bad idea to create an instance of my validation class inside the Upload method? Like this:
public class UploadService : IUploadService
{
public bool Upload(Request request)
{
var validation = new Validation();
var result = validation.ValidateRequest(request);
}
}
I know you can get around this by creating a constructor but as far as I know you can't create a constructor inside a WCF service implementation class, or am I wrong?
I'm new to WCF so if I'm totally heading the wrong direction please let me know.
Thanks
Personally I like as little as possible in my service methods. I would have a separate project to handle the Upload. This then allows you to reuse this code more easily, and to test the functionality without creating the service.
As to whether you should create your Validation like this it really depends on what it does, but generally I would make sure the Validation class implements an interface containing ValidateRequest(Request) and then inject that. You can then mock it in your tests if you need to.
So your service code would look like
public class UploadService : IUploadService
{
private readonly IUploadHandler _uploadHandler;
public UploadService(IUploadHandler uploadHandler)
{
_uploadHandler = uploadHandler;
}
public bool Upload(Request request)
{
//would possibly do some mapping here to create a different type of object to pass to the handler
_uploadHandler.Upload(request);
}
}
and the handler in a different project would look like
public class UploadHandler : IUploadHandler
{
private readonly IValidation _validator;
public UploadHandler(IValidation validator)
{
_validator = validator;
}
public bool Upload(Request request)
{
return _validator.ValidateRequest(request);
}
}
So my question is: Is it a bad idea to create an instance of my validation class inside the Upload method?
It comes down to whether you will be using Singleton or Per Call services. Usually it is better to have new instance of Service created for every request, and in that case it is OK to create all instances in your operation.
Interesting discussion on this topic Should WCF service typically be singleton or not?
If you decide to not to create Validation class for each then request there are two options:
Make it singleton
Create custom ServiceHostFactory for your service and initialize your Service in it (with constructor). Useful links on this topic:Extending Hosting Using ServiceHostFactory, Integrating StructureMap with WCF

using class interface as a parameter in wcf service

I Have WCF Service Contract and Using a class interface as a parameter as follow :
[ServiceContract(Name = "IFrameworkBaseService", CallbackContract = typeof(IFrameworkBaseServiceCallback))]
public interface IFrameworkBaseService
{
[OperationContract]
void InitializeConnection(IClientID clientID);
}
but I get the following error :
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state
Can anyone help me by this problem
Thanks
Afshin
I think the concret object you passed in for the IClientID is just unknown to the service.
You have to add it with KnownType-Attribute
[ServiceContract(Name = "IFrameworkBaseService", CallbackContract = typeof(IFrameworkBaseServiceCallback))]
[KnownType(typeof(MyClientId))]
public interface IFrameworkBaseService
{
[OperationContract]
void InitializeConnection(IClientID clientID);
}

Type not exposed by WCF Service

I have a small test web service to emulate something odd I'm noticing in a real world app. As the demo shows the same behaviour as the app I will use the demo for brevity.
In short My service interface file looks as follows (as you can see it is the default WCF service created by VS2008 but I have added a new public method (GetOtherType()) and two new classes at the bottom (SomeOtherType and SomeComplexType). SomeOtherType manages a generic List of type SomeComplexType
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WCFServiceTest
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
[OperationContract]
SomeOtherType GetOtherType();
}
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
[DataContract]
public class SomeOtherType
{
public List<SomeComplexType> Items { get; set; }
}
[DataContract]
public class SomeComplexType
{
}
}
My Service is implemented as follows
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WCFServiceTest
{
public class Service1 : IService1
{
#region IService1 Members
public string GetData(int value)
{
throw new NotImplementedException();
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
throw new NotImplementedException();
}
#endregion
#region IService1 Members
public SomeOtherType GetOtherType()
{
throw new NotImplementedException();
}
#endregion
}
}
The problem I have is that if I include a service reference to this service in an ASP.NET Web Application, I cannot see SomeComplexType via intellisense. The error relates to the type or namespace cannot be found. However, SomeOtherType can be found (I'm assuming as the type is a return type from one of the public methods).
Am I right in thinking I can't expose a type from a WCF Service if that type is not featured in the method signature of one of my public methods (either return type or argument)? If so, how would I be able to iterate over the Items inside an instance of SomeOtherType on the client?
Many Thanks and I hope this is clear.
Simon
The problem I have is that if I
include a service reference to this
service in an ASP.NET Web Application,
I cannot see SomeComplexType via
intellisense. The error relates to the
type or namespace cannot be found.
However, SomeOtherType can be found
(I'm assuming as the type is a return
type from one of the public methods).
Am I right in thinking I can't expose
a type from a WCF Service if that type
is not featured in the method
signature of one of my public methods
(either return type or argument)? If
so, how would I be able to iterate
over the Items inside an instance of
SomeOtherType on the client?
You are absolutely right - your SomeComplexType is never used in any of the service methods, and it's also never tagged as a [DataMember] in any of the types that are indeed used as parameters in your service methods. Therefore, from the point of view of WCF, it's not needed, and won't show up in the WSDL/XSD for the service.
As Graham already pointed out - you are using the SomeComplexType in one place:
[DataContract]
public class SomeOtherType
{
public List<SomeComplexType> Items { get; set; }
}
but since the Items element is not tagged as a [DataMember], it (and therefore the type it uses) will not be included in the WSDL/XSD of your service. Since the Items are not marked as DataMember, they won't be in your serialized WCF message either, so you won't ever need to iterate over this collection :-)
So most likely, what you really want, is just add the [DataMember] attribute to your Items property; then it'll be included in the WSDL/XSD, and so will the SomeComplexType.
Looks like you need the [DataMember] attribute on your SomeOtherType.Items property, i.e.
[DataMember]
public List<SomeComplexType> Items { get; set; }
I'm not at all an expert on this topic, so just as a shot in the blue: Empty DataContracts are discarded by WCF? Try exposing anything in ComplexDataType (some int is enough) and see if that changes anything.
Also, I believe you can verify the availability of the type using the built-in wcftestclient (you need to turn metadata exchange on for this).
We can use Known type in Service in order to get exposed of the class and its members when it is not used in the operation contract signature directly or indirectly.
For such types where you just want it to be available on the client side even if its not used, below attribute class is handy to make it available on client side.
[KnownType(typeof(SomeComplexType))]