Including XML Comments in DataContract Serializer Metadata - wcf

is there some way of sending the summary info of properties in a DataContract?
e.g.
[DataContract]
public class MyClass
{
/// <summary>
/// My Summary information
/// </summary>
[DataMember]
public int MyProperty {get;set;}
}
can this be available to the client that gets the datacontract? I doubt it, just hoping somebody knows something I don't, which is quite likely. :)

Take a look at WCFExtras on CodePlex. I haven't used it, but it sounds like it does exactly what you want:
Adding WSDL Documentation from Source Code XML Comments
This extension allows you to add WSDL
documentation (annotaiton) directly
from XML comments in your source file.
These comments will be published as
part of the WSDL and are available for
WSDL tools that know how to take
advantage of them (e.g. Apache Axis
wsdl2java and others). Release 2.0
also includes a client side WSDL
importer that will turn those WSDL
comments to XML comments in the
generated proxy code.

If you're referring to the XML comments, then no, they cannot be sent. There is noplace within a WSDL in which they could be sent in such a way that a client could use them.

Related

WebAPI - How do I get XML to output honour namespaces in the response content?

I am building an API using the WebAPI in ASP.NET MVC 4.0. I have built model classes based on sample XML supplied by my Business Analyst using the new, super smart Paste XML as Classes feature.
The problem is, when my client Accepts application/xml, the serialized response doesn't look like the original XML.
I have manually deserialized and serialized some XML (roundtrip) using the XMLSerializer, and although its better, closer to the original, it still lacks some namespace prefixes.
How can I ensure the output is exactly on spec.?
Firstly, you'll need to ensure the WebAPI is using the XmlSerializer to format your WebAPI responses, or at least use the XmlSerializer just for this resource/API.
In the WebApiConfig.cs file you'll find the route registration stuff and also some commented-out code.
Add under that chunk, add the following:
var xmlSerializer = new XmlSerializer(typeof(FruitXmlModel));
config.Formatters.XmlFormatter.SetSerializer<FruitXmlModel>(xmlSerializer);
This will specify the old XmlSerializer be used when serializing the FruitXmlModel CLR type. Note that you'll probably need to reference the XML serialization assemblies.
Next, you'll need to add this code to the class in your model that represents the element in your XML that begins the new namespace.
...
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces Namespaces = new XmlSerializerNamespaces();
public FruitXmlModel() // ctor for one of my models
{
this.Namespaces.Add("banana", "http://www.fruitschema.org/banana");
}
...
If you've used the Paste XML as Classes feature, then this class should already be annotated with the correct attributes XmlTypeAttribute with the correct namespace set.
All being well, this simple change will provide the WebAPI and the XmlSerializer all that's needed to produce the properly prefixed XML output.
I wish you good luck, Luke, hope to meet again soon.

What can I put in the namespace for WCF?

I just started learning on WCF and is trying to create a WCF service for my client application.
From the msdn tutorial, I have went through all the individuals steps and sort of grasp how WCF works and now I am trying to start coding the service on my part. For the first step it says, defining a service contract. and the sample code msdn gives are as follows
namespace Microsoft.ServiceModel.Samples
{
class Program
{
static void Main(string[] args)
{
}
}
}
and the service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
what i would like to ask is, what can i actually substitute the namespace with since I am developing for my own application?
The namespace can be a string - typically it's a URI, like in your question, but it could also be a simple dotted namespace
[ServiceContract(Namespace = "Microsoft.ServiceModel.Samples")]
Contract namespaces are just strings to resolve possible conflicts (can be useful when versioning, for example). If you omit it your WSDL will contain http://tempuri.org. Not what you want in production. However, it's not that easy to just set proper name in ServiceContractAttribute, there are also binding and schema namespaces. For better understanding WSDL namespaces in context of WCF I highly recommend this blog post.

WCF service reference does not include commens from original service methods

I have created a simple WCF web service with a method. This method has comments on it.
Why does the comment not appear in the service reference for a consuming app?
Is there some other way to propagate to method comments to the proxy?
/// <summary>
/// Do some work
/// </summary>
public void DoWork()
{
}
It doesn't appear on the service reference because the comments aren't part of the service metadata. There are two options you can use to have the comments appear on the proxy:
Share the contract interface between the server and the client (i.e., not generate the proxy, but simply reuse your interface on the client side).
Use some custom WSDL export extension which is aware of the comments (or other attributes), and a custom WSDL import extension which can understand those when generating the client. The sample at http://msdn.microsoft.com/en-us/library/aa717040.aspx is one possible implementation.
Perhaps WCF Extras would work for you. It sounds like what you want.
"Adding WSDL Documentation from Source Code XML Comments"
Make sure your service reference is marked as internal instead of public and the warning will go away.

ServiceKnownTypeAttribute doesn't pop up in WSDL

I have an service Interface:
[ServiceContract]
[ServiceKnownType(typeof(Models.ArticleImage))]
public interface IPhotoManagementService
{
[OperationContract]
bool Login(string username, string password);
[OperationContract]
bool IsLoggedIn();
[OperationContract]
void UpdateImage(string articleID, string selectedImage);
}
As you can see I specify a typeof(Models.ArticleImage) on my ServiceContract.
So building the WSDL of this service should cause ArticleImage to pop up in the WSDL. Unfortunarly this doesn't happen at all. Why is that?
ArticleImage has DataContract on it. And when I return an ArticleImage in my interface, then the WSDL does pick up ArticleImage.
Edit: it doesn't even pop up in the service reference in the consuming project!
This is the result of a lot of testing:
The model I'm trying to add is a LINQ to SQL model.
When I add a normal model with ServiceKnownType it works.
When I use my LINQ to SQL entities in my Interface it works.
When I add my LINQ to SQL entity through ServiceKnownType it doesn't pop up.
Only types used as input/output parameters of service contract operations are published in the WSDL.
Why would it need to? Where does your service expose something that could possibly be an ArticleImage?
Re your comment; when using [ServiceKnownType], the extra trype is still exposed in the "mex" (consumed via "svcutil") - but not by the WSDL. Are you using a WCF client? It should appear (I've just checked... it did). In general, though, returning vague data from a web-service isn't a great idea... sub-types, sure! Dictionary<string,ArticleImage> or even Dictionary<string,SomeBaseType> (with [KnownType] etc), fine! But object, HashTable, etc - aren't a good idea (IMO).
You might also just return a list of your type (List<ArticleImage>) which will work in all scenarios (and be easy for WSDL etc); and let the client make the dictionary at their end.
With regards to LINQ-to-SQL; objects for "mex" need to be decorated with [DataContract] / [DataMember]. You can do this in the designed by toggling the "serialization" property for the dbml. With this set (Serialization Mode = Unidirectional), it should work. To be honest, though, I think you be better-off just adding a dummy method that makes the type explicit on the API.

How can I force WCF to autogenerate WSDLs with required method parameters (minoccurs="1")?

While using WCF and OperationContracts I have the following method defined:
[OperationContract]
[FaultContract(typeof(ValidationFault))]
[FaultContract(typeof(FaultException<ExceptionDetail>))]
int DoSomething(int someId, MyComplexType messageData);
When this gets translated to a WSDL by the WCF runtime, it ends up with with minoccurs="0" listed for the parameters someId and messageData (and subsequently throws a runtime error if these parameters are missing).
If I generate a proxy using SoapUI I get something that looks like this:
<com:DoSomething>
<!--Optional-->
<com:EventId>1</com:EventId>
<!--Optional-->
<com:myComplexType >
<com:id>1</com:id>
</com:myComplexType >
</com:DoSomething>
The id field in MyComplexType is marked up with DataMemeber attribute using IsRequired="true" and thus is exposed as mandatory.
It's obviously quite misleading for the WSDL to specify that a parameter is optional when it isn't, but I can't see any obvious way to markup the OperationContract to force WCF to recognise and expose these parameters as required.
I'm slightly baffled there doesn't seem an obvious way to do this (reading intellisense / msdn / google). Or I'm going blind and overlooking something obvious.
Any clues?
I've just written a Blog post about this subject, as I ran into the problem myself last week.
It explains how you can modify the metadata that WCF generates at runtime.
Aside from downloading the source file, you only need to add an attribute to your contract definition. Like so:
[ServiceContract]
[RequiredParametersBehavior]
public interface ICalculatorService
{
[OperationContract]
int Add(int firstValue, int secondValue);
}
Here's the Blog post that explains it in more detail: Controlling WSDL minOccurs with WCF
Check that MyComplexType is marked with a [DataContract] attribute.
For my own WCF contract, I found that minOccurs = 1 would not show up for IsRequired=true in the generated wsdl until the whole chain of objects implicated in the contract were marked as such.