PRIMEFACES: What java code can be run in XHTML files in PRIMEFACES - primefaces

Traditionally,all the java methods in XHTML code in Primefaces is of the form
<p:commandButton action="#{bean.variable}">
Is there another way to call java methods in XHTML code like
<p:commandButton action="#{bean.method()}">
I need to run the class below. I can use the #ManagedBean (and also use CDI and use #Named) but unsure how the method will be called even if i place a #PostConstruct on public void build(); Something is missing and i dont know how to fix it.
public class SimpleReport_Step01 {
public SimpleReport_Step01() {
build();
}
private void build() {
try {
report()//create new report design
.columns(//add columns
// title, field name data type
col.column("Item", "item", type.stringType()),
col.column("Quantity", "quantity", type.integerType()),
col.column("Unit price", "unitprice", type.bigDecimalType()))
.title(cmp.text("Getting started"),cmp.horizontalList().add(
cmp.hListCell(projectOverview()),
cmp.hListCell(projectStatus())
))//shows report title
.pageFooter(cmp.pageXofY())//shows number of page at page footer
.setDataSource(createDataSource())//set datasource
.show();//create and show report
} catch (DRException e) {
e.printStackTrace();
}
}
private ComponentBuilder<?, ?> projectOverview(){
HorizontalListBuilder hlb = cmp.horizontalList();
hlb.add(cmp.text("max")).newRow();
hlb.add(cmp.text("con")).newRow();
hlb.add(cmp.text("fex")).newRow();
return cmp.verticalList(cmp.text("PROJECT OVERVIEW"),hlb);}
private ComponentBuilder<?, ?> projectStatus(){
HorizontalListBuilder hlb = cmp.horizontalList();
hlb.add(cmp.text("")).newRow();
hlb.add(cmp.text("")).newRow();
hlb.add(cmp.text("")).newRow();
return cmp.verticalList(cmp.text("PROJECT STATUS"),hlb);}
private JRDataSource createDataSource() {
DRDataSource dataSource = new DRDataSource("item", "quantity", "unitprice");
dataSource.add("Notebook", 1, new BigDecimal(500));
dataSource.add("DVD", 5, new BigDecimal(30));
dataSource.add("DVD", 1, new BigDecimal(28));
dataSource.add("DVD", 5, new BigDecimal(32));
dataSource.add("Book", 3, new BigDecimal(11));
dataSource.add("Book", 1, new BigDecimal(15));
dataSource.add("Book", 5, new BigDecimal(10));
dataSource.add("Book", 8, new BigDecimal(9));
return dataSource;
}
}
I know this is a swing app and probably i can change it to run on the browser by using the usual jasper methods used like in this link

Related

Replacement for #helper in ASP.NET Core

So far, i don't think ViewComponent solves that neither does TagHelper. Is there any replacement to this? Something that takes parameters and returns a HtmlString?
I don't see anything harmful with:
#helper foo(string something) {
<div>Say #something</div>
}
var emailbody = classfilenameinAppCodefolder.foo("hello"); //store result in a variable for further processes
For now i believe its a temporary delete before RC. https://github.com/aspnet/Razor/issues/281 and https://github.com/aspnet/Mvc/issues/1130 Well! it better be. I hope someone is working on it. Without #helper, building large HtmlString or 'template' would be a serious pain.
Note: Partial View doesn't seem to do the trick. I think it only renders views not return view to variable.
Secondly, what happened to the App_Code folder?
According to the following Github issue, it looks like #helper is coming back and will be included in asp .net core 3.0.0 preview 4.
https://github.com/aspnet/AspNetCore/issues/5110
UPDATE
Starting in asp .net core 3, you can now define a local function within a Razor code block.
#{
void RenderName(string name)
{
<p>Name: <strong>#name</strong></p>
}
RenderName("Mahatma Gandhi");
RenderName("Martin Luther King, Jr.");
}
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-3.1#razor-code-blocks
Alternatively you can use the #functions directive like this:
#{
RenderName("Mahatma Gandhi");
RenderName("Martin Luther King, Jr.");
}
#functions {
private void RenderName(string name)
{
<p>Name: <strong>#name</strong></p>
}
}
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-3.1#functions
#{
Func<String, IHtmlContent> foo = #<div>Say #item</div>;
}
I'd like to expand on #Alexaku's answer and show how I've implemented a helper like function. It's only useful on one specific page but it allows you to execute a piece of razor code multiple times with input parameters. The syntax is not great but I've found it very useful in the absence of razor's #helper function. First declare some kind of Dto that will contain the input parameters into the function.
#functions {
private class Dto
{
public string Data { get;set; }
}
}
Then declare the razor function. Note that the displayItem value can be multi-line and also note that you access the Dto variable using the #item.
#{
Func<Dto, IHtmlContent> displayItem = #<span>#item.Data</span>;
}
Then when you want to use the razor template you can call it like the following from anywhere in the page.
<div>
#displayItem(new Dto {Data = "testingData1" });
</div>
<div>
#displayItem(new Dto {Data = "testingData2" });
</div>
For .NET Core 3, you can use local functions:
#{
void RenderName(string name)
{
<p>Name: <strong>#name</strong></p>
}
RenderName("Mahatma Gandhi");
RenderName("Martin Luther King, Jr.");
}
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-3.1#razor-code-blocks
As #scott pointed out in his answer, local functions are finally available as of .NET Core 3. In prior versions one can resort to templated Razor delegates.
But none of the answers addresses the question "what happened to the App_Code folder?" The aforementioned features are local solutions, that is, helper functions defined in these ways cannot be shared between multiple views. But global helper functions could often be more convenient than the solutions MS provide out-of-the-box for view-related code re-use. (Tag helpers, partial views, view components all have their cons.) This was thoroughly discussed in this and this GitHub issue. According to these discourses, unfortunately, there's not much understanding from MS's side, so not much hope is left that this feature will be added any time soon, if ever.
However, after digging into the framework sources, I think, I could come up with a viable solution to the problem.
The core idea is that we can utilize the Razor view engine to look up an arbitrary view for us: e.g. a partial view which defines some local functions we want to use globally. Once we manage to get hold of a reference to this view, nothing prevents us from calling its public methods.
The GlobalRazorHelpersFactory class below encapsulates this idea:
public interface IGlobalRazorHelpersFactory
{
dynamic Create(string helpersViewPath, ViewContext viewContext);
THelpers Create<THelpers>(ViewContext viewContext) where THelpers : class;
}
public class GlobalRazorHelpersOptions
{
public Dictionary<Type, string> HelpersTypeViewPathMappings { get; } = new Dictionary<Type, string>();
}
public sealed class GlobalRazorHelpersFactory : IGlobalRazorHelpersFactory
{
private readonly ICompositeViewEngine _viewEngine;
private readonly IRazorPageActivator _razorPageActivator;
private readonly ConcurrentDictionary<Type, string> _helpersTypeViewPathMappings;
public GlobalRazorHelpersFactory(ICompositeViewEngine viewEngine, IRazorPageActivator razorPageActivator, IOptions<GlobalRazorHelpersOptions>? options)
{
_viewEngine = viewEngine ?? throw new ArgumentNullException(nameof(viewEngine));
_razorPageActivator = razorPageActivator ?? throw new ArgumentNullException(nameof(razorPageActivator));
var optionsValue = options?.Value;
_helpersTypeViewPathMappings = new ConcurrentDictionary<Type, string>(optionsValue?.HelpersTypeViewPathMappings ?? Enumerable.Empty<KeyValuePair<Type, string>>());
}
public IRazorPage CreateRazorPage(string helpersViewPath, ViewContext viewContext)
{
var viewEngineResult = _viewEngine.GetView(viewContext.ExecutingFilePath, helpersViewPath, isMainPage: false);
var originalLocations = viewEngineResult.SearchedLocations;
if (!viewEngineResult.Success)
viewEngineResult = _viewEngine.FindView(viewContext, helpersViewPath, isMainPage: false);
if (!viewEngineResult.Success)
{
var locations = string.Empty;
if (originalLocations.Any())
locations = Environment.NewLine + string.Join(Environment.NewLine, originalLocations);
if (viewEngineResult.SearchedLocations.Any())
locations += Environment.NewLine + string.Join(Environment.NewLine, viewEngineResult.SearchedLocations);
throw new InvalidOperationException($"The Razor helpers view '{helpersViewPath}' was not found. The following locations were searched:{locations}");
}
var razorPage = ((RazorView)viewEngineResult.View).RazorPage;
razorPage.ViewContext = viewContext;
// we need to save and restore the original view data dictionary as it is changed by IRazorPageActivator.Activate
// https://github.com/dotnet/aspnetcore/blob/v3.1.6/src/Mvc/Mvc.Razor/src/RazorPagePropertyActivator.cs#L59
var originalViewData = viewContext.ViewData;
try { _razorPageActivator.Activate(razorPage, viewContext); }
finally { viewContext.ViewData = originalViewData; }
return razorPage;
}
public dynamic Create(string helpersViewPath, ViewContext viewContext) => CreateRazorPage(helpersViewPath, viewContext);
public THelpers Create<THelpers>(ViewContext viewContext) where THelpers : class
{
var helpersViewPath = _helpersTypeViewPathMappings.GetOrAdd(typeof(THelpers), type => "_" + (type.Name.StartsWith("I", StringComparison.Ordinal) ? type.Name.Substring(1) : type.Name));
return (THelpers)CreateRazorPage(helpersViewPath, viewContext);
}
}
After introducing the singleton IGlobalRazorHelpersFactory service to DI, we could inject it in views and call the Create method to acquire an instance of the view which contains our helper functions.
By using the #implements directive in the helper view, we can even get type-safe access:
#inherits Microsoft.AspNetCore.Mvc.Razor.RazorPage
#implements IMyGlobalHelpers
#functions {
public void MyAwesomeGlobalFunction(string someParam)
{
<div>#someParam</div>
}
}
(One can define the interface type to view path mappings explicitly by configuring the GlobalRazorHelpersOptions in the ordinary way - by services.Configure<GlobalRazorHelpersOptions>(o => ...) - but usually we can simply rely on the naming convention of the implementation: in the case of the IMyGlobalHelpers interface, it will look for a view named _MyGlobalHelpers.cshtml at the regular locations. Best to put it in /Views/Shared.)
Nice so far but we can do even better! It'd be much more convenient if we could inject the helper instance directly in the consumer view. We can easily achieve this using the ideas behind IOptions<T>/HtmlLocalizer<T>/ViewLocalizer:
public interface IGlobalRazorHelpers<out THelpers> : IViewContextAware
where THelpers : class
{
THelpers Instance { get; }
}
public sealed class GlobalRazorHelpers<THelpers> : IGlobalRazorHelpers<THelpers>
where THelpers : class
{
private readonly IGlobalRazorHelpersFactory _razorHelpersFactory;
public GlobalRazorHelpers(IGlobalRazorHelpersFactory razorHelpersFactory)
{
_razorHelpersFactory = razorHelpersFactory ?? throw new ArgumentNullException(nameof(razorHelpersFactory));
}
private THelpers? _instance;
public THelpers Instance => _instance ?? throw new InvalidOperationException("The service was not contextualized.");
public void Contextualize(ViewContext viewContext) => _instance = _razorHelpersFactory.Create<THelpers>(viewContext);
}
Now we have to register our services in Startup.ConfigureServices:
services.AddSingleton<IGlobalRazorHelpersFactory, GlobalRazorHelpersFactory>();
services.AddTransient(typeof(IGlobalRazorHelpers<>), typeof(GlobalRazorHelpers<>));
Finally, we're ready for consuming our global Razor functions in our views:
#inject IGlobalRazorHelpers<IMyGlobalHelpers> MyGlobalHelpers;
#{ MyGlobalHelpers.Instance.MyAwesomeGlobalFunction("Here we go!"); }
This is a bit more complicated than the original App_Code + static methods feature but I think this is the closest we can get. According to my tests, the solution also works nicely with runtime compilation enabled. I haven't had the time so far to do benchmarks but, in theory, it should generally be faster than using partial views as the shared view is looked up only once per consumer view and after that it's just plain method calls. I'm not sure about tag helpers though. It'd be interesting to do some benchmarks comparing them. But I leave that up to the adopter.
(Tested on .NET Core 3.1.)
Update
You can find a working demo of this concept in my ASP.NET boilerplate project:
Infrastructure (relevant files are only those whose name contains GlobalRazorHelpers)
Registration
Helper interface sample
Helper implementation sample
Usage sample
The #helper directive was removed since it was incomplete and its current design did not fit in the new 'ASP.NET 5 way'. One of the reasons is that helpers should be declared in the App_Code folder while ASP.NET 5 has no concept of special folders. Therefore the team decided to temporarily remove the feature.
There are plans to bring it back in the future though. See this and this.
You can easily replace that "feature" with a ViewComponent (and a TagHelper if you want). ASP.NET Core is much more friendly to web designers, and the ViewComponents allow you to write HTML without any (weird to most) razor code.
For example:
Create a SayComponent : ViewComponent class:
public class SayComponent : ViewComponent
{
public void Render(string message)
{
return View(message);
}
}
Create a View file under Views/Shared/Say/Default.cshtml with just
#model string
<div>Message: #Model.</div>
And call it:
#await Component.RenderAsync("Say", "some message")
For a better experience, add this to your _ViewImports.cshtml file:
#addTagHelper *, YourSolutionName
And then you can use it as a tag helper:
<vc:say message="some message"></vc:say>
How about using partials to recreate reusable tags?
MyProject/Views/Shared/_foo.cshtml
#model string
<div>#Model</div>
MyProject/Views/Courses/Index.cshtml
#{
Layout = "_Layout";
}
<div>
<partial name="_foo" model="foo" />
<partial name="_foo" model="bar" />
<partial name="_foo" model="baz" />
</div>

Windows Phone 8.1 MapTileSource binding with MVVM

I'm trying to bind the DataSource of a MapTileSource to a property on my view model, but I am getting the error REGDB_E_CLASSNOTREG on the Maps:MapTileSource line (underlined in blue is VS editor). I could always use a binding helper to achieve the same effect (I needed to in the 8.0 version of my app) but this seems like it should just...work. Any idea what is wrong?
<Maps:MapControl Style="{Binding Path=MapStyle}" Center="{Binding Path=MapCenter, Mode=TwoWay}" ZoomLevel="{Binding Path=ZoomLevel, Mode=TwoWay}" MapServiceToken="">
<Maps:MapControl.TileSources>
<Maps:MapTileSource Layer="BackgroundReplacement" DataSource="{Binding Path=BaseLayerDataSource}" />
</Maps:MapControl.TileSources>
</Maps:MapControl>
I also tried with just a static data source with the same effect:
<Maps:MapControl Style="{Binding Path=MapStyle}" Center="{Binding Path=MapCenter, Mode=TwoWay}" ZoomLevel="{Binding Path=ZoomLevel, Mode=TwoWay}" MapServiceToken="">
<Maps:MapControl.TileSources>
<Maps:MapTileSource Layer="BackgroundReplacement">
<Maps:MapTileSource.DataSource>
<Maps:HttpMapTileDataSource UriFormatString="" />
</Maps:MapTileSource.DataSource>
</Maps:MapTileSource>
</Maps:MapControl.TileSources>
</Maps:MapControl>
Edit: I tried the sample code at http://msdn.microsoft.com/en-us/library/windows/apps/xaml/dn632728.aspx and it works fine, so it seems obvious that the MapTileSource itself is not unregistered. But that is all codebehind and uses no data binding, so it is not of much use to me.
Edit 2: If I ignore the error and try to deploy the app to the phone emulator, I get this on InitializeComponent() of the view:
An exception of type 'Windows.UI.Xaml.Markup.XamlParseException' occurred in HikePoint.exe but was not handled in user code
WinRT information: Cannot deserialize XBF metadata type list as '%1' was not found in namespace '%0'. [Line: 0 Position: 0]
Additional information: The text associated with this error code could not be found.
Cannot deserialize XBF metadata type list as '%1' was not found in namespace '%0'. [Line: 0 Position: 0]
If there is a handler for this exception, the program may be safely continued.
What's your project platform target ? Try to change it to x64.
Similar Question on SO
I eventually gave up and just made a behavior to handle the binding for me.
public class TileSourceBehavior : DependencyObject, IBehavior
{
public DependencyObject AssociatedObject { get; private set; }
public void Attach(Windows.UI.Xaml.DependencyObject associatedObject)
{
var mapControl = associatedObject as MapControl;
if (mapControl == null)
throw new ArgumentException("TileSourceBehavior can be attached only to MapControl");
AssociatedObject = associatedObject;
}
public void Detach() { }
public static readonly DependencyProperty TileSourceProperty =
DependencyProperty.Register("TileSource", typeof(MapTileSource), typeof(TileSourceBehavior), new PropertyMetadata(null, OnTileSourcePropertyChanged));
public MapTileSource TileSource
{
get { return GetValue(TileSourceProperty) as MapTileSource; }
set { SetValue(TileSourceProperty, value); }
}
private static void OnTileSourcePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var behavior = dependencyObject as TileSourceBehavior;
var mapControl = behavior.AssociatedObject as MapControl;
// remove the existing tile source
var existingTileSource = mapControl.TileSources.FirstOrDefault(t => t.Layer == MapTileLayer.BackgroundReplacement);
if (existingTileSource != null)
mapControl.TileSources.Remove(existingTileSource);
// add the tile source
behavior.TileSource.Layer = MapTileLayer.BackgroundReplacement;
mapControl.TileSources.Add(behavior.TileSource);
}
}
You use it thus, where TileSource is a MapTileSource property on your ViewModel.
<Maps:MapControl>
<i:Interaction.Behaviors>
<behaviors:TileSourceBehavior TileSource="{Binding Path=TileSource}" />
</i:Interaction.Behaviors>
</Maps:MapControl>

Javax.Swing; How can I create an object of a different class and assign variables received from the jframe ? Conceptual issue

I am working for the first time with javax.swing and jframes, so please excuse me if you find this question primitive.
Problem: In my main function I have created an object of a class lets say ClassTest. So the code goes like:
import TestPackage.ClassTest.*;
public class Qinterface extends JFrame and implements ActionListener
{
public string Login;
public static void main(String[] args){
ClassTest test = new ClassTest();
try{ eventqueue invoker ...}catch{}
}
Qinterface(){
setResizable(false);
setTitle("Carrefour : Qualys Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(300, 100, 850, 500);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
txtEnterText = new JTextField();
txtEnterText.setText("Enter Qualys Login");
txtEnterText.setBounds(10, 193, 166, 23);
contentPane.add(txtEnterText);
txtEnterText.setColumns(10);
btnSubmit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent eSubmit)
{
//button is pressed
System.out.println("You clicked the button Submit");
Login = txtEnterText.getText();}});
}
}
So as seen in the last line of the code I am able to get the value from the txtEnterText field and assign to a local variable "Login". But how do i go about if I want to assign this value to an instance of a class created in the main function, for example;
test.x=txtEnterText.getText();
I know its not possible in this approach as we are in the constructor the Qinterface class and the variable of the ClassTest instantiated in the main are not visible.
So the question is general and conceptual; how do you go about such kinds of problems to resolve them, when coding with javax.swing ?
Using a login process as an example:
Your interface class could hold a "LoginData" object that is populated by the action listener. By providing a getter for the data object, the login data can then be accessed from outside of the interface.
This is just one of the many ways you could tackle this problem.
This would be a good candidate for MVC architecture - you can read about it a little here.

CDI conversation and primefaces wizard component

I just realized that my wizard component forgets the steps that lay in the past as I'm using a #RequestScoped wizard backing bean. Using #SessionScoped will work but is ugly.
Thus I tried to get it working using #ConversationScoped but had to realize some strange effect. (maybe out of J2EE experience)
Given this kind of wizard backing bean:
#Named
#RequestScoped
public class EvaluationWizard implements Serializable {
...
#Inject
private Conversation conversation;
#Inject
private Song selectedSong;
...
public void setSelectedSong(final Song song) {
selectedSong = song;
}
public Song getSelectedSong() {
return selectedSong;
}
public void onDialogOpen(final ActionEvent actionEvent) {
conversation.begin();
}
public void onDialogClose(final CloseEvent closeEvent) {
conversation.end();
}
...
}
My Song object looks like this:
#Named
#ConversationScoped
public class Song extends SelectItem implements Serializable {
private String title;
public void setTitle(final String title) {
this.title = title;
}
#Override
public String toString() {
return title;
}
}
The wizard contains several steps in order to set things up. The selectedSong property is an item of a list and represents the currently selected song.
This selection is saved in the "EvaluationWizard" backing bean and my debugging confirms that this is the case - but it's only the case for one wizard step.
Any help on that would be very appreciative.
Greetings, Marcel.
The Primefaces wizard component will not work with RequestScoped beans you are correct. You must either use #SessionScoped or #ViewScoped.
I personally like using ViewScoped as the bean will be created when you navigate to the page and will die when you leave the page. This gives you the benefit of a persisted bean without cluttering up the session.
Yes #RequestScoped won't work. Until today we also used #SessionScoped. Today I learned that it's better to use #ViewAccessScoped because you get window isolation compared to #SessionScoped. In our App we got a lot of bugs caused by #SessionScoped. I just replaced it with #ViewAccessScoped and I solved 17 different tickets in 10 minutes with it.

Is there anyway to serilize linq object for Memcached?

I'm just start switching to memcached and currently on testing with memcached.
I'm having 2 object, I created an object and put [Serializable] on it (for instance, let call this Object1), the other object is created using Linq DBML (Object2)..
I tried to memcached List<Object1>, it work just fine, like charm, everything here is cache and loaded properly.
But then, i move on to the Linq object, now i try to add to memcached List<Object2> this does not work, it did not add to memcached at all. no key was added
I move on and change the Serialization Mode to Unidirectional, do the add again, still no hope.
Is there anyway to make this work?
Here is the simple test I just wrote, using MemcachedProvider from codeplex to demonstrate:
public ActionResult Test()
{
var returnObj = DistCache.Get<List<Post>>("testKey");
if (returnObj == null)
{
DataContext _db = new DataContext();
returnObj = _db.Posts.ToList();
DistCache.Add("testKey", returnObj, new TimeSpan(29, 0, 0, 0));
_db.Dispose();
}
return Content(returnObj.First().TITLE);
}
this is from Memcached, no STORE was called:
> NOT FOUND _x_testKey
>532 END
<528 get _x_testKey
> NOT FOUND _x_testKey
>528 END
<516 get _x_testKey
> NOT FOUND _x_testKey
>516 END
And in my SQL profiler, it called 3 query for 3 test time => Proved that the object called back from Memcached is null, then it query.
It looks like the default implementation (DefaultTranscoder) is to use BinaryFormatter; the "unidirectional" stuff is an instruction to a different serializer (DataContractSerializer), and doesn't add [Serializable].
(Note: I've added a memo to myself to try to write a protobuf-net transcoder for memcached; that would be cool and would fix most of this for free)
I haven't tested, but a few options present themselves:
write a different transcoder implementation that detects [DataContract] and uses DataContractSerializer, and hook this transcoder
add [Serializable] to your types via a partial class (I'm not convinced this will work due to the LINQ field types not being serializable)
add an ISerializable implementation in a partial class that uses DataContractSerializer
like 3, but using protobuf-net, which a: works with "unidirectional", and b: is faster and smaller than DataContractSerializer
write a serializable DTO and map your types to that
The last is simple but may add more work.
I'd be tempted to to look at the 3rd option first, as the 1st involves rebuilding the provider; the 4th option would also definitely be on my list of things to test.
I struggled with 3, due to the DCS returning a different object during deserialization; I switched to protobuf-net instead, so here's a version that shows adding a partial class to your existing [DataContract] type that makes it work with BinaryFormatter. Actually, I suspect (with evidence) this will also make it much efficient (than raw [Serializable]), too:
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using ProtoBuf;
/* DBML generated */
namespace My.Object.Model
{
[DataContract]
public partial class MyType
{
[DataMember(Order = 1)]
public int Id { get; set; }
[DataMember(Order = 2)]
public string Name { get; set; }
}
}
/* Your extra class file */
namespace My.Object.Model
{
// this adds **extra** code into the existing MyType
[Serializable]
public partial class MyType : ISerializable {
public MyType() {}
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
Serializer.Serialize(info, this);
}
protected MyType(SerializationInfo info, StreamingContext context) {
Serializer.Merge(info, this);
}
}
}
/* quick test via BinaryFormatter */
namespace My.App
{
using My.Object.Model;
static class Program
{
static void Main()
{
BinaryFormatter bf = new BinaryFormatter();
MyType obj = new MyType { Id = 123, Name = "abc" }, clone;
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
ms.Position = 0;
clone = (MyType)bf.Deserialize(ms);
}
Console.WriteLine(clone.Id);
Console.WriteLine(clone.Name);
}
}
}