I am currently developing a WCF service .net 4.0 which has got 2 properties. For some reason those property is not visible on the client.
Following is the code for the service.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Data;
using System.IO;
using System.Configuration;
using Longview.ScatIt.Data.Model;
using Longview.ScatIt.Service.Contract;
namespace Longview.ScatIt.Service
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "SqlJob" in code, svc and config file together.
[ServiceContract]
public class SqlJob : ISqlJob
{
#region IJob Members
[DataMemberAttribute(Name="FileName")]
internal string _fileName;
[DataMemberAttribute(Name = "Location")]
internal string _location;
#endregion
}
}
I read somewhere on internet that in partial trust property need to be defined as "internal" and add [assembly: InternalsVisibleTo("System.Runtime.Serialization")] attribute in AssemblyInfo.cs in the service contract.
Am I doing something wrong because of which those to properties are not visible on the server?
Any suggestion is appriciated
Thanks
You're mixing up two different things:
You can have services that are decorated with the ServiceContract attribute. A service has a set of methods that you wish to expose via OperationContracts.
A service method can return or accept objects that you decorate with the DataContract attribute. Data contracts have members that should use the DataMember attribute.
What you have now is a service contract with data members. This doesn't make sense.
Here are some more links for services and data contracts.
Related
I've looked around - can't find the answer to this, even in lots of sample code.
I'm trying to compile a WCF Service Application that uses [datacontract] classes as parameters on the interface members, which are from a global C# class library... This is on the server side. When I import the service reference into the client, it's re-namespace-based the global class library classes, and generated a bunch of serialization code!
I cannot add a reference to the global class library in the client project and use the classes freely. this seems clunky. I've checked the button when importing the service reference "reuse types", but I don't know what that does, but it's not the right thing.
During the import of the service library, it allows me to specify the namespace for the about-to-be-generated proxy classes. I'm pretty sure this isn't supposed to be the same namespace as the classes used on the server side!
example:
GLOBAL CLASS LIBRARY
namespace SquallGlobal
[datacontract] class ProcessStartInfo{ }
WCF SERVICE
namespace Squall
[servicecontract] interface IJob{
[OperationContract] StartJob( SquallGlobal.ProcessStartInfo psi );
}
END USER PROJECT
WCF Service imported under namespace 'Squall_Imported'
using SquallGlobal;
if I want to call proxy.StartJob( ), I need to pass in a Squall_Imported.ProcessStartInfo, not SquallGlobal.ProcessStartInfo!
Thus, the final question: How do I keep the proxy-generation code from re-basing the namespace on global classes used in interface methods?
I'm looking to call a .NET 4.6 service inside my .NET Core RC2 app.
I have tested the service within the WCF Test Client supplied by Microsoft and it works fine, I would like to now consume it inside my .NET Core application but am unsure on how to do that.
I have tried using the svcutil to generate the service reference file but I'm guessing this isn't really designed for the new .NET framework as it uses IExtensibleDataObject which doesn't exist in Core and the namespace System.Runtime.Serialization which now seems to have split into Xml, Primitives and Json.
DOes anybody have a example how I could simply consume an external (Not within my project) WCF.
Many Thanks
Microsoft released "WCF Connected Service for .NET Core RC2 and ASP.NET Core RC2". It should do the job.
I used it to generate client code for my service and:
it uses these attributes on DataContract classes:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.2.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="Person", Namespace="http://schemas.datacontract.org/2004/07/Mock")]
public partial class Person : object
It uses [System.Runtime.Serialization.DataMemberAttribute()] for DataContract properties
It uses these attributes to define service contract:
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.2.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="Mock.IMockService")]
public interface IMockService
This is a sample opertaion definition inside the contract interface:
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IMockService/LookupPerson", ReplyAction="http://tempuri.org/IkMockService/LookupPersonResponse")]
System.Threading.Tasks.Task<Mock.LookupPersonResponse> LookupPersonAsync(Mock.LookupPersonRequest request);
To mark request and response objects it uses:
[System.ServiceModel.MessageContractAttribute(WrapperName="LookupPerson", WrapperNamespace="http://tempuri.org/", IsWrapped=true)]
public partial class LookupPersonRequest
And property of the request/response is annotated with:
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://tempuri.org/", Order=0)]
public CepikMock.PersonSearchCriteria criteria;
Finally it generates basic IClientChannel interface
public interface IMockChannel : Mock.IMockService, System.ServiceModel.IClientChannel
{
}
And a ClientBase implementation
public partial class MockServiceClient : System.ServiceModel.ClientBase<Mock.IMockService>, Mock.IMockService
Inside the client class, each service method is exposed like this:
public System.Threading.Tasks.Task<Mock.LookupPersonResponse> LookupPersonAsync(Mock.LookupPersonRequest request)
{
return base.Channel.LookupPersonAsync(request);
}
My application is trying to consume a WebService for which i have a WSDL file. So, i generated an interface from that using SvcUtil.exe. I am using that in my class as below :
namespace ApplicationUsage
{
public class Usage
{
private readonly IExportService _exportServiceProxyClient;
public Usage(IExportToNavisionService _exportServiceProxyClient)
{
_exportServiceProxyClient= exportServiceProxyClient;
}
}
I am injecting the "IExportService" as :
Component.For<IExportService >() .AsWcfClient(DefaultClientModel.On(WcfEndpoint.FromConfiguration("exportServiceProxyClient")));
My issue is that i am forced to use the Endpoint name in the app.config same as the property name ("exportServiceProxyClient") in the class constructor ("Usage") where the instance to be injected. I dont think that it is a good idea. If i dont do this, i get an exception :
**Could not find endpoint element with name 'exportServiceProxyClient' and contract 'IExportService ' in the ServiceModel client configuration section.
This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.**
I dont know how to get around this issue. Why Windsor wants that the endpoint name should be same the variable name in the constructor for the class where it is being injected.
Can anybody help?
We have to implement a provided external API.
This API cannot be changed.
For this API, SOAP messages are exchanged, and one of them dealing with fault exception is like that :
<h:Parent xmlns:h="namespace1">
<Member xmlns="namespace2">0</Member>
</h:Parent>
While we can implement this with other frameworks such as asmx, we do not succeed in doing it in WCF : data member seems to have the same namespace as the datacontract.
Is there a way to add a namespace for datamember ?
Thanks a lot
You can change the namespace associated to the Member data contract using the Namespace property.
I have three projects in my Visual Studio Solution:
“Core” contains a bunch of types.
"WCF Service” uses all of the types in “Core” in service methods.
“Test Client” is a test client app and just has a bunch of test
code.
When I consume my WCF Service in my Test Client, everything looks and works great. The proxy for the service methods are generated so I can pass parameters with the correct type like Core.BusinessObj. However, when I consume that same WCF Service from Core, the proxy being generated requires those same service methods to pass like this: ServiceProxy.BusinessObj. This is causing a problem since I want to create object of type Core.BusinessObj and pass them to my service no matter where that service is being consumed. I am sure this has something to do with referencing my WCF Service within the same project where all the types are defined, but can’t figure out how to get the namespaces correctly identified.
Does anyone know what I am doing wrong?
You're not doing anything wrong - that's just the way WCF works!
When you build the service, you define the service methods and the parameters (and their data types) that those services will expect. This is packaged up on the server side and typically exposed via metadata exchange (MEX).
When the client comes along, and creates the client side proxy for your service, all it can rely on are the bits and pieces in the metadata - description of the service methods (names, parameters), and the description of what the XML will look like that travels between client and server.
Client and server in WCF are talking to one another via serialized (XML) messages - there is no other connection - no direct link or anything. So all the client can do is to make sure his data types that he creates based on the service metadata will serialize into the same XML as the service expects (and that he's able to deserialize the XML messages from the server).
The client creates new client-side types that will have the same "XML footprint" (the same structured in serialized XML) - but that's all he can do. That's why you get types that look very similar - but they are different (typically in a different namespace). That's also the reason why you shouldn't have any functionality (code) in your server-side data contracts - you cannot serialize functionality over XML messages .....
Now, if you control both ends of the communication wire (both the server and the client) and you write both of them in .NET, then you can take a "shortcut" to re-use the types. Basically, you need to do what you did - put all the types and interfaces into a separate assembly ("Core"). Next: before you create your WCF proxy on the client side, make sure the client project references that "Core" assembly. When you create the WCF client-side proxy with the "Core" assembly referenced, you can tell WCF to "reuse types in referenced assemblies" - if you have this option on (it's on by default), then if your referenced assemblies already contain a data type that matches the needs of the WCF client, then that type (from your "Core" assembly) will be reused (instead of a new one created).
WCF - Add Service Reference - Advanced Options
Make sure that your Core.BusinessObj is Serializable
(Example, assuming its for .NET 4)
[Serializable]
public class BusinessObj
Make sure that your service is building fine (with no errors)
Update the service reference (After successfully building of the service)
I built a solution as you described. And it passes the test without any problem.
In my solution there are 3 projects now
Core
WCFService
TestClient
Project Core has one class "BusinessObj"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Core
{
[Serializable]
public class BusinessObj
{
public int id { get; set; }
}
}
Project WCFService has a WebService named "Service1"
(reference to Core has been added)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WCFService
{
public class Service1 : IService1
{
public Core.BusinessObj GetBusinessObj()
{
return new Core.BusinessObj()
{
id = 1
};
}
}
}
Test project, TestClient has one unit test "UnitTest1"
(reference to Core has been added)
(service reference to Service1 has been added)
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestClient.ServiceReference;
using Core;
namespace TestClient
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Service1Client ServiceProxy = new Service1Client();
BusinessObj x = ServiceProxy.GetBusinessObj();
Assert.IsTrue(x.id == 1, "Something's wrong dude!!!");
}
}
}
I think "using Core;" is missing from your TestClient