Get property values from a string using Reflection - c#-4.0

I am new to this concept of reflection and finding problem in retrieving property value from a string. E.g.
I have a class Employee with following properties :
public string Name {get;set;}
public int Age {get;set;}
public string EmployeeID {get;set;}
string s = "Name=ABCD;Age=25;EmployeeID=A12";
I want to retrieve the value of each property from this string and create a new object of Employee with those values retrieved from the string for each field.
Can anyone please suggest how it can be done using reflection ??

//may be..
string s = "Name=ABCD;Age=25;EmployeeID=A12";
string[] words = s.Split(';');
foreach (string word in words)
{
string[] data = word.Split('=');
string _data = data[1];
Console.WriteLine(Name);
}

Here an example of how you maybe could do it
it used Reflection like you wanted ^^
using System;
using System.Collections.Generic;
using System.Reflection;
namespace replace
{
public class Program
{
private static void Main(string[] args)
{
var s = "Name=ABCD;Age=25;EmployeeID=A12";
var list = s.Split(';');
var dic = new Dictionary<string, object>();
foreach (var item in list)
{
var probVal = item.Split('=');
dic.Add(probVal[0], probVal[1]);
}
var obj = new MyClass();
PropertyInfo[] properties = obj.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
Console.WriteLine(dic[property.Name]);
if (property.PropertyType == typeof(Int32))
property.SetValue(obj, Convert.ToInt32(dic[property.Name]));
//else if (property.PropertyType== typeof(yourtype))
// property.SetValue(obj, (yourtype)dic[property.Name]);
else
property.SetValue(obj, dic[property.Name]);
}
Console.WriteLine("------------");
Console.WriteLine(obj.Name);
Console.WriteLine(obj.Age);
Console.WriteLine(obj.EmployeeID);
Console.Read();
}
}
public class MyClass
{
public string Name { get; set; }
public int Age { get; set; }
public string EmployeeID { get; set; }
}
}

Related

Object does not match target type with SetValue using Type

I'm trying to dynamically build set objects based on a user input document. For some reason SetValue is throwing Object does not match target type, despite that it does.
Is what im trying to achieve even possible?
private void MapProp(string prop, string invalue)
{
var currType = _userAssembly.GetType(_className);
var property = currType.GetProperty(prop, BindingFlags.Public | BindingFlags.Instance);
var value = Convert.ChangeType(invalue, property.PropertyType);
property.SetValue(styleType, value, null);
}
}
Currently its attempting to map to said object:
public class TestObject: ITestObj
{
public string PropertyA {get;set;}
public string PropertyB {get;set;}
}
Calling Code
MapProp("PropertyA", "testValue");
and the getType classname = .Assembly.TestObject
#user4550364 ,I dont know what does your _user assembly does ,so I am gonna put my sample code ,this might help you to adapt the idea to your code.This is also an example of late binding.
Class file
public class TestObject: ITestObj
{
public string PropertyA {get;set;}
public string PropertyB {get;set;}
void Print(string PropertyA,string PropertyB)
{
//Assuming that interface ITestObj has this method definition and hence implementing here.
}
}
Main code
using System.Reflection;
static void Main(string[] args)
{
Assembly executingassembly = Assembly.GetExecutingAssembly();
Type TestObjecttype = executingassembly.GetType("ur_namespace.TestObject");
object instance = Activator.CreateInstance(TestObjecttype );
string[] parameters = new string[2];
parameters[0] = "PropertyA ";
parameters[1] = "PropertyB ";
//To get properties
PropertyInfo[] properties = TestObjecttype .GetProperties();
foreach (PropertyInfo property in properties)
{
Console.WriteLine(property.PropertyType.Name+" "+property.Name);
}
MethodInfo method = customertype.GetMethod("Print");
//Object created ,now invoke using its instance
string printMethodInvoked= (string)method.Invoke(instance, parameters);
Console.WriteLine(printMethodInvoked);
Console.Read();
}
}

Create field in SharePoint programmatically using CSOM (Not with XML)

Is it possible to create fields in SharePoint with CSOM, not using XML?
I've seen many examples using XML, but none with just setting properties for the field programmatically?
fields.Add(new **FieldCreationInformation** {
InternalName = "Test",
etc..
});
That's doable, in the following example is introduced a FieldCreationInformation class:
[XmlRoot("Field")]
public class FieldCreationInformation
{
[XmlAttribute("ID")]
public Guid Id { get; set; }
[XmlAttribute()]
public string DisplayName { get; set; }
[XmlAttribute("Name")]
public string InternalName { get; set; }
[XmlIgnore()]
public bool AddToDefaultView { get; set; }
//public IEnumerable<KeyValuePair<string, string>> AdditionalAttributes { get; set; }
[XmlAttribute("Type")]
public FieldType FieldType { get; set; }
[XmlAttribute()]
public string Group { get; set; }
[XmlAttribute()]
public bool Required { get; set; }
public string ToXml()
{
var serializer = new XmlSerializer(GetType());
var settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
var emptyNamepsaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
using (var stream = new StringWriter())
using (var writer = XmlWriter.Create(stream, settings))
{
serializer.Serialize(writer, this, emptyNamepsaces);
return stream.ToString();
}
}
public FieldCreationInformation()
{
Id = Guid.NewGuid();
}
}
and then extension method for creating a new field:
public static class FieldCollectionExtensions
{
public static Field Add(this FieldCollection fields, FieldCreationInformation info)
{
var fieldSchema = info.ToXml();
return fields.AddFieldAsXml(fieldSchema, info.AddToDefaultView, AddFieldOptions.AddFieldToDefaultView);
}
}
Usage
var fieldInfo = new FieldCreationInformation();
fieldInfo.FieldType = FieldType.Geolocation;
fieldInfo.InternalName = "ContactsLocation";
fieldInfo.DisplayName = "Contacts Location";
ctx.Site.RootWeb.Fields.Add(fieldInfo);
ctx.ExecuteQuery();
When I add fields with CSOM/JSOM I use the method on the FieldCollection AddFieldAsXml. This requires you to build a string of xml with all of the properties for the desired field, but it works. I included an excerpt of the related cpde below:
Microsoft.SharePoint.Client.Web web = _context.Web;
FieldCollection fields = web.Fields;
_context.Load(fields);
_context.ExecuteQuery();
Field field = fields.FirstOrDefault(f => f.StaticName == _staticName);
if (field == null)
{
Field createdField = fields.AddFieldAsXml(xml, false, AddFieldOptions.AddToNoContentType);
_context.Load(createdField);
_context.ExecuteQuery();
}
Similar code is used if you would like to add a field directly to an existing list.

Xml Parsing in C#

http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.atom on this site, I wrote the following code to retrieve the data.
protected void Button1_Click(object sender, EventArgs e)
{
string adresal = "http://" + txtAd.Text;
WebResponse GelenCevap;
WebRequest adresistegi = HttpWebRequest.Create(adresal);
GelenCevap = adresistegi.GetResponse();
StreamReader CevapOku = new StreamReader(GelenCevap.GetResponseStream());
string KaynakKodlar = CevapOku.ReadToEnd();
XmlDocument xmlDoc = new XmlDocument(); // Create an XML document object
xmlDoc.Load("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.atom"); // Load the XML document from the specified file
XmlNodeList depremler = xmlDoc.GetElementsByTagName("entry");
foreach (XmlNode node in depremler)
{
var a = node.ChildNodes;
foreach (XmlElement x in a)
{
ListBox1.Items.Add(x.InnerText);
}
}
}
In this way I get all the data in the ListBox.But I need to assign them to variable data line by line.How can I do? I would appreciate if you can help.
Also i need id,title, updated, georss:point,georss:elev variables.
First add an Enrty and Category class:
public class Entry
{
public string Id { get; set; }
public string Title { get; set; }
public string Updated { get; set; }
public string Summary { get; set; }
public string GPoint { get; set; }
public string GElev { get; set; }
public List<string> Categories { get; set; }
}
public class Category
{
public string Label { get; set; }
public string Term { get; set; }
}
Then use LINQ to XML
XDocument xDoc = XDocument.Load("path");
List<Entry> entries = (from x in xDoc.Descendants("entry")
select new Entry()
{
Id = (string) x.Element("id"),
Title = (string)x.Element("title"),
Updated = (string)x.Element("updated"),
Summary = (string)x.Element("summary"),
GPoint = (string)x.Element("georss:point"),
GElev = (string)x.Element("georss:elev"),
Categories = (from c in x.Elements("category")
select new Category
{
Label = (string)c.Attribute("label"),
Term = (string)c.Attribute("term")
}).ToList();
}).ToList();

Assign value to workflow variable

I have one question about Windows Workflow Foundation 4. I have an activity named PositionArrayActivity. This activity has a Sequence activity inside it. I need that in Execute method (during the workflow execution) oneFund variable mapping his value to PORTFOLIO_NAME that is created in Create method.... What have I to do to mapping oneFund value to PORTFOLIO_NAME at runtime?
Thanks
public sealed class PositionArrayActivity : NativeActivity, IActivityTemplateFactory
{
[Browsable(false)]
public Dictionary<string, List<Entity>> dictionary = new Dictionary<string, List<Entity>>();
public ActivityAction<Entity[]> Body { get; set; }
public Entity[] PositionList { get; set; }
public SqlDataReader rdr;
public SqlDataReader sdr;
public Entity[] positionArray;
public List<String> fundList;
public String oneFund { get; set; }
public String date { get; set; }
public List<Entity> listToArrayPositions;
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.AddDelegate(Body);
}
protected override void Execute(NativeActivityContext context)
{
// A lot of code....
}
public Activity Create(DependencyObject target)
{
Variable<string> var = new Variable<string>
{
Name = "PORTFOLIO_NAME"
};
var fef = new PositionArrayActivity();
var aa = new ActivityAction<Entity[]>();
var da = new DelegateInArgument<Entity[]>();
da.Name = "positions";
fef.Body = aa;
aa.Argument = da;
aa.Handler = new Sequence
{
Variables = { var }
};
return fef;
}
}
You need to have an ActivityContext to set a variable value so first move the declaration of the var (did that name actually compile?) to a higher scope.
Then in Execute
var.Set(activityContext, oneFund);
One thing though, the oneFund property will only be set once at application startup so you may have some surprising results. If you wanted that to be for each instance, you need an inargument.

Deserialization of XDocument doesn't work

I have this code:
[Serializable]
[XmlRoot("ISO_CCY_CODES")]
public class IsoCurrencyCodes
{
public IsoCurrencyCodes()
{
IsoCodes = new List<IsoCurrencyCode>();
}
public IsoCurrencyCodes(List<IsoCurrencyCode> isoCodes)
{
IsoCodes = isoCodes;
}
[XmlArrayItem("ISO_CURRENCY")]
public List<IsoCurrencyCode> IsoCodes { get; set; }
public static IEnumerable<IsoCurrencyCode> Get()
{
var doc = XDocument.Parse(XmlStringIsoCodes.XmlSource.Replace("\r\n", ""));
var res = doc.Deserialize<IsoCurrencyCodes>();
return res.IsoCodes;
}
}
[Serializable]
[XmlRoot("ISO_CURRENCY")]
public class IsoCurrencyCode
{
public IsoCurrencyCode()
{
}
[XmlElement(ElementName = "ENTITY")]
public string Entity { get; set; }
[XmlElement(ElementName = "CURRENCY")]
public string Currency { get; set; }
[XmlElement(ElementName = "ALPHABETIC_CODE")]
public string Alpha_Code3 { get; set; }
[XmlElement(ElementName = "NUMERIC_CODE")]
public int NumCode { get; set; }
[XmlElement(ElementName = "MINOR_UNIT")]
public string MinorUnit { get; set; }
}
And this code, for deserialization:
public static XDocument Serialize<T>(this T source)
{
var ser = new XmlSerializer(source.GetType());
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
{
ser.Serialize(writer, source);
}
return XDocument.Parse(sb.ToString());
}
public static T Deserialize<T>(this XDocument xmlDocument)
{
var xmlSerializer = new XmlSerializer(typeof (T));
using (var reader = xmlDocument.CreateReader())
return (T) xmlSerializer.Deserialize(reader);
}
This is the XML source
But deserialization doesn't work. Please help.
Thanks!
I believe you only want to use XMLArray if you have a collection element for all of the items to sit underneath. For example here it could be ISO_CURRENCIES. I'm assuming you can't change the source in this case, so just use this instead:
[XmlElement("ISO_CURRENCY")]
public List<IsoCurrencyCode> IsoCodes { get; set; }
You should find that works.
Additionally, if you find you have further problems in getting the deserialization classes right, you can have them autogenerated for you from the XML and then you can take a look at the code that is created:
xsd source.xml
xsd source.xsd /c
This will create source.cs which you can then use in your project or adapt for your own uses.
As a further note, you'll find you can't use int for Minor_Unit as it's nullable (look at ANTARCTICA). You can't deserialize straight to an int?, so you'll either have to make it a string or go via another property, look at this question for more information.

Resources