I have code that builds a custom WCF wsdl on the fly. In one particular scenario, the WSDL exported should use the XmlSerializerOperationBehavior as the IWsdlExportExtension as opposed to the default DataContractSerializerOperationBehavior IWsdlExportExtension.
However, every time I try this from the WSDL generation code, I get a null reference exception from the ExportBody method of the XmlSerializerMessageContractExporter (which is used internally in System.ServiceModel by the XmlSerializerOperationBehavior ExportContract method). I've reflector'd it and I can't see anything obviously wrong. For some reason, .NET also doesn't want to work with source stepping in this scenario...
Simply, the most basic way I can reproduce this is
var c = ContractDescription.GetContract(typeof(IMyService));
foreach (var op in c.Operations)
{
op.Behaviors.Remove(typeof(DataContractSerializerOperationBehavior));
op.Behaviors.Insert(0, new XmlSerializerOperationBehavior(op));
}
new WsdlExporter().ExportContract(c); // throws NullReferenceException
Does anyone have any ideas on this?
Thanks very much.
have you check c is not null?
The only other thing i can think of is this statement
new WsdlExporter().ExportContract(c);
maybe the compilier doesn't like it, try this instead
WsdlExporter wsdlImporter = new WsdlExporter()
wsdlImporter.ExportContract(c);
We've had scenarios in the past with wcf and chaining operations and the solution has been to unchain the calls.
I figured it out. The problem is that XmlSerializerOperationBehavior will throw a null reference exception if XmlSerializerFormatAttribute is not present on the ServiceContract interface itself. Had to reflector the whole thing to figure it out...
Related
I have searched google and exhausted a fair bit of my time trying to figure out what is going on with my WCF and client Windows form app.
I am continuously getting the following error
"Unable to set field/property Ingredients on entity type Datalayer.UnitOfMeasure. See InnerException for details."
...
inner exception is
"An item cannot be added to a fixed size Array of type 'Datalayer.Ingredient[]'."
Stack Trace -
at System.Data.Objects.Internal.PocoPropertyAccessorStrategy.<AddToCollection>b__0[T](Object collectionArg, Object item)
at System.Data.Objects.Internal.PocoPropertyAccessorStrategy.CollectionAdd(RelatedEnd relatedEnd, Object value)
The way I have configured my solutions I have a WCF web-service which reference my DataLayer class library, I have a windows app (test app) which references the WCF services as well as DataLayer project.
If I don't reference the DataLayer in my test app, this issues does not occur however I lose the ICollection<Ingredient> to simple Ingredient[] array. Now as you can see this becomes a coding pain to initialize the array every time.
Any idea anyone? thanks in advance.
I was running into this exact error, but the accepted answer wasn't quite the solution I needed. It turns out that the client was sending a List<Order> up to my WCF service, but since the Customer.Orders property was defined as an ICollection<Order>, the WCF deserializer deserializer just deserialized it in the simplest form it could, which was an array of type Order, i.e., Order[].
The only solution I was able to come up with was to change the property in question on my POCO objects from an ICollection<Order> to a HashSet<Order>. See Stop WCF Deserializing Empty ICollection into Zero Capacity Array for a few more details.
When you are adding reference to WCF service in the test using 'Add Service Reference' there is a option to configure the default collection type for the generate proxy on the client. The default i think is array, you can change it to a generic list.
In case you are using svcutil,that too allows the same thing.
Weird. I had this same error, and was doing the right thing, calling "ToArray()". Changed it to "ToList()" and it started working fine.
I'm having very strange issue with my WCF Service Proxy client generated by "svcutil.exe" . My WCF Service works very fine if I don't have a function that returns DataTable. As soon as I add a method that returns a DataTable the client generated by svcutil.exe is behaving very strangely. The Interface is no longer found and client is not able to call the service. But if I add as a Service Reference its working very smoothly. I know its not a good habit to use DataTable as a return type but I need to. I cannot use the Service Reference :-( Any idea why its behaving or what I'm missing!!!
Have a look at the DataTableSurrogate class. It is used by the SyncFramework for serialization and really easy to use.
MSDN DataTableSurrogate
You shouldn't really serialize datasets, instead you should use datamodels and keep anything to do with datasets, tables, readers etc on your backend & in the business layer.
But.. if you want to do so you need to add the following "include" in svcutil, which is causing your issue. (Tells to reuse the types defined in System.Data.dll and not generate them in the proxy)
/r:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Data.dll
Here is the scenario. I have a WCF service, when this service is called it passes control to an instance of another class (created via Ninject). In that class I need to do some work, specifically with Entity Framework and repositories. To cut a long story short, I have the following binding declared.
Bind<IGenericProductRepository>()
.To<GenericProductRepository>()
.WithConstructorArgument( "context", new StagingDataContext());
When I want to use this repository I have the following.
using (var genericProductRepository = IoC.Resolve<IGenericProductRepository>())
The problem is, that I only get a new instance of genericProductRepository if it's a brand new request, if the method is called multiple times in the same request I get an error stating that the context (the EF context) is already disposed, this is because it seems like I am getting the same instance back that was already disposed in the using statement. To explain it another way, using the Microsoft WCF Test Client, if I invoke it the first time, the code runs fine, if I push the invoke button again (without restarting the test client, i.e. the same request) then it throws this error about it being disposed already.
I have tried to play around with the various "scopes" that come with Ninject, but clearly I am missing something.
So my basic question is, how do I get a new repository whenever it hits that line, instead of using the same one ? Help would be greatly appreciated, I'm really trying to push for my company to adopt Ninject and drop Spring.
Look at your binding again. Even without any knowledge about Ninject you should notice that the instance of your context is created exactly once at the time the binding is defined. But what you want is have a new context on every resolve. Best it is done by not using WithConstructorArgument and let Ninject create the instance. Therefore you have to define a additional binding for the type of context. If this is not possible for some reason you have to use the lazy version of WithConstructorArgument
WithConstructorArgument("context", ctx => new StagingDataContext())
Furthermore, you might want to try The WCF extension for Ninject:
https://github.com/ninject/ninject.extensions.wcf
That way you can get rid of the ServiceLocator like usage.
Web service newbie... Please bear with me.
I was given a WSDL file to import into my vb .NET project. I understand that this is a contract which is supposed to tell me how to use the related web service. That's where my problem comes in. I see all kinds of classes, properties, Interfaces, etc. in the imported service reference. Nothing telling me that "if you have X, Y, and Z as inputs call this function to return W".
At the risk of sounding too vague, what is it that I should be looking for that tells me how I should be using this? How do I know which functions to call and from what classes to call them from? Should I expect some documentation to be provided with the WSDL or is the WSDL supposed to be enough for me to look at it and say "ahh, that's how this is used!".
I've read through the various WSDL tutorials out on the web and they gave me a basic understanding (I think...?). I'm missing something somewhere though and I'm really sure where.
Thank you for any assistance.
The classes that have been generated are easy to use.
Basically you would have one client class, and in that class one method for each endpoint/operation declared in the WSDL.
In addition, there should be one class for each complex type defined in the XSD part (the operation input arg object and output result object).
You can then invoke your WS in a way similar to the following (simplified) example.
Try
Dim service As New MyServiceRef.MyServiceClient()
service.Open()
Dim output As MyServiceRef.myCallResponse
Dim args As New MyServiceRef.myCallRequest
args.arg1 = 1
args.arg2 = "A"
output = service.myCallRequest(args)
...
Catch ex As Exception
treat ( ex )
End Try
The WSDL will tell you or, perferably, a SOAP library how to communitcate with the SOAP server. A SOAP service can be an interface to get data for almost anything.
However, if the function names and parameters are not named well, it could be very vague what data you are to send to the SOAP service and what the response will be.
Most of the time, it should be documented. You should get those documents or learn what the service actually does from the service provider. The WSDL is not really meant to be for human consumption. Though, if you are writing your own XML, then yes, you'd need to pay attention to the WSDL. If a library is creating the XML for you, it usually works with the WSDL to find out how to structure the XML and read the response.
When you add reference of the web service, it creates a proxy for you to call the web methods on the server. Here is a simple tutorial for consuming web services in VB.NET
This is my first time consuming a SOAP web service in ASP.Net and I am a little lost on how this works.
https://www.secureach.com/AchProcessorWebService/AchProcessorService.asmx
I created the Service Reference called AchProcessor in VS 2010 and now I have some Code hints in the VS editor. My first bit of code looks like this..
AchProcessor.WebServiceInfoRequest ws = new AchProcessor.WebServiceInfoRequest();
At this point I am kind of lost.. if I type ws. the only code hint I get is 'Body' with the exception of ToString, GetType etc...
Visual Studio would have generated the code using svcutil (or an app named along these lines) as you have seen, among such code is a proxy, or, a client, and this can be used as follows:
using (var client = new MyWebServiceClient())
{
var result = client.MyMethod();
}
So, in your case, MyWebServiceClient should be replaced with AchProcessorClient. As mentioned above by John Saunders, use the Object Browser to determine the definite name of the type if not so easily found as described here.
Although an appropriate binding for the service is most likely already in the configuration file, it is worth mentioning that you can actually specify the binding used in the constructor of the client, too.