Skip navigation
All Places > PI Developers Club > Blog > Author: MichaelvdV@Atos
1 2 Previous Next

PI Developers Club

24 Posts authored by: MichaelvdV@Atos

MITRE released the 2011 'Top 25 most dangerous software errors'. You can find it on the CWE website.


While it is a very long document, and it looks a bit intimidating, it is actually a very good read (well, maybe not all of it, but it is very interesting to browse trough). They offer a lot of in-depth information with code samples. I think this is a must read for people who develop software in critical environments (that's us...). The list offers information about the severity, attack frequency, consequences, etc.


Here's a summary of the top 25 most dangerous software errors, with links to sections in the article:




Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')




Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')




Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')




Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')




Missing Authentication for Critical Function




Missing Authorization




Use of Hard-coded Credentials




Missing Encryption of Sensitive Data




Unrestricted Upload of File with Dangerous Type




Reliance on Untrusted Inputs in a Security Decision




Execution with Unnecessary Privileges




Cross-Site Request Forgery (CSRF)




Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')




Download of Code Without Integrity Check




Incorrect Authorization




Inclusion of Functionality from Untrusted Control Sphere




Incorrect Permission Assignment for Critical Resource




Use of Potentially Dangerous Function




Use of a Broken or Risky Cryptographic Algorithm




Incorrect Calculation of Buffer Size




Improper Restriction of Excessive Authentication Attempts




URL Redirection to Untrusted Site ('Open Redirect')




Uncontrolled Format String




Integer Overflow or Wraparound




Use of a One-Way Hash without a Salt

In the first part of this series we discussed the 'yield' keyword, and we learned about 'lazy' and 'eager' evaluation. In this part we continue with some of the lesser known C# language features. Like mentioned in the first post, its sometimes difficult to determine what featurers are really 'lesser known', as this is different for every developer. In this post we are looking at several language features, so I'm sure there's something for everyone!


Inline if statement (:? operator)


The inline if operator is a ternary operator (it uses 3 'arguments', and creates one result). The inline if operator is a conditional operator that can be used as a single expression.


Let's take a look at the 'regular' if statement:

string state = "NOT DEFINED";

if (GetValue() > 10)
  state = "High";
  state = "Low";

To give an example, you can use the inline if operator to get the same result with less code:

string state = GetValue() > 10 ? "Hight : "Low"

 If we compare the grammer of the two:

//'Normal' if statement
if (boolean expression)
  true expression
  false expression

//Inline if statement
boolean expression ? true expression : false expression
Using normal if statements, we can nest several statements:
if (condition1)
else if (condition2)
  else if (condition3)

We can do the same with the inline if operator:
var value = condition1 ? action1
                 : condition2 ? action2
                 : condition3 ? action3
                 : action4

 It get's really interesting if you think of the inline if operator as just another expression, much like '10 + 10' or '"Hello" + "World"'. Here are some examples how you can use the inline if operator, to shorten your code, and make it much easier to read:

var useFirstServer = true;
            var server = new PISDK.PISDK().Servers[useFirstServer ? "firstServer" : "secondServer"];

            var number = 10;
            var elem = new AFElement(number < 10 ? "LowNumberElement" : "HighNumberElement");

            var day = "yesterday";
            var value = new AFValue(100, day == "today" ? DateTime.Today : DateTime.Today.AddDays(-1));





The ?? operator (null-coalescing)


One of the things we as programmers have to do all to often, is check for null values. You can never trust user input, or know if a calculation produced a null result. A simple example would be this:

  public void SchrodingersCat()
            //Create a new random generator
            var random = new Random();
            //Create an array with objects and nulls
            var stateArray = new object[] { "Hello world!" , null, "Hello Again!", null };
            //Get a state using a random generated index
            var state = stateArray[random.Next(stateArray.Length -1)];

            //We don't know what 'state' will be, it can be an object or a null

            string stateText = string.Empty;
            if (state != null)
                stateText = state.ToString();
                stateText = "NOTHING";




We cannot know what 'state' will be until we check it. It can be either null or a string. In this case, we use an if statement to check wheter state is null. We can also do it shorter with the inline if statement we discussed earlier in this article.

 public void SchrodingersCat()
            //Create a new random generator
            var random = new Random();
            //Create an array with objects and nulls
            var stateArray = new object[] { "Hello world!" , null, "Hello Again!", null };
            //Get a state using a random generated index
            var state = stateArray[random.Next(stateArray.Length -1)];

            //We don't know what 'state' will be, it can be an object or a null

            Console.WriteLine(state != null ? state.ToString() : "NOTHING");





Here we use the inline if statement to check for a null value. As you can see we don't need any intermediary variables. This is already really short. But, C# provides us with an ever shorter way: the null-coalescing operator (or ??).


The grammer of the ?? operator is:


possiblyNullValue ?? valueIfNull


So, if we want to use it in this case:



  public void SchrodingersCat()
            //Create a new random generator
            var random = new Random();
            //Create an array with objects and nulls
            var stateArray = new object[] { "Hello world!" , null, "Hello Again!", null };
            //Get a state using a random generated index
            var state = stateArray[random.Next(stateArray.Length -1)];

            //We don't know what 'state' will be, it can be an object or a null

            Console.WriteLine(state ?? "NOTHING");





That's even shorter! And it produces again less code. In this case it also improves readability, once you are used to using the ?? operator.


The 'using' statement


The term 'using' has two distinct functions within C#. We all use the 'using' directive everytime we create a new application.


The using directive let's us 'import' a namespace, so that we can use the types of that namespace without having to use the full typename. For example:

using System.Xml.Linq;
using OSIsoft.AF.Asset;



This is something we use everyday. The 'using statement' has a totally different function.


We can use the using statement to define a scope. Outside of this scope, the objects will be disposed. Objects that implement the IDisposable interface deal with unmanaged code. This means, they have unmanaged pointers or handlers that cannot be controlled (or freed) by the Garbage Collector of .NET. The IDisposable interface has only one method, the 'Dispose' method. This happens when you are for instance dealing with the filesystem, or certain network related objects.


For example, let's say we want to make use of a MemoryStream, and ensure that all the (unmanaged) handlers are freed successfully after use. We can use the following code:

  var text = "Hello world!";
            var buffer = Encoding.ASCII.GetBytes(text);
            var stream = new MemoryStream(buffer);

            //Do something with the stream


            //Stream is still accessable here, but it is already disposed. We will get Exceptions when we try
            //to access it after the Dispose method is called



We call the 'Dispose' method after we are done dealing with the MemoryStream. The issue here is that the 'stream' variable will still be in scope (accessable) after we have called the 'Dispose' method. Once you have called the 'Dispose' method, the underlying resources are freed. You will get an Exception if you would try to use stream.Peek().


There is a better, nicer and safer way to ensure proper disposal. This is done with the 'using' statement.

var text = "Hello world!";
var buffer = Encoding.ASCII.GetBytes(text);
using (var stream = new MemoryStream(buffer))
      //Do something with the stream
//stream will be out of scope here



In this case, we are creating a new memorystream from a byte[] array. We can use the stream inside the using block. The variable will be out of scope after the using block, and it will automatically call the 'Dispose' method of the MemoryStream. This is a much safer way than manually having to call 'dispose'. Offcourse, you can 'nest' using statements, which creates really clean code:

var text = "Hello world!";
            var buffer = Encoding.ASCII.GetBytes(text);
            using (var stream = new MemoryStream(buffer))
            using (var streamReader = new StreamReader(stream))
            using (var streamWriter = new StreamWriter(stream))
                //Do something with the stream, streamReader and streamWriter
            //stream, streamReader, streamWriter are out of scope now





In this article we described the usage of the 'inline if' operator, or ?: operator. It can help you produce cleaner and lesser code. We also learned about the null-coalescing operator, or the ?? operator. It is a very short way of doing null checks in a single statement.


The 'using statement', not to be confused with the 'using directive' allows us to create safe and clean code when dealing with unmanaged resources.


Further reads


The :? operator (MSDN)


The ?? operator (MSDN)


The using statement (MSDN)


The using directive (MSDN)


The IDisposable interface (MSDN)


IDisposable: What your mother never told you about resource deallocation (CodeProject)




Previous articles in this series


Exploring lesser known C# Language features Part I (the 'yield' statement)





Hello fellow vCampus members!


The vCampus All-Star awards are granted to vCampus members that actively share their technical expertise with the community. They are considered the most active and most valuable members in the community. Last year there where 3 All-Stars awarded. These where Rhys Kirk from RJK Solutions, Asle Frantzen from Amitec and myself (when I was still working for our partner Atos Origin).


This year we will again reward those who are considered the most valuable members in the community. Next to getting recognized by the community, being a vCampus All-Star will profile yourself (and your company) as being PI development experts. We are planning on announcing the vCampus All-Stars for this year in October. You can get awarded multiple years in a row for your continued involvement with vCampus.


Being a vCampus All-Star will also get you:

  • Personal vCampus blog (if desired)
  • Moderate vCampus forums (if desired)
  • Voluntary participation to team meetings
  • Free admissions for the year to come
    • OSIsoft vCampus & OSIsoft vCampus Live
    • Users Conference
  • A few more surprises…

OSIsoft and the vCampus team will determine who are considered the most valuable members, and who are eligable for this award. We do need input from the community for this. We really want to hear from you! Who do you consider the most valuable members? Is there someone who always has bright answers and questions, who takes part in discussions, and who you consider being among the best and brightest on vCampus?


Let us know by emailing to











A lot of us use Microsoft .NET in their daily efforts to create applications for the PI system. It seems there is still somewhat of a 50/50 spread between VB.NET and C# developers. I myself am an avid C# developer, and I really like the language. The fact that I’m not a VB.NET programmer has nothing to do with the language itself, but it’s more about my history as a developer.








C# (and .NET in general) has a lot of really nice features, and it keeps getting better with every release. With every release, new major functionality becomes available. For instance, the introduction of generics in .NET 2.0, the introduction of WCF/WPF in .NET 3.0, the introduction of LINQ and lambda’s in .NET 3.5, and now the introduction of dynamic typing in .NET 4.0.








A lot of the times, these major changes go accompanied by some lesser changes. A lot of the time, the lesser changes are there to make the bigger changes possible. For instance, LINQ (a big change) relies heavily on ‘Extension Methods’ (a lesser change). Lambdas are also a very big part of LINQ, and these are getting more and more accepted. The acceptance of a more functional programming paradigm embedded into an object oriented language seems to be a very smart decision, that works really well for us programmers.








In this blog post series, I would like to have a look at some of the lesser known constructs in C#. It’s sometimes difficult to decide which ones are ‘lesser known’. It could be that you are already familiar with some of them, but I’m sure there will be some that you are not that familiar with!







The ‘yield’ keyword

I think this is a prime example of a lesser known, and therefore lesser used, construct that could really affect your programming style in a good way.








The yield keyword is used in what we call iterators. An iterator can be a method, get accessor or operator that returns a collection that can be enumerated. A very good example of using this would be an implementation of the ‘GetEnumerator()’ method. This method is being used when you use a foreach statement to loop over a collection (for instance an array or List<T>). You can only use the yield statement when returning an IEnumerable<T> or derivative.








Let’s say, we want to create a method that returns a collection of data. A simple example would be:






static void Main(string[] args)
            var sinusoid = GetSinus(1, 10);
            foreach (var number in sinusoid)

        public static List GetSinus(double from, double to)
            List returnList = new List();
            Console.WriteLine("Getting sinus");
            for (double i = from; i < to; i++)
                var sin = Math.Sin(i);

            return returnList;





As you can see, in order for us to create a collection of sinusoid values, we first create a new empty List<double>. We use a ‘for’ loop to go through the input range, and we add every calculated sinusoid value to the list. Once we are done, we return the entire list.








If we run this code, the output will be:










Let’s introduce a method that does the same, but uses the ‘yield’ keyword.




   public static IEnumerable GetSinus(double from, double to)


            Console.WriteLine("Getting sinus");

            for (double i = from; i < to; i++)

                yield return Math.Sin(i);



There are several changes to this method implementation. For instance, the return value is a ‘IEnumerable<double>’. We don’t use a returnlist here. We just loop trough the range using a ‘for’ loop, and we return our calculated sinus value using the ‘yield return’ statement.





If we run the application with our new GetSinus method, the output will be:


















Something has changed in the output… I invite you to have a look at the first code sample, and both output samples. You will notice something is off… We will come back to that later.






In addition to the ‘yield return <expression>’ statement, we can also use ‘yield break’, which is implemented in the following example:








 public static IEnumerable GetSinus(double from, double to)


            Console.WriteLine("Getting sinus");

            for (double i = from; i < to; i++)

                if (i > 5)

                    yield break;


                    yield return Math.Sin(i);




This example will break off the iteration when i > 5. This means that it will break out of the for loop, and ends the execution of this method. You can for instance use this if you trap exceptions in  your iterator block, and want to end iteration when an error occurs.






Back to the output of the two samples…










You will notice that the “Looping” and “Getting sinus” writelines are executed in a different order. We can see that in this example the “Getting sinus” writeline is executed after the “Looping” writeline. This means, that the actual method gets executed when running the foreach loop. But, how can this be? We created the variable ‘sinusoid’, and assigned the output of the ‘GetSinus’ method before the foreach loop.








This behavior is called ‘Defered Execution’, or sometimes called ‘lazy execution’. This means that an expression is not evaluated until its realized value is needed. In this case, the value isn’t needed until the foreach loop. That’s why the “Getting Sinus” writeline is executed after the ‘Looping” writeline. If you have used LINQ or LINQtoSQL before, you may have noticed this behavior also.








For this sample, we can negate this behavior by changing the assignment of the ‘sinusoid’ variable to:


var sinusoid = GetSinus(1, 10).ToList();




In this case, the realized values of the GetSinus iterator are needed immediately, because we are using the .ToList() extension method to create List<double>.






The purpose of ‘Defered Execution’ is to improve performance when manipulating large data collections. This is especially true when working with multiple ‘chained’ queries or manipulations.






One effect of this lazy evaluation is that you can ‘reuse’ your expression, for instance, after your data changes. Let’s see an example of that:






 static void Main(string[] args)
            //Create an array of ints
            var numbers = new int[] { 1, 5, 7, 8, 2, 7, 9, 4, 3 };
            //Create a LINQ query that selects all numbers lower than 5
            var lowNumbers = from n in numbers

                             where n < 5

                             select n;

            //Print all the low numbers
            Console.WriteLine("First time printing low numbers");
            foreach (var lowNumber in lowNumbers)


            //Loop trough the numbers array, and decrease every number by 2

            for (int i = 0; i < numbers.Length; i++)


 = numbers
 - 2;

            //Print all the low numbers again, using the same lowNumbers variable
            Console.WriteLine("Second time printing low numbers");
            foreach (var lowNumber in lowNumbers)




The output of this example will be:








This is, at first sight, a bit counter-intuitive. Shouldn’t the result of the assigned ‘lownumbers’ variable be the same throughout the whole execution of this code? This is how ‘Defered Execution’ behaves.




The best way to see it is that ‘lowNumbers’ is not assigned the output of the LINQ query, but it is assigned the LINQ query itself. Every time the realized values of ‘lowNumbers’ are needed, the LINQ query gets executed.




Again, we can negate this effect by assigning ‘lownumbers’ like this:




var lowNumbers = (from n in numbers


                             where n < 5


                             select n).ToList();




In this way, the realized values of the LINQ query are immediately needed to create the List<double> using the .ToList() extension method.


If we do that, the output of our sample will be:
















This shows we negated the ‘Lazy evaluation’ by making it ‘Eager Evaluation’, using the .ToList() method.




We can use the ‘yield’ statement to create iterator blocks. Iterator blocks return collections of type ‘IEnumerable<T>’ or derivatives.


When we use the ‘yield’ statement, we don’t need any temporary collections that we will return. By using the ‘yield’ statement, we use less code and it will be better readable.


Iterator blocks use Lazy Evaluation, we can negate the lazy evaluation by immediately assigning the realized values.


·         In lazy evaluation, a single element of the source collection is processed during each call to the iterator. This is the typical way in which iterators are implemented.


·         In eager evaluation, the first call to the iterator will result in the entire collection being processed. A temporary copy of the source collection might also be required. For example, the OrderBy method has to sort the entire collection before it returns the first element.

Further reads

The ‘yield’ statement on MSDN


Iterators on MSDN


Deferred Execution and Lazy Evaluation in LINQ to XML on MSDN


101 LINQ Samples: Query Execution

Hi everyone!


Rhys blogged about how he thought it was important to be able to wave at PI using the Microsoft Kinect sensor. I took this as a challenge, and bought one ... I started coding, and here is a short demo video of the results so far.


Click the link to view the video! I hope you enjoy it! (best viewed in 720P)


View the video on youtube!






Hello fellow vCampus members! As most of you already know, I recently joined OSIsoft. After being involved with vCampus for quite a long time as a partner, I now have the pleasure to speak to you as a vCampus Team member.

The next vCampus Live! will already be the third vCampus event!  As a community, we can all agree this is really ourevent. A lot of tech talk, great networking possibilities, and not a lot of marketing talk.

We have received a lot of feedback on the previous events, and one thing really stands out: We want more hands-on experience during the event.

OSIsoft has listened to this, and has changed the format. For the next vCampus Live! event, there will be much more hands-on labs, specially made for the occasion. This means:  less PowerPoint, more interaction, and more coding!

We are still working on the precise topics of the hands-on labs. This is where we, as the community can step in.

What we would like to ask you is:

·         What topics do you want to get more hands-on experience with?

·         How do you think this event can help you become an even better PI Developer?

We live in very exciting times, new technologies emerge in rapid pace. We are moving into a new era of computing. The future is happening right now! Be a part of this, and join us by commenting below.  Also you can email us at with your comments. Help us to make this event the best PI Tech event ever!

Please also make sure you register for the PI Coresight webinar on June 15!





3rd party appstore

Posted by MichaelvdV@Atos Nov 8, 2010

About a year ago, our fellow vCampus member MOH M ERIGH opened a thread about a 3rd party vCampus appstore.


Since then, a lot of good discussion has evolved around this subject. Personally, I really like the idea of 3rd party companies (or individuals) to have the opportunity to offer applications to other OSIsoft partners and customers.


I’m pleased to announce the initial development of a OSIsoft Appstore. Please note that this is purely the technical development. The procedural and legal issues involved have not been addressed.


The main idea behind this development is simple: let’s make a practical start implementing this idea.


You can find the development version here: [Silverlight 4]


For the Cloud fans here: it’s a Windows Azure Cloud application, that uses SQL Azure for the backend, and Silverlight 4 for the frontend. It was hacked together over the weekend, so understandibly, it's not at all done yet.


At this point it’s populated with some mock data. The usage is pretty simple. On the left side you have the ability to browse through categories (or select ‘companies’  to browse by company). On the right upper pane, you will find all the products that belong to the selection. On the right pane, you will find the detailed information about the product. If you want to order a product, you are presented with a form to fill out. You can ask question to the owner in the same way.


Note: not all product categories have products in this mockup J


I’m hoping this will be received with enthusiasm. I’m not trying to hijack the idea here, it’s just to make a start with creating a 3rd party OSIsoft appstore.


I would like to invite everyone to have a look, and give your reaction. Maybe it will be time to further crystallize the idea and set up specifications.


I haven’t looked at any of the legal stuff, but my initial thought would be that this is just a marketplace to bring customers and companies together. Information about the product and ordering the product is a deal between the costumer and the company.


EDIT: The application can be offline or faulting sometimes. This is because I'm developing in the same instance. I hope to resolve this asap.


EDIT2: Updates on the development progress can be found at [DEAD LINK]


Let's become Rebels!

Posted by MichaelvdV@Atos Nov 4, 2010

After vCampus Live! I haven't been that active on vCampus. Were doing some pretty exciting projects here at Atos, but that keeps me away from being as active on vCampus as I sometimes would like to be. In the mean time, a lot has happened. There are some pretty good discussions going on about Silverlight vs HTML5, the envisioning of an 3rd party appstore, and off course Cloud computing and PI.


The last one, is the one I would like to talk about. Ahmad asked us:


"As the community on the cutting edge of PI development and integration, what do you think of offering PI as a service in the Cloud? What are the potential opportunities? How about the challenges? What would it take to win the trust of customers to let someone else host their PI System? How would you envision the interaction between the PI System and data sources in the plants? Would it provide a good opportunity for our partners? Share your ideas with us."


These are all pretty good and challenging questions. Specially, the first two questions. What are the opportunities, and what are the challenges? These questions cannot be answered quickly. But, it really provides the opportunity for some good and deep thinking.


The 3rd question: "What would it take to win the trust of customers to let someone else host their PI System?" is another very interesting one, but not as interesting as the first two questions. I would like to say, that this question is interesting, but totally irrelevant.


But,  this is the question that everyone is trying to answer. The overall consensus seems to be that (existing) PI costumers would in no way allow their data to be stored in ‘the cloud', and therefore, that cloud computing and PI is not a viable option.  Let's assume for now, that our traditional customers are not in any way interested in hosting their PI data in the cloud.


With establishing this assumption, let us look back at the primary (and most important question): "What are the potential opportunities?"


 "What are potential opportunities of cloud computing", and "No way I'm going to host my data off-premise". This is not mutually exclusive. It's very thought provoking though, and allows for creative ‘potential opportunities'.


Wikipedia offers the following definition to cloud computing:


"Cloud computing is Web-based processing, whereby shared resources, software, and information are provided to computers and other devices (such as smart phones) on demand over the Internet."


This in itself contains the answer to question number one. Sharing information and software. This opens up the new  opportunities: offering time series data storage and calculations as a service for the internet.


This is a paradigm fork for us, which is not excluding the ‘traditional' usage of the PI system. Cloud computing in itself is a paradigm shift, so we have to shift paradigm to see the opportunities! One paradigm will support the other.


Let's envision some potential opportunities:

  • Offering a public ‘on demand' service to web applications or application servers to store logging information and time series information, run calculations, and provide visualization for them. Things like number of hits, Performance Information, database usages, etc. These figures will become more and more important in the ‘on demand world', to become or remain sustainable.
  • Offering domain specific time series storage and calculations, stuff like GPS locations. Think about storing GPS locations (time stamped) for car rental/lease companies, transport companies, UPS, etc.
  • Offering the ability to share, compare and publish data. Sustainability and environmental data, weather information, traffic information, etc. There is an ongoing demand for open-governments and companies. Why not use technologies like Web services and OData to give companies and governments the opportunity to publish this information. Give client applications the possibility to combine and join information from different sources.
  • Offer the ability to run complex and ‘on the fly' calculations that take a lot of resources
  • Etc. etc. etc.

The basis of my thought process are that cloud computing is a paradigm shift in itself. We are trying to fit in using our ‘old ways'. We have to shift paradigm ourselves to be able to fully appreciate the opportunities of Cloud Computing. We must not see Cloud Computing as this big threatening thing that we don't fully understand, we have to embrace it for what it is, and see the opportunities that it offers.


We are the Empire, the internet and Cloud Computing are the Rebels. We are used to tight contracts, procedures and safety and we are bound by that. The internet and cloud computing is free,  anarchy like and not bound to rules. We have to become Rebels to fully appreciate the possibilities, and become entrepreneurs in this new environment.


If we want in, we have to play by the rules of the Internet.


Disclaimer: This article is meant to be thought provoking, and in no way discredit or disrespect anyone's opinion

Having fun with AF and dynamic programming

I haven't been really active on vCampus lately due to time constraints. We are working on some pretty exciting projects here at Atos, but that takes it's toll on my vCampus activity. I thought it would be time to make use of my newly earned Blogging priviliges, and talk some geek


Today, let's talk about dynamic programming with c# and .NET 4.0. For those of you who aren't using Visual Studio 2010, and if you have the chance, you should really switch. Besided having the awesome benefits of .NET 4.0, the UI has changed a lot, and has some really cool features you should check out.


Allright, dynamic programming in C#. What's that about?


 public class DAFElement : DynamicObject
        public AFElement EmbeddedElement { get; set; }


        public DAFElement(AFElement embeddedElement)
            EmbeddedElement = embeddedElement;


        public override bool TryGetMember(GetMemberBinder binder, out object result)
            result = null;
            var name = binder.Name.Replace("_", " ");
            if (EmbeddedElement.Attributes.Contains(name))
                result = new DAFAttribute(EmbeddedElement.Attributes[name]);
                return true;
            if (EmbeddedElement.Elements.Contains(name))
                result = new DAFElement(EmbeddedElement.Elements[name]);
                return true;
            var prop = EmbeddedElement.GetType().GetProperty(name);
            if (prop != null)
                result = prop.GetValue(EmbeddedElement, null);
                return true;
            return false;

Filter Blog

By date: By tag: