C# consuming a wcf Request method in a Restful way - c#

We have been provided with a couple of xsd's from a third party. I have used the XSD Utility to create some classes. One of these classes is called 'GetProducts' and it has one method on it called Request.
The idea is that the 3rd party will call this method and then we need to act on the information that it has sent via this method.
in my ServiceContract class how do I consume this method in a Restful way? I'm not sure how I should declare the operationcontract. Can anybody offer a good code sample. Here's the method that has been generated from the xsd:
public partial class GetProducts
{
private ProductsRequest requestField;
/// <remarks/>
public ProductsRequest Request
{
get { return this.requestField; }
set { this.requestField = value; }
}
}`

Related

Using a client proxy with rest in C#

Running into a block trying to follow the logic of an example program. The example is used to demonstrate creating a contract, create a rest web service and then consume the rest service.
What throws me is I have the interface defined in the contract
namespace ProductDetailsContracts
{
[ServiceContract]
public interface IProductDetails
{
[OperationContract]
[WebGet(UriTemplate = "products/{productID}")]
Product GetProduct(string productID);
}
}
then used in the web service
using ProductDetailsContracts;
public class ProductDetails : IProductDetails
{
public Product GetProduct(string productID)
{
//do something
}
}
The code is then consumed in the client
using ProductDetailsContracts;
namespace ProductClient
{
class ProductClientProxy : ClientBase<IProductDetails>, IProductDetails
{
public Product GetProduct(string productID)
{
return this.Channel.GetProduct(productID);
}
}
}
I feel ClientBase<IProductDetails> is the key but I don't see how it is associated with the web service ProductDetails. My real goal to understanding this will be to run a client application that can add and update records in a SQL Server.
The interface you defined is the contract you pass to your client which tells them what services you provide, in your case you provide a GetProduct method.
Then, you create a concrete implementation of that contract, so when client code calls on your interface, they will end up invoking that concrete implementation, which will probably access some external resource (a database or a file) containing the product.
Your ProductClientProxy, which inherits from ClientBase<IProductDetails> is responsible for settings up the channel that will allow the client to make calls to your service. ClientBase is part of the WCF infrastructure, and is the class that actually reads the settings from your app.config and is responsible for settings up communication.
I suggest you read more about ClientBase and even look at the source code

Add unit test case to test external webservice (.asmx) .NET

I have made a code to read the external web service and find the expose methods and their parameters using System.Web.Services.ServiceDescription.
I am also able to invoke the method and get the output through webservice.
This is done only on the bases of external Web service Url.
Everything is done from CodeBehind (C#).
I need to add the unit test case to test the functionality by adding dummy .asmx webservice which will be accessed by unit test.
Please let me know or have suggestion to how can i create a dummy service on the fly and used.
As far as I can see, there 2 different functionalists:
WSDL provider - i.e. class which gets a valid wsdl from somewhere
WSDL parser - the class which parses the wsdl and extracts the data
Here is a pseudo-code implementation of these to make them easy to mock and unit test.
public interface IWSDLProvider
{
string GetWsdlFromService(string url);
}
public class MyWsdlProvider : IWSDLProvider
{
private readonly IWebWrapper _webCLient;
public MyWsdlProvider(IwebWrapper webClient)
{
_webClient = webCLient;
}
public string GetWsdlFromService(string url)
{
//do here whatever is needed with the webClient to get the wsdl
}
}
public interface IWSDLParser
{
MyServiceData GetServiceDataFromUrl(string url);
}
public class MyWsdlParser : IWSDLParser
{
private readonly IWSDLProvider _wsdlProvider;
public MyWsdlParser(IWSDLProvider wsdlProvider)
{
_wsdlProvider = wsdlProvider;
}
public MyServiceData GetServiceDataFromUrl(string url)
{
//use the wsdl provder to fetch the wsdl
//and then parse it
}
}
The IWebClient is a wrapper around WebClient to allow easy mocking.
Using any mocking framework with the above code, you can easily isolate and mock any part, and test only the behavior at hand. That way, you can even make the mock for the wsdl provider to return any wsdl you want to test with.
You can go even further and wrap/isolate the System.Web.Services.ServiceDescription calls, so you don't really have to pass even a wsdl in your tests, just work on the results.

Sharing WSDL types without XSD

I can't seem to find an example of generating proxies from WSDLs with shared types but without having any XSDs to go along with them. Can anyone please mark this as duplicate and point me to an example please?
Here are 2 services, each has its own namespace and a common type. The only thing that is publicly accessible are their WSDLs, there is no type's XSD or its .dll to pass to wsdl.exe /sharedtypes or svcutils and without it I end up with identical class Foo that I can't pass in to SetFoo and class Foo1.
The best I could come up with is generating proxies programmatically and detecting duplicates via CodeDOM, ignoring DataContract/WebServiceBinding namespaces, but it's a huge mess...
[WebService(Namespace = "http://tempuri.org/FOO1")]
public class Service1 : WebService
{
[WebMethod]
public Foo GetFoo()
{
return new Foo();
}
}
[WebService(Namespace = "http://tempuri.org/FOO2")]
public class Service2 : WebService
{
[WebMethod]
public void SetFoo(Foo foo)
{
}
}
public class Foo
{
public int Bar { get; set; }
}
There is a way of doing this, which is outlined here.
In your case you can skip the first step, generate the proxy from service 1 and then use the /r flag on svcutil to reference the service 1 proxy assembly when you generate your service 2 proxy.
This will ensure your service 2 proxy will use the same instance of Foo from your service 1 proxy.
However, have you considered just hosting a single service with two operations? It would save you a lot of work.
Edit: Also have a look at this post:
http://blogs.msdn.com/b/youssefm/archive/2009/10/09/reusing-types-in-referenced-assemblies-with-svcutil-s-r-switch.aspx
First off, you need to set the [DataContract(Namespace="some namespace here")] for all common service data types, otherwise when the WSDL and XSDs are generated then you will have objects from two difference namespace --- this is absolutely essential. The namespace value will only apply to the types defined in the XSD and not in the WSDL. XSD = data, WSDL = service.
The XSDs and WSDL and generated if, and only if, you have the META service behavior set - add this behavior and then you can navigate to the URL. The URL of the META service behavior will then have a link to your WSDLs and XSDs.
I use the following piece of code to self-host services in windows services rather than through IIS, however the same principals apply....
/// <summary>
/// Enables meta data output for a service host.
/// </summary>
/// <param name="host">The service host.</param>
/// <remarks>Must be invoked prior to starting the service host.</remarks>
public static void SetupMetaDataBehaviour(ServiceHost host)
{
ServiceMetadataBehavior metaDataBehaviour = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (metaDataBehaviour == null)
{
metaDataBehaviour = new ServiceMetadataBehavior();
metaDataBehaviour.HttpGetEnabled = true;
host.Description.Behaviors.Add(metaDataBehaviour);
}
else
{
metaDataBehaviour.HttpGetEnabled = true;
}
}
after adding your two web references:
double click on the second web service reference
in the object browser navigate to the definition of Foo
right click on Foo and choose go to definition
delete the definition for the class Foo
add a using statement for the namespace of webservice one
find and replace all instances of <namespace-of-service-reference-2>.Foo with just Foo
This should fix your problem as it forces the autogenerated code for both service references to use the same class declaration.

Get custom object via WCF in an Explorer-Extension isn't working but in Winform

I have a WCF Host with something like this:
[ServiceContract]
public interface IMountToOs
{
[OperationContract]
char GetMountDriveLetter();
[OperationContract]
MyTestClass MyTest();
}
public class MyTestClass
{
public string A { get; set; }
public string B { get; set; }
}
Client
private IMountToOs _proxy;
public IMountToOs Proxy
{
get
{
if (_proxy == null)
{
NetTcpBinding binding = new NetTcpBinding();
binding.MaxReceivedMessageSize = 2147483647;
binding.OpenTimeout = TimeSpan.FromMilliseconds(50000);
EndpointAddress address = new EndpointAddress("net.tcp://localhost:1234/MountToOsHost");
//_proxy = new MountToOsClient(binding, address);
ChannelFactory<IMountToOs> factory = new ChannelFactory<IMountToOs>(binding);
_proxy = factory.CreateChannel(address);
}
return _proxy;
}
}
While I can access
MessageBox.Show("Okay - " + Proxy.GetMountDriveLetter());
I can't call this method:
MessageBox.Show("Okay - " + Proxy.MyTest().A);
The complete extension is not working. But only while using it in an extension. Even if I insert a Messagebox in the first line of the extension it is not hit. I don't know why. It seems to run a pre-check and find the call of the custom class which is refused or so...
If I use a winform or so there is no problem.
.net 3.5
curious is that I have a break-point and a message of the hosts side. So I see that the method is not called
Update
now I moved the wcf-call in the Load Method of the extension and get a exception:
System.MissingMethodException: method not found:
"Contracts.Interfaces.MyTestClass
Contracts.Interfaces.IMountToOs.MyTest()".
My winform test and this extension use the same interface so that the method should known from both. no contract or so is outdated
According to what I found here and in the comments of the post: "For creating dynamic service proxy using client channel factory method, you will need datacontracts of the service. If you don't have datacontracts but you have the service URL, then you could use reflection to create proxy at runtime and call the service method."
Seems that the MyTestClass type is not known on the client side, so I think you could use reflection, or share the class between the client and server or much more simple, use the datacontract attribute.
Also, found something on MSDN that says something like this:
"When to use a proxy?
We create proxy using svcutil.exe. The output of this tool gives a proxy class and makes corresponding changes to the application configuration file. If you have a service that you know is going to be used by several applications or is generic enough to be used in several places, you'll want to continue using the generated proxy classes. We use proxy in WCF to be able to share the service contract and entities with the client. Proxies have several restrictions like they need to have gets and sets , contructors can't be exposed , methods other than the service contract cannot be exposed, repetition of code, everytime that we add/modify a service contract/data contract/message contract we need to re-generate the proxy for the client.
When to use ChannelFactory
The other option is using the ChannelFactory class to construct a channel between the client and the service without the need of a proxy . In some cases, you may have a service that is tightly bound to the client application. In such a case, it makes sense to reference the Interface DLL directly and use ChannelFactory to call your methods using that. One significant advantage of the ChannelFactory route is that it gives you access to methods that wouldn't otherwise be available if you used svcutil.exe..
When to use a ChannelFactory vs Proxy class?
A DLL is helpful if the client code is under you control and you'd like to share more than just the service contract with the client -- such as some utility methods associated with entities and make the client & the service code more tightly bound. If you know that your entities will not change much and the client code is less, then a DLL would work better than a proxy. If the client to your service is external to the system, such as API, it makes sense to use a proxy, because it makes sharing the contract easier by giving a code file rather than a DLL."
We cant see the class
MountToOsClient: IMountToOs
So we can only assume it is ok.
[DataContract] // Missing
public class MyTestClass
{
[DataMember] // Missing
public string A { get; set; }
[DataMember] // Missing
public string B { get; set; }
}
MountToOsClient can not expose Mytestclass without these attributes.

Is it possible to prevent WCF services from inspecting object properties on the client?

I'm working with a 3rd party API whose objects I am exposing through a web service. Unfortunately the API has some quirks, including throwing exceptions when trying to access some properties if the object's ID field is 0.
So I'm creating a valid instance of the object on the server and pushing it through a WCF service to the client. The problem occurs when the client receives the object. It seems that for whatever reason, the service inspects each of the properties of the object before it populates them on the client. So the objects are throwing exceptions when the client receives them but before I'm able to do anything with them. Here's some quick example code to demonstrate what is happening.
public class ExposedClass {
public int Id { get; set; }
List<OtherClass> _other;
public List<OtherClass> Other {
get {
if (Id == 0) throw new Exception("Can't access field 'other' if object not initialized");
return _other;
}
}
}
In the service:
[ServiceContract]
public MyService {
[OperationContract]
public ExposedClass GetThing() {
ExposedClass c = new ExposedClass();
c.Initialize(); // makes the Id field valid
return c;
}
}
And the client:
[TestMethod]
public void GetThingFromService {
var svcClient = new MyClient();
var c = svc.GetThing(); // exception thrown here on client
Assert.IsNotNull(c);
}
Any ideas?
Usually a DataContract class should not contain any programming logic. It is used as a sort of container to store information which is passed to the client.
My approach would be to copy the information I need from the 3rd party object onto a custom DTO (Data Transfer Object) before sending it down the network.
Are the 3rd party classes actually required at the client end? If possible it would be a good idea to discard the 3rd party objects at the server, thus layering and insulating your users from buggy code which you have no control over.
There are two possibilities:
Contact the developer of the library and tell them that they need to fix their code.
Barring that use (if licensing allows) Reflector and tear apart the assembly, fix it yourself, and recompile.
An object should never depend on the order of fields being assigned for this exact reason.

Categories