Can I reference a DataContract and its proxy version from same class - wcf

I'm dipping my foot into WCF and am trying to make a simple test project that can both consume the service as a service and also directly instantiate it's classes and work with them.
I had an earlier working version where data passed was just primitive types. However, when I attempted to convert to using data contracts, I'm getting conflicts in whether it's referencing the proxy-declared version of the contract or the version from the project itself.
Question: Is it possible to do this and if so, how would I resolve the data contract references?
private void Test()
{
MyService fssDirect = new MyService(); // direct instantiation
MyServiceClient fssService = new MyServiceClient(); // Service proxy
ClientCredentialsContract Client = new ClientCredentialsContract();
ResponseDataContract Result = new ResponseDataContract();
if (CallAsService)
{
Result = fssService.Create(Client, Request);
}
else
{
Result = fssDirect.Create(Client, Request);
}
}
In the above, any reference to the RequestDataContract and ClientCredentialsContract types indicates
Warning: The type 'MyContracts.RequestDataContract' in 'C:...\Test\MyServiceProxy.cs' conflicts with the imported type 'MyContracts.RequestDataContract' in 'C:...\MyService\bin\Debug\Contracts.dll'. Using the type defined in 'C:...\Test\MyServiceProxy.cs'.
(Names changed and paths shortened to protect the innocent)
Thanks,
John

When you create the proxy for your service, try referencing the assembly which contains the data contracts (if using "Add Service Reference", go to the advanced options, select "reuse types in referenced assemblies"; if using svcutil, use the /r argument). This way the tool won't generate the data contracts and you won't have the conflicts.

Related

wsdl2java code generation for lists of custom objects

I would like to know if the tool "wsdl2java" (Axis2) is able to generate stubs that support getting list of custom ojects.
For instance, if I have a WS that have the following method:
public List<Device> getDevices(){
//...
}
Where Device is a custom class...
This tool can do that?
I changed the return data type of my Web Service to an array because of that:
http://www.ibm.com/developerworks/webservices/library/ws-tip-coding/index.html
And I had to do some changes (some namespaces) to the generated stub (I used ADB)...
I changed that because it was giving me an ADBException: Unexpected subelement ...

WCF service with 4 input parms and 3 out parms gets reordered by Add Service Reference in Proxy Class Project

I've looked in SO and elsewhere and seen questions posed about this along with some answers that still make no sense to me in my case.
I'm refactoring my working VStudio 2010 solution which has:
one project with an ASMX webservice
another separate project for the proxy class (no code here except what is generated by Add Web Reference
another separate project for the client (contains a reference to the
ProxyClass.dll
The new VStudio 2010 solution has:
one project of type WCF service library for the contract by itself (IFileService.cs)
one project of type WCF service library for the implementation of the contract (FileService.cs)
another separate project for the proxy class (no code here except what is generated by Add Service Reference
another separate project for the client (contains a reference to the WCFProxyClass.dll)
Here is the contract which ends with 3 out parameters (and the implementation of same is the same order):
[ServiceContract(Name = "IFileService", Namespace = "http://www.cbmiweb.com/TrimWCF/2011/11")]
public interface IFileService
{
[OperationContract]
public string DownloadFile(string trimURL
, string TrimRecordNumber
, string CallerPC
, string RequestorID
, out byte[] docContents
, out string returnFiletype
, out string returnFilename)
{
Here is what Add Service Reference generated in my proxy class project:
public string DownloadFile(
out byte[] docContents
, out string returnFiletype
, out string returnFilename
, string trimURL
, string TrimRecordNumber
, string CallerPC
, string RequestorID)
{
return base.Channel.DownloadFile(out docContents, out returnFiletype, out returnFilename, trimURL, TrimRecordNumber, CallerPC, RequestorID);
}
I have read answers ranging from "you cannot use out parms in WCF" to "you should not use Add Service Reference but instead use svcutil.exe" to "the order of the parameters do not matter...it will still work".
I am confused about what to do here (and what I've done wrong that led to this re-arranged order and WHY that happened).
First of all, you haven't done anything wrong :). Even though the signatures in the methods in the client and the server are different, they're equivalent wrt the messages which will be produced / consumed by them. You can use that proxy class without any problems, and it should work just as well.
Why this happens is another story - in the service description (WSDL), there are two "messages" for each (non-one-way) operation: one with the input parameters, one with the output parameters. The messages contains respectively the input(s) and output(s) of the operation, but there's nothing in the WSDL which shows the order of them. So when a tool such as Add Service Reference or svcutil is generating the client proxy, it will simply "choose" one order (out parameters first), but the request which the proxy will send to the service will be compatible with what the server expects (and also, the response from the server will be correctly understood by the proxy).
If you want to maintain the order of the parameters, you can create the proxy class yourself. For this you can either use the ChannelFactory<T> class, or create your own client class derived from ChannelBase<T>. But you don't really need to do that, as I mentioned before.

WCF Service Reference Will not compile

I currently have a simple WCF service with the following operation:
[OperationContract]
int InsertApplication(Application application);
The Application Parameter is defined as follows:
[DataContract]
public class Application
{
int test = 0;
[DataMember]
public int Test
{
get { return test; }
set { test = value; }
}
}
This service is being consumed within a Windows service with a namespace SpringstoneColoAgent. I added a service reference with no problems called OfficeInternalService. The code that calls the service method is as follows:
Application application = new Application();//= ConvertToApp(app);
application.Test = 1;
int oracleID = client.InsertApplication(application);
However, visual studio is telling me that 'application' is an invalid parameter. On further research I try to build anyway. I get a bunch of errors pointing to the Reference.cs file. Looking at this file I determine all the errors revolve around code that uses the following:
SpringstoneColoAgent.OfficeInternalService._
Where anything it is trying to reference under the service reference name is incorrect. So for example this code is giving an error:
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IOfficeInternalService/InsertApplication", ReplyAction="http://tempuri.org/IOfficeInternalService/InsertApplicationResponse")]
int InsertApplication(SpringstoneColoAgent.OfficeInternalService.Application application);
If I do not fully qualify the namespace and remove SpringstoneColoAgent.OfficeInternalService. so that the code looks like this:
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IOfficeInternalService/InsertApplication", ReplyAction="http://tempuri.org/IOfficeInternalService/InsertApplicationResponse")]
int InsertApplication(Application application);
This will fix the error. I repeated this everywhere I could find the error and everything compiled fine. The downside is that everytime I make a change to the WCF service and need to update the service reference it loses these changes and I have to go back and change them.
I'm guessing I am missing something here and was curious if anyone had any direction or has run into a similar situation.
Thanks for any advice!
The Application class is a known .NET type: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.aspx. Try to work with a different class name to avoid name clashes.
Also try to avoid the int private member in the datacontract. Because it is not a datamember, it is not exposed in the WSDL and a generated proxy class on the client side does not know this private member. This can also cause problems.

Consume WCF Data service in client application throws error

I am working on WCF Data service which imported stored procedure, as below.
[WebGet]
public List<GetMTSearchResultTest_Result> GettMTSearchResultTest()
{
MediaMarketResearch_PRODEntities ent = new MediaMarketResearch_PRODEntities();
return ent.GetMTSearchResultTest().ToList();
}
when i consuming this in my client application it says error as "The closed type MMRClient.MMRServiceReference.GetMTSearchResultTest_Result does not have a corresponding element settable property."
I am getting this error while bind to the grid view as below.
DataServiceContext context = new DataServiceContext(new Uri("http://localhost:4131/MMRDataService.svc/"));
IEnumerable<GetMTSearchResultTest_Result> empResult = context.Execute<GetMTSearchResultTest_Result>(new Uri("http://localhost:4131/MMRDataService.svc/GettMTSearchResultTest"));
GridView1.DataSource = empResult;
GridView1.DataBind();
Note: I imported this stored proc as complex type.
Please advice me on this.
Regards,
Jaydeep
I think this link may help you (see the selected answer).
Essentially, what the solution may be is to create a partial class for GetMTSearchResultTest_Result and decorate it with a DataServiceKey attribute, providing a non-nullable column that acts as a primary key (although I don't think it has to be unique).
So your partial class would look something like:
[DataServiceKey("YourKeyColumnName")]
public partial class GetMTSearchResultTest_Result {
}
If you're just doing reads, I don't think you'll need any implementation.
Hopefully this works. Let me know if there are issues/questions and I'll update accordingly.
You can always make a new service reference to a non data service. That is to a normal WCF service. You can simply have a [ContractOperation] returning a list of the troubled "complex types" and that's it.
This way you would have two services the original data service and a new normal WCF service. But this shouldn't be such an issue. You don't have to make the troubled "complex type" as a Entity.

Showing enums client side from wcf service

I don’t know if it’s possible, but I want to be able to refer to enums from my WCF service on the client side. I have one core project, and in that project the enums are:
public enum StatusType
{
Ok = 1,
Error = 2,
Unknown = 0
}
public enum DirectionType
{
None = 0,
ToSystem = 1,
FromSystem = 2
}
I have one Service project using the core project and it is setting the enum types from the core project likes this:
[DataContract()]
static class EnumHelper
{
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
{
List<Type> knownTypes = new List<Type>();
// Add any types to include here.
knownTypes.Add(typeof(StatusType));
knownTypes.Add(typeof(DirectionType));
return knownTypes;
}
}
And in the interface :
[ServiceKnownType( typeof(EnumHelper))]
[ServiceContract( SessionMode = SessionMode.Allowed)]
public interface HandlerService
when I call a method either who takes or returns an enum, it works fine, but I then have to refer to the core project in the client project to use the enums client side, I would want to do that from the Service if it’s possible.
I have tried to set the enums in the core project to
[DataContract]
public enum StatusType
{
[EnumMember]
Ok = 1, /*!<Done with no error */
[EnumMember]
Error = 2, /*!<Done with error */
[EnumMember]
Unknown = 0, /*!<No data registered, default value */
}
with no effect.
I want to use it like this in my client project:
Either like client.StatusType.Ok or Servicereference1.StatusType.Ok or something like that,
note like Core.StatusType.Ok
The reason I want this, is because the Service should be used in different projects, and we don’t want everyone to be dependent on a common dll liberary, if it’s possible to skip it. I use net.tcp binding for the service. Hope it was understandable, thanks for any help :)
If you want to share types and classes between server and client, you have to put them into a separate assembly, and use that on both the server and the client side. This only works if you control both ends of the wire, e.g. write both the server and the client side of the code (which I believe you are).
If you create a separate MyWCFTypes assembly on the server side, you can reference that assembly in your client projects as well, and when importing the service definition, WCF should reuse existing classes, e.g. should reuse your MyWCFTypes classes without creating new classes for the same enums.