What is the correct way to configure App.Config files when using wcf services - wpf

Let's say that I have a simple WPF or Winforms solution. To that solution I add a new project (based on a class library template , which I then reference in the main project) which is intended to be a data layer containing an entity framework data model. When I create the data model in the new project the connection string that it uses gets added to the app.config file of the main project in the solution.
Now let us say that I want to add two more projects to the solution (both of which will again be based on class libraries) to contain details of WCF services that I wish to use. In each case I add the WCF service by using the ADD Service Reference option from the right click context menu of the projects.
Unlike the data model project though the bindings for the service model get added to the local projects app.config file ass opposed to the app.config file of the main start-up project.
Should I simply copy those bindings to the start-up project's app.config file, or should I copy and then delete, or in fact should I be doing something completely different. Thus far trying combination of the first two suggestions I get error messages connected with endpoint configuration, however my knowledge of WCF is not really sufficiently good to fully understand the MSDN articles that the error list points me to.
Note that if the service references are added to the main project I get no errors whatsoever, so I figure this must be a configuration problem of some description.
Would anyone be able to provide the correct procedure for adding projects that essentially contain no more than a WCF service reference to an existing visual studio solution.
Edit
The screenshot below shows my main app.cofig file after having copied over the bindings configurations from the two service contracts. I'm not sure whether I should have commented out the bit that I did or not, I had thought that by doing so I might get rid of the blue squiggly underlines telling me the following (which I must admit to not understanding):
Warning The 'contract' attribute is invalid - The value 'ErsLiveService.IERSAPIService' is invalid according to its datatype 'clientContractType' - The Enumeration constraint failed.

You're likely getting the blue squigglies because the namespace ErsTestService is defined within the project in which you created the service reference. If the root namespace of that project is MyServiceReferenceProject then try changing the namespace to MyServiceReferenceProject.ErsTestService.IERSAPIService.

Related

Adding WebAPI to Composite-C1

I am really impressed with CompositeC1 and the ability to add data types on the fly, reference other data types with a foreign key relationship, etc. The built in functions are also really handy.
Ideally, I could create a separate Web API project that would be able to use all of the functions that are generated on the fly in CompositeC1 and expose them out as REST services.
Should I do this as a separate project referencing the dll's in CompositeC1's bin directory? Those dll's are regenerated each time a custom data type is altered... would that cause an issue?
I just wrote a post tonight that I think answer the question.
http://www.s-innovations.dk/Blog/2013/06/25/Mobile-Services-for-Composite-C1--Idea-Creation
I make an API by tapping into the C1 System and get my data from there. No need to worry about dlls being generated and such.
But you can create your own API in a seperate dll also. You can see from my post the basic steps of getting an API up and running.
You could get a problem if you make a WebAPI that exposes something that a user deletes in the console, then your dll breaks? The idea with my project is to make it dynamic expose types configured from within the console. So if someone deletes a type, then it also get removed from my API.

Check CopyLocal property of all references post/during build in multi project solution (Multi Xap)

I have a Silverlight solution that has multiple silverlight projects (Views) that all compile to their own .Xap file.
There is one "master" project that handles the dynamic downloading of the Xap files, which works pretty well.
But now I need to make sure that all the references are set to CopyLocal=false in all the View Projects. Only the "master" project can have CopyLocal=true.
This means that the Xap files generated by the Views stay rather small.
What I would like to do is check post or during the build process to see if any of the View projects have a reference with CopyLocal=true.
What would be a smart way of doing this? Using an external tool in the Post Build event? Or perhaps an addin for Visual Studio ? Or creating a macro in Visual Studio for this?
I have looked at using .extmap with assembly caching, but since you have to specify the assemblies in that, this does not solve my problem. I just need to know if there is a reference with the wrong setting and report that. Fixing it is not the question, that will still be done manually. It's just the notification I need.
Solution has 35 projects now, so dont want to check them all by hand every time.
I found a question similar to this one, but it lists msbuild as a possible solution. I would like to know if there is a way to do this using "code" (be it prebuilt in a tool/addin or otherwise)
I have chosen to go the Addin path. I created an addin that listens to : BuildEvents.OnBuildBegin
Whenever that event fires I create a list of all projects in the current solution. Doing a bit of recursive searching since there are also Solution folders that make life in DTE world a bit harder.
Then I loop through all the projects and cast them to a VSProject so I can loop through all the references.
Anytime I come accross a reference that is wrong, I create an ErrorTask where I set the Document property to the full solution path of the reference. To do this I Build the path for the project this reference is in, all the way up to the root of the solution.
The ErrorTask is then sent to an ErrorListHelper class I created, that handles the ErrorTasks and also performs navigation.
If I'm done with all the projects and I found any errors, I cancel the current build and show the Error List window, where my ErrorListHelper holds all the Reference Errors I created.
Whenever I want to navigate to the Reference in question, I activate the Solution Explorer window and get the root of it using an UIHierarchy.
Then I walk the path from the root on down, step by step, using the UIHierarchy to get to the UIHierarchyItems and expand them. Until I get to the deepest level (the reference) and I Select that.
Since I only need it for a certain solution and within that solution for certain projects (.Views.* and .ViewModels.*) I also have some checking for those in place during buildup of the Error List.
It works like a charm, already found 12 "wrong" References in 35 projects where I tought all were well.
I am using a different path now to do this. I have a base class that I can use to write unit tests that have access to the DTE2 object. This way I dont need an addin. This also works for Silverlight projects since the test class does not actually need access to the Silverlight projects, just being in the solution is enough to be able to iterate through the projects and check the references.

Generating Silverlight service reference - how to tell what is causing proxy classes to be generated

I have a large object structure that I'm wanting to share between a .Net4 backend and a Silverlight 5 front end. I've created two class library projects of the appropriate type, and have my object structure implemented in the .Net library, and linked into the SL library. On the Silverlight client side I am referencing the Silverlight class library. When I generate the service reference I have checked the option to "Reuse types in referenced assemblies". However when I generate the service reference I am finding that types that are in referenced assemblies are still being generated. It is only certain types, and appears to be largely collection types (attributed with <CollectionDataContract>).
I have a main object that has many properties which are generally either List<MyTypeA> or in some cases they are MyListTypeB, where MyListTypeB inherits from List<MyTypeB>. It seems to be the classes similar to MyListTypeB that are causing the proxies to be generated. These are all attributed with <CollectionDataContract> and have a default constructor.
I also find that even though the project where I am adding the service reference to has a reference to the other SL project containing the entities, when I update the service a new reference directly to the dll is also being added to the project. I'm not sure why this is happening, or if it is causing confusion in the service proxy generation
Is there any way to tell what classes/properties are causing the service generation to generate proxy classes? Or is it a case of trial and error having to comment out attributes until they aren't generated and hone in on the problem class?
I have now found out about the use of the svcmap file, and updating the CollecitonMappings elements to include my collection types, described here:
http://mostlydevelopers.com/blog/post/2009/12/14/Configure-WCF-Service-ndash3b-Reuse-Collection-Types-Issue.aspx
It seems a little unusual that the svcmap functionality is so undocumented.
I was able to add an entry int he svcmap file similar to the following:
<CollectionMappings>
<CollectionMapping TypeName="MyNamespace.MyType" Category="List" />
</CollectionMappings>
And then when I updated the service reference the proxy collections are not generated.

What is the correct way to solve the ambiguous reference issue in WCF services?

Project Structure
I have a silverlight project SLProj, that references a silverlight class library project called ServiceClients. ServiceClients has two wcf service references, Svc1.svc and Svc2.svc. Both Svc1.svc and Svc2.svc are in two different WCF projects which use the same set of DataContracts which are again in a different class library project called MyDataContracts.dll.
Problem description
Now in my ServiceClients project I get an ambiguous reference issue when I need to use a datacontract class which is present in both the service references. If this were a winforms or webforms project, I could reference the MyDataContracts.dll and reuse the common types. But since, this MyDataContracts.dll was built using a non silverlight class library, it can't be referenced in the silverlight project
Workaround...
I am not sure if this below is the best method to go about taking care of this issue. Can anybody let me know if there is a cleaner way to solve this problem, or is this the best way we have so far?
create a single service reference.
click the 'show all files' button in the solution explorer
drill into the service reference and find Reference.svcmap and open it
find the MetadataSources section
add a second line to include the address to your second service. for example:
MetadataSource Address="http://address1.svc" Protocol="http" SourceId="1"
MetadataSource Address="http://address2.svc" Protocol="http" SourceId="2"
save, close, and update service reference.
Use Automapper
Map the DataContracts with AutoMapper.
You will have to invest some time in understanding AutoMapper and reworking your application. Also AutoMapper adds overhead because all data objects will be mapped. But first you will have a clean solution without hacks and second you gain a decoupled and simple data object layer just for your client. Once done you can forget the mapping but you stay flexible for future changes.
If you never have worked with Automapper it's important to play around with it before starting. Automapper is special and needs some time to familiarise with it.
So there. These are the rough steps:
1. Create a subdirectory and sub-namespace Data and copy the DataContracts. Remove the attributes and properties your client doesn't need because these mapped classes live only in your client. You can also change some types or flatten some complex properties.
2. Create an AutoMapperInit.cs like described at Automapper (read the Getting Started Guide). Use the conflicting references like this:
using ref1 = YourProjectServiceReference1;
using ref2 = YourProjectServiceReference2;
3. Wrap the service client like this:
Example GetExample() {
return AutoMapper.Map<ref1.Example, Example>(ref1.YourService.GetExample());
}
The wrapper also needs the same using directives as in step 2.
4. In this wrapper add a static initializer like this (assuming your wrapper class is called Wrapper):
static Wrapper() {
AutoMapperInit.CreateMaps();
}
5. Omit service references in the client and use using YourClient.Data;, the namespace you created in step 1.
Your client is now decoupled from the service and you don't have conflicts anymore.
Disclaimer: I am not affiliated with AutoMapper. I just used it in a project with a similar problem and am happy with it and wanted to share my experience.
Your workaround is actually quite OK. We've used it in several projects like this with 3 service references. It is actually a workaround for the IDE which for some reason only allows to select one service to create a service reference at a time.
Another thing you could try-out is to multi-target your shared contract to .NET and Silverlight, using the same codebase. Details on how to do such thing is described in http://10rem.net/blog/2009/07/13/sharing-entities-between-wcf-and-silverlight. Might be more work but feel less hacky.

WCF from Silverlight without using Add Service Reference

David Betz describes in his article how to create reference to WCF without using "Add Service Reference" option:
http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2
Once WCF service is created, these are the statements within the silverlight:
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress("http://localhost:1003/Person.svc");
IPersonService personService = new ChannelFactory<IPersonService>(basicHttpBinding, endpointAddress).CreateChannel();
...
How does one references the types (such as IPersonService interface) created in WCF from Silverlight when I do not use "Add Service Reference" to buid proxies?
Idea is to reference assemblies that contain WCF data contracts in silverlight application, and to do that you need to fool VS so it thinks assembly is a SL assembly, he describes this in detail here
http://www.netfxharmonics.com/2008/12/Reusing-NET-Assemblies-in-Silverlight
and its not so easy, here is what needs to be done
Just use the same ILDasm/Edit/ILAsm
procedure already mentioned to tell
the assembly to use the appropriate
Silverlight assemblies instead of the
.NET assemblies. This is an extremely
simple procedure consisting of nothing
more than a replace, a procedure that
could easily be automated with very
minimal effort. It shouldn't take you
much time at all to write a simple
.NET application to do this for you.
It would just be a simple .NET to
Silverlight converter and validator
(to test for assemblies not supported
in Silverlight). Put that application
in your Post Build Events (one of the
top 5 greatest features of Visual
Studio!) and you're done. No special
binary hex value searching necessary.
All you're doing is changing two well
documented settings (the public key
token and version).
Second solution is a file level solution , you use add link option on files that contain your required data contracts implementations to SL and make sure they only contain types that allow to build SL and dont reference a lot of external assemblies , usually those conditions should be met for WCF services & data contracts.
I can write more but it would be just the copy paste from that link
You also have to split all methods declaration in you IPersonService according to Async pattern (BeginXXX/EndXXX) since Silverlight supports only asyncronous WCF (even in background threads).
As a help to do this, you may add Service Reference, then copy generated IPersonService (all methods will be decoupled) from Reference.cs. Then you may remove the reference.
However, if your service contract is often changed, you have to repeat Add-Service procedure again, and starting from this, I would say, it's easier just use Add-Service-Reference feature, rather than sharing the contract with your app server.
Only one thing that I would like detect. Often you need in namespaces with more complex support of NET within your WCF service. Therefore you must have real reasons to reference to Silverlight subset within your WCF service (or service library). There are many ways to
use so named traditional ways by Add Service Reference. They are presented in good article enter link description here.

Resources