Custom Business Object : AJAX Enabled WCF - c#

Can I pass a custom object between AJAX enabled WCF and my asp.net page?
I searched the web but could not find any examples. Most shows simple types like string and integers.
I also do not know how to populate custom object's property through JavaScript on the client side.
We have a browser add on and we have to pass data to that addon from a web service, I researched and looks like AJAX enabled WCF is way to go
Using .net framework 3.5 and VS 2008

You can't pass the actual custom objects, but you can of course pass the serialized version of them through your service and to your page, javascript, etc. Basically, you have to map the fields of your complex custom .NET types to classes decorated with the DataContract attribute. These classes are the types that your service will return. The DataContract-decorated classes will contain fields with primitive types, like strings, integers, etc. The WCF service will serialize these into XML or JSON.
On the client side, jQuery will be your best friend. I personally prefer JSON because the properties of your objects are much easier to get at that way instead having to deal with parsing a bunch of XML. So, setup your service to output JSON.
Also, to make your service URLs easier to read, make sure to use a RESTful approach. It's as easy as decorating your service methods with the WebGet attribute and supplying a UriTemplate. Once you see some examples, it'll blow your mind. Note: if you ever encounter a WebInvoke with Method="GET", just use WebGet instead...it's more compact...no Method specification needed.
This particular article was EXTREMELY useful to me when I was developing my WCF service and the ASP.NET app that consumed it: http://www.c-sharpcorner.com/UploadFile/sridhar_subra/116/
Here's another person asking the same question as you: http://social.msdn.microsoft.com/forums/en-US/wcf/thread/879d46af-9c78-4b5d-b746-82843d742a6f
Hope this helps! Long live WCF!

With .NET 3.5 your best bet is WebHttpBinding which accepts plain old XML (POX) and you need to send XML to the WCF service.
You can also use WCF REST using REST starter kit. For samples have a look here. This supports JSON as well.
If you were using .NET 4.0, JSON-enabled WCF HTTP was the way to go. WCF REST with 4.0 was an alternative although I really do not like it.

Related

Using custom class methods in web service client (C#)

I've been doing quite a bit a learning over the past couple of days and I believe I've come to a conclusion. I would like to ask if my current understanding is correct, as I've had a very difficult time getting a "straight" answer to my specific problem based on Google searches.
I have a C# class library (.dll) with some classes that are used across multiple projects, including customClass (namespace myDLL).
I have a C# web service. One of the web service functions has an "out customClass [] myCustomClass" array argument.
I have a C# web service client. I want to be able to use customClass in the client. Here is a list of questions:
1) Is it true that the customClass array that is returned to the web service client is NOT the same type as an array of type myDLL.customClass (even though it is intuitive to assume that it would be)?
2) Is there any easy way to cast/convert the customClass array in the web service client to the type myDLL.customClass? I'd prefer to not have to write supporting code or manually edit reference.cs. It is my belief that there is NOT such an easy method of conversion, although it can be done with supporting conversion code.
3) It is my belief that the output of web services is meant to be only data (in general). To expect that a client will get class behavior along with data "easily/natively" when using the web service WSDL is not an expectation supported by the web service/web service client model. Is this belief generally correct?
I appreciate any help. If anyone has an nice, straightforward links about this topic, I wouldn't be surprised I've already read it, but I will definitely be all eyes :).
Thanks,
Richard

Why are there extra arguments in my wcf web service reference?

I'm trying to convert an ASP.Net web service to WCF application. The client is on the .Net Compact Framework which does not support WCF so I need to make sure the WCF keeps supporting ASP style webservices. When I add the web service reference in Visual Studio the generated proxy class' methods have extra arguments.
For example if a method is defined as:
public void GetEmpInfo(int empNo)
That method will appear in the proxy class as:
public void GetEmpInfo(int empNo, bool empNoSpecified)
What causes this, and how do I get it to stop?
Check out this blog post ...
Where did these extra boolean
“specified” members come from and what
do they do? The answer is the schema
that the WCF data contract serializer
generates by default. Because of the
way its versioning model works, the
serializer generates all data members
as optional elements. The older web
services stack, ASP.NET Web Services
(“ASMX”), uses a different serializer,
the XmlSerializer, which maintains
full schema and XML fidelity. The
XmlSerializer maps all optional
elements to two members: one
represents the data itself, and one
specifies whether or not the data is
actually present – this is the
“xxxSpecified” member. These
xxxSpecified members must be set to
true to enable the serialization of
the corresponding “actual data”
members.
The .NET Compact Framework does support a subset of WCF. You can review this support on MSDN. Take a look, it may support enough for you to remove your legacy Web Services support.
This happens for types with a default value of not null. In these cases, it's impossible for the web service to know whether a parameter was set to the default value or simply not set at all.
You can get rid of the extra specification parameter by decorating your operation with the [XmlSerializerFormat] attribute like:
[OperationContract]
[XmlSerializerFormat]
string GetEmpInfo(int? empNo);
This attribute can also be added at the Class level, and this would make sense in most cases.
I understand you can handle this situation using nullable types (int?), but I was unable to fix it using this.

Is it possible to create read only elements in SOAP web services?

I have a class with a read-only property defined. In my code I define this as a property with a getter only.
I want to be able to send this object back and forth across a web service. When I call a "Get" method in the service, it would be populated with a value on the service side. Once I define this property, I don't want the consumer of the web service to be able to set/change this property.
When I add a reference to this web service to a project, the object has the property serialized a few different ways depending on how I try to define the object on the service side:
internal setter: Creates the property in the WSDL. Visual Studio generates a class with both a getter & a setter for this property.
no setter: Does not create the property in the WSDL. Visual Studio then obviously does not define this property at all.
Read-only public member variable - Does not create the property in the WSDL. Again, Visual Studio will not do anything with this property since it doesn't know about it.
Allowing the consumer of the web service to set a value for this property will not cause any harm. If the value is set, it is ignored on the web service side. I'd just prefer if the consumer can't change/set the property to begin.
Is there any way to define a property as read-only? Right now we're using C#/.NET 2.0 for the web service, and (for now at least) we have control over all of the consumers of this service, so I can try changing configurations if needed, but I prefer to only change things on the web service and not the consumers.
I can be wrong, but I think the problem here is how serialization works - in order to deserialize an object the serializer creates an empty object and then sets all the properties on this object - thats why you need a setter for the properties to be included in serialization. The client code has the same "interface" to the object as the deserializer.
Caveat, I am a Java guy so the first part of my answer focuses on what may be possible in C#.
Firstly, with a custom serializer in Java, you can do almost anything you want, including directly setting values of a protected or private field using reflection so long as the security manager doesn't prevent this activity. I don't know if there are analogous components in C# for the security manager, field access, and custom serializers, but I would suspect that there are.
Secondly, I think there is a fundamental difference in how you are viewing Web services and the Web service interface as part of your application. You are right-click generating the Web service interface from existing code - known as "code first". There are many articles out there about why WSDL first is the preferred approach. This one summarizes things fairly well, but I would recommend reading others as well. While you are thinking in terms of a shared code library between the client side and server side of your Web service and maintaining object structure and accessibility, there is no such guarantee once you publish an API as a Web service and don't have control over all of the consumers. The WSDL and XSD serve as a generic description of your Web service API and your server and client can be implemented using different data binding configurations, object classes, or languages. You should think of your Web service interface and the XML that you pass in and out of it as describing the semantics of the exchange, but not necessarily the syntax of the data (your class structure) once it is internalized (deserialized) in your client or server.
Furthermore, it is advisable to decouple your transport related structures from your internal business logic structures lest you find yourself having to refactor both your server implementation, your Web service API, and your (and other's) client implementations all at the same time.
There's no built-in way to do this in .NET 2.0 as far as I know. In cases where I wanted to serialize a read-only property, I've implemented the IXmlSerializable interface so that I could control the ReadXml() and WriteXml() methods.
In later versions of the .NET framework, you can serialize read-only properties by setting an attribute on the backing field.

Making an ASP.NET ASMX web service easily callable by ColdFusion web clients

I've written an ASP.NET webservice (.asmx style rather than WCF) and I have the main web methods working now in my prototype enviroment. Now I need to add several new parameters to one of the webmethods but, more significantly, I need to make my webservice as "consumable" (callable) as possible from a ColdFusion web application. I'm confused about how to best design parameter types for the webservice methods in light of usage by CF (or other client callers).
My prototype relies on my own ASP.NET web page which calls my webservice; here is how the proxy class for my service is called from the .aspx page:
BrokerASMXProxy.Svc.FileService brokerService = new BrokerASMXProxy.Svc.FileService();
recNumber = brokerService.UploadFile(binData, fileNameOnly, kvData);
Here is the signature of the webmethod:
[WebMethod]
public string UploadFile(byte[] incomingArray
, string FileName
, MetaData[] metaDataArray)
I'm a little concerned already about the byte array and the MetaData array (will ColdFusion have a problem calling this service with argument types like that?). I assume strings are not a problem but what are the best practices for designing webmethods (and their types) for use by ALL types of callers?
p.s. I also have a DownloadFile webmethod that has "out" parameters:
[WebMethod]
public bool DownloadFile(string recNumString, out byte[] docContents, out string returnFiletype)
..and I wonder similarly about ColdFusion's accomodation of these outputs. Thank you in advance.
If you're running ColdFusion 8, and happen to have that on the same physical server as your .NET code, you may be better off using .NET integration, where you can write a .NET class and intantiate it inside your CF code as if it were a CFC or a Java object.
Here's a good example (with tons more on the same blog) of writing a .NET class that's used in CFML code.
However, if your .NET and CF app servers are not on the same machine, you may have to go with a web service as you originally thought.
The great thing about web services is that they are language agnostic. It looks like you have a MetaData type or class defined, and you're expecting a collection of those to be sent as an input parameter. What that's going to ultimately translate to is some XML that represents that array, and each item in the array will be broken down to its core parts (strings, numbers, bools, etc)... In theory, it should just work, as long as you design your input XML accordingly.
It's been a while since I last created a .NET web service, but I'm sure there's a way to look at the expected XML structure (aka WSDL). Find that, and you've got your answer. Then you just need to create XML that fits that definition from your ColdFusion code and you're all set.

WCF: Individual methods or a generic ProcessMessage method accepting xml

My company is developing an application that receives data from another company via TCP sockets and xml messages. This is delivered to a single gateway application which then broadcasts it to multiple copies of the same internal application on various machines in our organisation.
WCF was chosen as the technology to handle the internal communications (internally bi-directional). The developers considered two methods.
Individual methods exposed by the
WCF service for each different
message received by the gateway
application. The gateway
application would parse the incoming
external message and call the
appropriate WCF service method. The
incoming XML would be translated
into DataContract DTO’s and supplied
as argument to the appropriate WCF
method.
The internal application
exposed a WCF service with one
method “ProcessMessage” which
accepted an Xml string message as
argument. The internal app would
parse then deserialize the received
xml and process it accordingly.
The lead developer thought option two was the better option as it was “easier” to serialized/deserialize the xml. I thought the argument didn’t make sense because DataContracts are serialized and deserialized by WCF and by using WCF we had better typing of our data. In option 2 someone could call the WCF service and pass in any string. I believe option 1 presents a neater interface and makes the application more maintainable and useable.
Both options would still require parsing and validation of the original xml string at some point, so it may also be a question where is the recommended place to perform this validation.
I was wondering what the current thoughts are for passing this kind of information and what people’s opinions on both alternatives are.
Option 1 is suited if you can ensure that the client always sends serialized representations of data contracts to the server.
However if you need some flexibility in the serialization/deserialization logic and not get tightly coupled with DataContracts, then option 2 looks good. Particularly useful when you want to support alternate forms of xml (say Atom representations, raw xml in custom format etc)
Also in option 2 inside the ProcessMessage() method, you have the option of deciding whether or not to deserialize the incoming xml payload (based on request headers or something that is specific to your application).
In option 1, the WCF runtime will always deserialize the payload.
I recently asked a couple of questions around this area: XML vs Objects and XML vs Objects #2. You'll find the answers to those questions interesting.
For our particular problem we've decided on a hybrod approach, with the interface looking something like this:
// Just using fields for simplicity and no attributes shown.
interface WCFDataContract
{
// Header details
public int id;
public int version;
public DateTime writeDateTime;
public string xmlBlob;
// Footer details
public int anotherBitOfInformation;
public string andSoemMoreInfo;
public book andABooleanJustInCase;
}
The reason we use an xmlBlob is because we own the header and footer schema but not the blob in the middle. Also, we don't really have to process that blob, rather we just pass it to another library (created by another department). The other library returns us more strongly typed data.
Good luck - I know from experience that your option 2 can be quite seductive and can sometimes be hard to argue against without being accused of being overly pure and not pragmatic enough ;)
I hope I understood this right. I think it might make sense to have your gateway app handle all the deserialization and have your internal app expose WCF services that take actual DataContract objects.
This way, your deserialization of the TCP-based XML is more centralized at the gateway, and your internal apps don't need to worry about it, they just need to expose whatever WCF services make sense, and can deal with actual objects.
If you force the internal apps to do the deserialization, you might end up with more maintenance if the format changes or whatever.
So I think I would say option 1 (unless I misunderstood).

Categories

Resources