I have a class with a Property :
[DataMember]
public bool MyProp { get; internal set;}
I notice that when the proxy is generated. The property is still settable even though I have marked it internal ( I thought that it won't be generated at all ).
Is there a way to achieve what I'm trying? I'd like to be able to set the property from the service side. But not allow the client side to be able to set the property.
A [DataMember] on a WCF contract is just a data field on a data contract - an XML schema. The .NET setter and getter visibility modifier are irrelevant when dealing with WCF messages, really.
If your field has a [DataMember] attribute, it will be part of the XML schema of your data contract - and the client cannot know that it has an "internal" setter on the server side - it's just part of the XSD data contract.
.NET and WCF are two very distinct and separate worlds - when your client calls a WCF service, it's a SOAP-based message passing only - there's no .NET based object interaction! You're not reaching out from your client to the server to call a method on an object on the server side - in which case maybe a .NET visibility specifier would come into play. Your client creates a messages and sends that to the server, which then reassembles the (server-side) object from that message - heck, there's even a SMTP (e-mail!) based transport for WCF!
The only thing the two sides share are contracts - service/operation contracts for your service methods, and XML schema based data contracts for your data being passed around. There' no concept of .NET based visibility specifications in XML schema.
As with Service Contracts, access modifiers on DataContracts/DataMembers do not play any role and are in essence meaningless :(
Without a get and set, you cannot serialize and deserialize over a WCF hop.
You could implement what you are trying to do in the logic of your service.
Related
Based on the processing of the incoming request I have to store the original (unserialized) message as string to a database.
So far I implemented a DispatchMessageInspector and a ServiceBehavior that I used to decorate my service implementation. My DispatchMessageInspector has a property to which I store the message string. My service implementation includes some business rules that check the request and if this check fails I'd like to store the original message.
How can I achieve to access the message string property of my DispatchMessageInspector from the service implementation in an elegant way?
You can add a Message Property containing the raw message in a form you like. Then in your service, you can access them through OperationContext.Current.IncomingMessageProperties["RawMessage"].
If I have a Windows service running a NET.TCP WCF endpoint and one of it's Operation Contracts returns a MyData object. How will this object be represented on the client? Will it only have fields? Will it include it's properties and methods? What about static methods? Etc.
Example:
The service contract specify a GetUser() method that returns a User object. User has a firstName field and a lastName field. It also has a FullName property that returns the firstName concatenated with the lastName. It has a method called Match(string name) that takes a name and returns a percentage using some secret algorithm that tells you how much User is love compatible with a person of that name. Finally, it has a static field PerfectMatchCount that gets incremented every time a Match gets 100%.
The User class is defined on the Server, but is returned by the GetUser() operation contract of the WCF service. When I receive the User object on the client end, will I be able to use all of it's fields, properties, methods and static fields/methods? Is there any plumbing that I need to do if I want to be able to use all of this class features, or is this limitations of WCF and I'm restricted to only a subset of that class features (which one)?
Thank You
You can use the exact same assemblies on both the client and server in order to have the full set of class functionality in both. If you want to do this, put all the data contracts and operation contracts into a standalone assembly (dll) and reference that assembly from both the client and server projects. Don't add a Service Reference in the client project. Instead, build up your WCF channels manually.
I'm writing a C# web service client in Visual Studio 2008 with a Java web service endpoint. I have no control over the endpoint and the SOAP messages that it sends back.
I created an auto-generated proxy client from the web service WSDL using the "Add Service Reference" option in Visual Studio. When I send my request I get a valid SOAP message back, which contains something like this:
<java:a_field xmlns:java="java:com.whatever">Value1</java:a_field>
<java:different_field xmlns:java="java:com.whatever">Value2</java:different_field>
However, it does not actually parse those two values, and all of the values after that are null. After debugging, I found that this code in the auto-generated Reference.cs was the problem:
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=30)]
public string different_field {
get {
return this.different_fieldField;
}
set {
this.different_fieldField = value;
this.RaisePropertyChanged("different_field");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=31)]
public string a_field {
get {
return this.a_fieldField;
}
set {
this.a_fieldField = value;
this.RaisePropertyChanged("a_field");
}
}
These two fields are out of order, so it doesn't serialize them properly, and the rest of the fields are not serialized at all. The WSDL itself declares the fields in the same order that the proxy class is expecting them in, it's just the actual response that changes the order. I can work around this by manually swapping the two Order= values, but that would be a huge pain to maintain given that the WSDLs change frequently and there are 100s of fields that need to be checked for this kind of error. Is there any better way for me to be able to ignore this ordering mismatch and still use the auto-generated web service proxy?
Having dealt with something similar, and knowing that it's a giant pain, I would suggest creating your own "fake" WSDL that reflects what is actually returned from the web service instead of what is specified. The issue appears to relate more to an inaccurate XSD that is part of the WSDL. It seems that some of the Java web service frameworks do not follow the order (or other specifications) strictly by default, and your third-party web service provider may not have the knowledge, resources, or motivation to fix the problem.
It is better still, as a matter of best practice, not to import the WSDL at all as a service reference, instead creating the interfaces and service proxies by hand and the configuration either manually or with the WCF Service Configuration Editor. There are a number of resources on how to do this -- Google is your friend.
I am using message inspector in WCF application to store request & responses, into DB.
Whether to store these data in DB or not has to be restricted based on userInput received in the front-end.
To cut the long story short, I need help to address these issues -
States in page context are not available in the extensibility points
interface.
Inspectors method also do not accept any custom
parameters.
In this case, How can we pass the parameters to the WCF extensibility points for customizations?
Well the IDispatchMessageInspector interface receives a IClientChannel on each call, which is in turn an IExtensible. You would have to implement an custom IExtension, and extend the client channel when it's initialized (using an IChannelInitializer implementation). You could then retrieve the extension from the channel parameter in the inspector method implementation, and use it as a means of communication with you front end..
The ONLY argument I can see for SOAP WCF over REST (json) wcf is the fact that once my service is created I can add a a reference in visual studio and I get a load of strongly typed classes ready for me and a client class that I can call all my webmethod through. It even sets up the web.config as far as I remember.
However when I expose a REST (json) service I still get a WSDL. So Im wondering is there still a way to build my references automatically?
Not using WCF tools. Unlike with SOAP (which has an established protocol for describing services - WSDL), REST doesn't. WADL is one such protocol, but it isn't too widespread and WCF does not support it. You still get a WSDL, because WCF will describe everything it can from the service. However, the WSDL won't have a <wsdl:port> element, which would describe the REST endpoint, which is why you get the WSDL, but cannot generate a reference to it.
The post at http://blogs.msdn.com/b/carlosfigueira/archive/2012/03/26/mixing-add-service-reference-and-wcf-web-http-a-k-a-rest-endpoint-does-not-work.aspx has a lot more info on this issue.
Very old question, newer answer.
today using openapi (swagger) I can achieve this by using swagger inspector doing samples i can document my rest services as well as create a spec yml/json file allowing for validations and acceptance criteria as well as automated clients for java,python,c#,ruby,javascript and others I'm sure
I would like top elaborate:
Although it is true you cannot get a WSDL add service reference with a JSON REST WCF service, what I do is create two met data hooks:
is the operations returning JSON
is a single XML op returning a class wrapper which includes all the service classes I allow, I call it Discover:
i.e.
public class Discover
{
public Manager Manager {get;}
public Employee Emp {get;}
....
}
[OperationContract]
public Discover DiscoverDTOs()
You can, indirectly. While the client generated by Visual Studio won't work, that client implements an interface, also generated, that you can use like this:
WebChannelFactory<IService> factory = new WebChannelFactory<IService>(new Uri(endpointAddress));
IService proxy = factory.CreateChannel();
int result = proxy.Operation(1, 2, 3);
WebChannelFactory has another overload which accepts a WebHttpBinding, you can configure based on the service configuration, or you can make this configuration manually in your app.config file.