How to pass objects between silverlight and asp.net - c#

I have seen examples where you can pass parameters between aspx and silverlight app as well as how to pass simple values back to aspx.
Is it possible to pass generic types such as list collections from a silverlight app to a asp.net page to be picked up. I have looked at serialization but not sure if this is the best approach due to performance?
Thanks in advance

You can also communicate with your .aspx page client-side, through scriptable objects... see HtmlPage.RegisterScriptableObject(string, object) in Silverlight documentation.

Since Silverlight is client-side and ASP.Net is server-side, you will need to use serialization in order to pass objects between the two.
I would consider using the DataContractSerializer in Silverlight to serialize the object as XML. You can then push the XML up any way you want: ASPX web service, WCF service, HTTP PUT, Hidden fields in the HTML, etc.

Review:
Sharing C# code between Windows and Silverlight class libraries
Your Answer will be listed within that solution already provided for the same question or nearly exact.
Excerpt:
You cannot set a reference from a Silverlight assembly to a regular .NET assembly but you can do so the other way round.
So create a shared Silverlight assembly and add your code to that assembly. Now you can set a reference fro both your regular .NET and you other Silverlight assembly to the shared Silverlight assembly.
The restriction is that you can only put code in there that would work on both the .NET and Silverlight CLR but that is no different from sharing code.
Courtesy: Maurice

Related

How to re-use a user control in two Silverlight client applications?

I'm kind of new to Silverlight and I have a solution which has one web project (webApp) that provides remote services and two client applications (client-1 and client-2) that uses these services.
I have created a complex user control in client-1 that view/edit an object retrieved from webApp and I want to re-use this control in client-2.
The problem is, when you reference the service from the client apps, the types are "locally-typed". For example, MyClass defined in the webApp becomes client-1.MyClass in client-1 app. Using exactly the same object (reference) in client-2 app, it is now of type client-2.MyClass
If I create a library to host my control, I will have to add a reference to the web services and I will have a third type, lib.MyClass. We all know that client-1.MyClass, client-2.MyClass and lib.MyClass are all exactly the same class that was generated from web.MyClass but I can't find a way around this problem.
I'm currently looking at sharing the source code of the user control in each client application and having pre-processor defines in each project so I can do this in my user control code file:
#if CLIENT-1
using Client-1.WebAppServiceReference
#end if
#if CLIENT-2
using Client-2.WebAppServiceReference
#end if
Then the method that uses the type MyClass are using the correct "local-type" in each client app. But I'm having problem since there is no pre-processor functionality in the xaml and there is a reference to the application's namespace there that I need to be conditional.
There's got a be an easier way of re-using controls accross silverlight projects, no?? There is no way I'm going to have two copies of the source files for this control, on in each project!!
Thanks!
There are a couple of options that allow you to use shared entity classes across Silverlight projects/WCF service proxies.
Use an RIA class library
Use a portable class library
If you create your DataContract classes with either of the above, and then reference the library from both your WCF and Silverlight client projects, then the auto-generated code will use a reference to those shared classes (rather than the locally auto-generated classes). This should allow you to re-use your Silverlight UserControls between projects.
The difference between the two approaches is this. If you use the first approach (RIA project), then when you create files named "SomeEntityClass.shared.cs", the ".shared" tells Visual Studio to place a copy of the file in a mirror Silverlight project. The second approach (PCL) is a newer approach -- it allows you to create class libraries that are capable of targeting multiple platforms (.Net, Silverlight, Windows Phone, ...), with a reduced set of core .NET libraries.
I suggest you to dissociate the XAML and graphical stuff from any of Business logics and the like. MVVM is a very good pattern to follow.
After that, you can reference your UserControl from second project with the very useful functionality of Visual Studio "Add as Link"
Here how you can do it :
For the underlying business, you can make it available for both project, and linking these 2 with it.
Hope it helps

Serializing on Desktop, Deserializing in Silverlight

I'm trying to create content via a small C# desktop app, and have it appear inside a Silverlight application. (I'm creating plain, ordinary C# objects, and trying to make them easily persist.) The context is a game of some sort, where I have a desktop tool that lets me create and edit the content I want, and then the Silverlight binaries consume it.
How can I serialize something in (desktop) C# and deserialize it in Silverlight?
I have a small library I created for serialization; it uses Mike Talbot's amazing serializer for Silverlight, and a simple BinaryFormatter for desktop. Within each platform, these are OK; but across platforms, these two are obviously incompatible.
Is it possible to do this? I would not like to revert back to manually serializing by saving data as text and then parsing it, and I would not like to use an embedded database if possible. I may have lists of lists and other complex data, and manually parsing it is too painful.
If it's not possible, what alternatives do I have?
Edit: ProtoBuf .NET looks OK, but as I mentioned in Marc's comment, I'm using the serializer inside my own library. This means that requiring users of my persistence library to add attribution to classes to serialize them will break encapsulation. I don't want to do that.
What do I mean by breaking encapsulation?
The target user of my library (Persistent Storage) is a game developer. They will use the library to persist information within their games.
Hence, they only consume PersistentStorage.dll. Internally, Persistent Storage uses a serializer (currently, Mike Talbot's for Silverlight, and a simple Binary one for non-Silverlight) to persist data.
For me to say "to use my library, put [ProtoContract] or [Serializable] on all your classes" breaks encapsulation. It means the user knows about the internals of my library usage, which they shouldn't. I can change serializers tomorrow, and they shouldn't care.
I am aware that as a work-around, I can ask them to attribute everything with [PersistMe] and have that as a plain empty attribute that, in turn, extends whatever attribute my serializer needs. But I'm hoping that other serializers, like Mike Talbot's, will not require any attribution to use.
You can try to use Silverlight Serializer
From the author's page:
Serializing Classes Between .NET 4 and Silverlight
You may want to use SilverlightSerializer to share objects between Silverlight and .NET 4, perhaps across a WCF link.
The vital thing to do in these circumstances is to define the classes you want to share in a Silverlight assembly that only references System, System.Core and mscorlib. These are the requirements for assemblies that can be used in both types of project. If you define your classes in this way then they can be deserialized on the back end without a problem, reference anything else and it won’t work. Fortunately most of what you will need is included in those system assemblies!
You need to use the same format in this scenario. Since BinaryFormatter isn't OK for Silverlight, that is out. Personally I'd use protobuf-net, which works on both and can be configured to work on vanilla objects (but is easier if you can add attributes), but if your linked serialiser works on desktop that is a viable option too.
With an example of your model I can be more specific.
Why not try old school xml serialization with the XmlSerializer, both the .Net framework on the desktop and silverlight should have that class. This way there is no addition library to include, its in the framework.
You could also look at Sharp serializer. It allows you to either use xml based formatting or binary formatting for serialization.
I have used it in a similar scenario to share data between a Silverlight and a non Silverlight application and it works beautifully.
Just for reference:
you can build a single SilverlightSerializer DLL and reference it in .net and Silverlight. this works even though the DLL targets Silverlight
Silverlight doesn't run with enough security permissions to enable the inspection of private class members. SilverlightSerializer let's you write support classes to serialize third party components with non-standard requirements, and this can work for private members, but in that particular case it's manual and requires that the serialization class and the serialized class are one in the same.
Have you tried a JSON Serializer like JSON.net ( http://json.codeplex.com/ )?
JSON Specification: http://json.org
We use WCF to do all our serialization to the Silverlight client. We have a dll shared between the client and the server that has all the data transfer objects and interfaces. This allows us to not use the wsdl to generate service ref in silverlight.
To do the searlization we use the DataContractSerializer with a BinaryMessageEncoding. Also you do have to watch out for private setters of objects (which cant be done in silverlight, as you cant set a property with a private setter in the partial trust enviroment of silverlight). If you want to use generics and other things like that, use the NetDataContractSerializer, but that will break compatability with Java and other standards based web services outside of .net (but should work fine for silverlight).
All our DTO's are POCO, other then we add a [ItemKey] Attribute to one of the properties (no other attributes or interfaces), so that our system knows which property is the primary key (this isnt required but it makes things easier to do updates in the persistance layer if things change in the objects).

Change Assembly Name during Binary Serialization

Let me briefly explain my architecture before I ask my question. I have a client application that calls out to a web service and passes it a couple of items of data. The web service uses this data to do some lookups and then returns a binary serialized object, by using the BinaryFormatter, as a byte array to the client. The client then deserializes the object and uses it. My problem is I had to rename the assembly that the server uses for the new version. This has caused a problem when deserializing in the client. It is not an option for me to deploy a new client just so the new assembly name can be used so my question is, is there a way I can change the Assembly Name that is being written during serialization. I know how to use SerializationBinders for deserializing but that does not solve my problem as that would require deploying a new client.
I am currently using C# 2.0 for both the win forms application and the web service.
If I were using .NET 4 the solution from Thomas would have been perfect. However, .NET 2.0 does not provide this functionality. Instead I just renamed the dlls back to what they were. I would like to eventually rename the dlls but at this point I have not found a viable solution where I would not have to deploy something to the client as well.
You can recreate an empty assembly with the old name containing just the AssemblyInfo.cs, where you put a type redirect:
[assembly: TypeForwardedTo(typeof(MyClassName))], for every type that is moved to another assembly. Ofc this assembly should reference the new one.
But generally consider not using binary serialization for complex data structures, because it's not friendly to such changes as moving types between assemblies.

Class Libraries, Silverlight and Webservices

I have a Silverlight Class Library that I want to use in both my Silverlight and my WebService project.
I am able to create and reference the Library in both projects without any problems, but when I try to use any of the classes in the Library on the Silerlight project, I get an ambiguous reference error between my Library and the Asmx Webservice (apparently, the silverlight project believes that the classes in the class library exist in the webservice).
How can I correct this issue? I have tried rebuilding and cleaning, but it does not seem to work. Can anyone help?
Sounds like the objects you are passing to Silverlight, via the WCF service, are the same objects in your class library. In that case the generated web-reference objects will be given the same names. Linking with the library will then give you 2 sets of objects with the same names.
If you install RIA services, once feature is the ability to share code between client and server by simply adding ".shared" in the class filenames before the extensions. ASMX services are so last century :)
if you don't want to learn the RIA services way of sharing objects across the great-web-divide (which I would recommend), you need to separate the data objects from the functionality you actually want to share client and server side.
To give more specific advice on your current set-up I would need to see more about how it is structured.
A technique you can use is aliasing your using statements:
using MyNameSpace = My.Name.Space;
using MyWebService = My.Web.Service;
Then access all of your objects with these aliases to remove the ambiguities.

Problem sharing domain model between WCF and Silverlight Project

I am writing a Large Scale Silverlight Application.
I am currently writing the data retrieval elements.
I have now encoutered and issue.
I have a common Project that hold objects, this project is referenced by both the UI and the WCF service.
The UI requires INotifyPropertyChanged for binding purposes.
Now the WCF must use the same objects, but I am getting a compiler error saying
"The type
'System.ComponentModel.INotifyPropertyChanged'
is defined in an assembly that is not
referenced."
EDIT: The error is in the WCF service.
I want one object class, how do I solve this problem?
diagram http://www.pcbuyersguide.co.za/picture.php?albumid=19&pictureid=1708
Thanks
-Oliver
If you plan to use the same source code for your Entities (domain) for both a clr and silverlight project you will need to use 2 projects because the Silverlight assemblies are not the same as CLR assemblies.
Add a Silverlight Class Library project to your solution, the name is not important but I usually just use XXXX_SL.
Now, you will 'Add Existing Item' all of the source files from the clr project, but notice the dropdown on the open or select button? click that and 'add as link' or whatever it says there.
You are now using the same source for both projects and your solution will compile.
There may be some minor tweaks along the way but that will set you on the right path..
Here is some reference material
did you add a reference in the compiling project to System.ComponentModel
I found a method here that allows one to create the CLR classes on the service side and then one can use the generated objects from the Service Reference as the classes are generated with the INotifyPropertyChanged and ObservableCollection.
This solves the immediate problem of the client/server boundary but does fit into my solution because in order to use the generated objects you need the service reference. But I have a ProxyClass that does the talking to WCF so there I cannot see a way of passing these object types back to the ViewModel.
I see some people have written mapper classes, but this is far from ideal as I would have to write 3 classes for each POCO object (client class, server DTO class, mapper).
Any more suggestions?

Categories

Resources