Why can't I update metadata on an SPFile object? - c#

According to Microsoft's documentation:
The Windows SharePoint Services 3.0
object model supports updating file
metadata. You can use an indexer on
this property to set a value. For
example, to set the value of the
MyDate property for a given file to
the current date and time, use the
indexer and call the Update method, as
follows:
[Visual Basic]
oFile("MyDate") = DateTime.Now
oFile.Update()
[C#]
oFile["MyDate"] = DateTime.Now;
oFile.Update();
But when I write the line of code:
oFile["Test"] = "test";
It errors out with:
Cannot apply indexing with [] to an
expression of type
'Microsoft.SharePoint.SPFile'
Am I doing something wrong or did Microsoft screw up?

I don't have SharePoint to try it on right now, but it looks like sample is wrong. I believe it should be oFile.Properties["Test"]="test"; as the article talks about Properties property.

Related

What's the easiest way to create a managed visualiser in C#?

I have a background in C++ and recently I started working in C#.
I have written following pieces of code (in Visual Studio):
var list_Loads = database.GetData<Load>().ToList();
var test_list = list_Loads.Where(o => (o.Name.Substring(0, 3) == "123")).ToList();
When I run the program and I move my mouse over both lists, first I get the count, which is very useful, but when I ask for the entries, this is what I get:
0 : namespace.Load
1 : namespace.Load
2 : namespace.Load
...
Not very useful, as you can imagine :-)
So my question: how can I show the Name attributes of those objects?
I thought: no problem. I have a background in native visualisers, so it should be rather easy to turn this into useful information, but then it comes:
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Then I found another solution, which comes down to: "Write an entire C# project, debug, test and install it and it might work" (see documentation on "Custom visualisers of data" on the Microsoft website).
I almost choked in my coffee: writing an entire project, just for altering the view of an object??? (While, in C++, you just create a simple .natvis file, mention the classname and some configuration, launch .nvload and that's it.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
By the way, when I try to load a natvis file in Visual Studio immediate window, this is what I get:
.nvload "C:\Temp_Folder\test.natvis"
error CS1525: Invalid expression term '.'
What am I doing wrong?
Thanks in advance
OP (my emphasis):
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
If you just want to specify [DebuggerDisplay] on a type, you don't have to have access to the source code. You can make use of [assembly:DebuggerDisplay()] and control how a type appears in the debugger. The only downside is that [assembly:DebuggerDisplay()] naturally only affects the current assembly whose code your mouse is hovering over. If you wish to use the customised display in other assemblies that you own, then you must repeat the [assembly:DebuggerDisplay()] definition.
Here's an easy before-and-after example with DateTime. I picked DateTime because we generally don't have access to the source code and it has some interesting properties:
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
...which on my machine defaults to:
Maybe I'm fussy and I just want to see:
Day of the week and
Day of the year
...I can do that via:
using System.Diagnostics;
[assembly: DebuggerDisplay("{DayOfWeek} {DayOfYear}", Target = typeof(DateTime))]
...which results in:
Example:
namespace DebuggerDisplayTests
{
public class DebuggerDisplayTests
{
public DebuggerDisplayTests()
{
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
}
}
.
.
.
}
Overrides
[assembly:DebuggerDisplay()] can also be used as a means to override pre-existing [DebuggerDisplay] on a 3-rd party type. Don't like what style they have chosen? Is the type showing far too much information? Change it with [assembly:DebuggerDisplay()].

Log4Net, how to add a custom field (variable) to my logging

I'm referring to the excellent post :
Log4Net, how to add a custom field to my logging
But it doesn't give me the entire solution.
No problem to log a string like "This is a test", but If I want to log a variable, it's responding (null).
Here is my snipped code not working:
log4net.GlobalContext.Properties["versionid"] = Variables.IDVERSION;
Here is my working snipped code :
log4net.GlobalContext.Properties["versionid"] = " This is a test";
Although, IDVERSION is a public property systematically updated in my code c#.
Has anyone an idea How to solve this problem? I think I'm near the solution.
At the moment you call this:
log4net.GlobalContext.Properties["versionid"] = Variables.IDVERSION;
The property will hold the value of Variables.IDVERSION at that moment. It won't automagically track updates to the Variables.IDVERSION variable.
So if you set Variables.IDVERSION later in code, you need to do the assignment to Properties["versionid"] again.
When log4net evaluates context properties it calls the .ToString() method of the property value. So you could have dynamic property values if you have a reference as a value (I believe your idversion field is a value type eg. Int?).
See https://logging.apache.org/log4net/release/manual/contexts.html for more details

Does Simple.OData.Client support open properties?

I am working with Simple Odata Library
https://github.com/object/Simple.OData.Client/wiki
I need to define open parameters, but i dont seam to see any definition or documentation for this.
Example for clarification:
Along with my oData call, i send a parameter called "mode", which i can set to any number between 0-10. My server will know what to do with it. This parameter however is not pre-defined.
Recent releases of Simple.OData.Client support OData open types, look at examples here:
https://github.com/object/Simple.OData.Client/blob/master/Simple.OData.Client.IntegrationTests/TripPinTests.cs
Search for tests containing "OpenProperty".
user2824991:
I think so. I have tested the untyped and typed scenario for both query and update.
For example:
var order = await client.For("Orders")
.Set(new {OrderId = 9, OrderName = "New Order", MyProperty = "Dynamic Property", GuidProperty = Guid.NewGuid()})
.InsertEntryAsync();
Where, "OrderId" and "OrderName" are both declared properties, while "MyProperty" and "GuidProperty" are both dynamic properties.
Here's my test codes update. it belongs to my sample project.

WiX burn: how to change 'WixBundleManufacturer' in bootstrapper application?

I am building a customizable setup application with WiX, having started with this tutorial:
http://bryanpjohnston.com/2012/09/28/custom-wix-managed-bootstrapper-application/
The setup needs to be customizable, so I need to set some Variables from inside my MainViewModel this is an example:
var customProductName = "The Custom Product";
this.Bootstrapper.Engine.StringVariables["WixBundleName"] = theCustomProduct;
This works how expected. However, I cannot set the Variable WixBundleManufacturer. I get a System.ArgumentException: Value does not fall within the expected range.
Is it somehow possible to set the manufacturer value from inside my view model at runtime?
No, the WixBundleManufacturer is read-only variable set from the authored Bundle element Manufacturer attribute. You could open a feature request.
The feature request was implemented in v3.10.0.1719. The variable is now writable like any other Burn variable.

C# property attributes

I have seen the following code:
[DefaultValue(100)]
[Description("Some descriptive field here")]
public int MyProperty{...}
The functionality from the above snippit seems clear enough, I have no idea as to how I can use it to do useful things. Im not even sure as to what name to give it!
Does anyone know where I can find more information/a tutorial on these property attributes?
I would be also interested in any novel / useful tasks this feature can do.
The functionality from the above
snippit seems clear enough,
Maybe not, as many people think that [DefaultValue()] sets the value of the property. Actually, all it does to tell some visual designer (e.g. Visual Studio), what the code is going to set the default value to. That way it knows to bold the value in the Property Window if it's set to something else.
People have already covered the UI aspect - attributes have other uses, though... for example, they are used extensively in most serialization frameworks.
Some attributes are given special treatment by the compiler - for example, [PrincipalPermission(...)] adds declarative security to a method, allowing you to (automatically) check that the user has suitable access.
To add your own special handling, you can use PostSharp; there are many great examples of using PostSharp to do AOP things, like logging - or just code simplification, such as with automatic INotifyPropertyChanged implementation.
They are called Attributes, there is a lot of information in msdn, e.g. http://msdn.microsoft.com/en-us/library/z0w1kczw.aspx
In general they don't "do" anything on their own, they are used by some other code that will use your class. XmlSerialization is a good example: XmlSerializer (provided by Microsoft as part of the framework) can almost any class (there are a number of requirements on the class though) - it uses reflection to see what data is contained in the class. You can use attributes (defined together with XmlSerializer) to change the way XmlSerializer will serialize your class (e.g. tell it to save the data as attribute instead of an element).
The ones in your example is used by the visual designer (i.e. MS Expression Blend and Visual Studio designer) to give hints in the designer UI.
Note that they are metadata and will not affect the property logic. Setting DefaultValue for instance will not set the property to that value by default, you have to do that manually.
If you for some reason want to access these attributes, you would have to use reflection.
See MSDN for more information about designer attributes.
We use it to define which graphical designer should be loaded to configure
an instance of a specific type.
That is to say, we have a kind of workflow designer which loads all possible command
types from an assembly. These command types have properties that need to be configured,
so every command type has the need for a different designer (usercontrol).
For example, consider the following command type (called a composite in our solution)
[CompositeMetaData("Delay","Sets the delay between commands",1)]
[CompositeDesigner(typeof(DelayCompositeDesigner))]
public class DelayComposite : CompositeBase
{
// code here
}
This is information is used in two places
1) When the designer creates a list of commands, it uses the CompositeMetaData
to display more information about the command.
2) When the user adds a command to the designer and the designer creates
an instance of that class, it looks at the CompositeDesigner property,
creates a new instance of the specified type (usercontrol) and adds it
to the visual designer.
Consider the following code, we use to load the commands into our "toolbar":
foreach (Type t in assembly.GetExportedTypes())
{
Console.WriteLine(t.Name);
if (t.Name.EndsWith("Composite"))
{
var attributes = t.GetCustomAttributes(false);
ToolboxListItem item = new ToolboxListItem();
CompositeMetaDataAttribute meta = (CompositeMetaDataAttribute)attributes
.Where(a => a.GetType() == typeof(Vialis.LightLink.Attributes.CompositeMetaDataAttribute)).First();
item.Name = meta.DisplayName;
item.Description = meta.Description;
item.Length = meta.Length;
item.CompositType = t;
this.lstCommands.Items.Add(item);
}
}
As you can see, for every type in the assembly of which the name ends with "Composite",
we get the custom attributes and use that information to populate our ToolboxListItem instance.
As for loading the designer, the attribute is retreived like this:
var designerAttribute = (CompositeDesignerAttribute)item.CompositType.GetCustomAttributes(false)
.Where(a => a.GetType() == typeof(CompositeDesignerAttribute)).FirstOrDefault();
This is just one example of how you might be able to use custom attributes,
I hope this gives you a place to start.
These attributes customize the design time experience.
http://msdn.microsoft.com/en-us/library/a19191fh.aspx

Categories