How to deserialize a nested Array from xml to c# object? - c#

I'm trying deserialize the following soap xml response from my web service to a C# object:
<?xml version="1.0" encoding="utf-16"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<ns2:ExportPositionsQueryResponse xmlns:ns2="http://ns" xmlns:ns3="http://nscpm/datatypes/schema/v2011_06_01" xmlns="http://nscpmexportvalue/schema/v2011_06_01">
<ns2:Positions>
<FieldTypes>
<FieldType ExtId="PF_NAME" Type="string"></FieldType>
<FieldType ExtId="POSITION_QUANTITY" Type="double"></FieldType>
<FieldType ExtId="INST_NAME" Type="string"></FieldType>
<FieldType ExtId="INST_TYPE" Type="string"></FieldType>
<FieldType ExtId="POSITION_TYPE" Type="string"></FieldType>
<FieldType ExtId="POSITION_CLASS" Type="string"></FieldType>
</FieldTypes>
<Position>
<Field ExtId="INST_NAME" Value="name"></Field>
<Field ExtId="INST_TYPE" Value="asd"></Field>
<Field ExtId="PF_NAME" Value="ads"></Field>
<Field ExtId="POSITION_CLASS" Value="asd"></Field>
<Field ExtId="POSITION_TYPE" Value="asd"></Field>
<Field ExtId="POSITION_QUANTITY" Value="asd"></Field>
</Position>
<Position>
<Field ExtId="INST_NAME" Value="asd"></Field>
<Field ExtId="INST_TYPE" Value="asd"></Field>
<Field ExtId="PF_NAME" Value="asd"></Field>
<Field ExtId="POSITION_CLASS" Value="ads"></Field>
<Field ExtId="POSITION_TYPE" Value="NORMAL"></Field>
<Field ExtId="POSITION_QUANTITY" Value="asd"></Field>
</Position>
<Position>
</ns2:Positions>
</ns2:ExportPositionsQueryResponse>
</soap:Body>
</soap:Envelope>
After deserialization, xmlSerializer creates an object only with element FieldTypes and the last element of Position. I think XmlSerializer has a problem with the nested Array(PositionField[][] Position) and can't deserialize all Position array elements. Here is part of my C# object class, which I'm using for deserialization:
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://ns")]
public partial class ExportPositionsQueryResponsePositions
{
private FieldTypesFieldType[] fieldTypesField;
private PositionField[][] positionField;
[System.Xml.Serialization.XmlArrayAttribute(Namespace = "http://ns")]
[System.Xml.Serialization.XmlArrayItemAttribute("FieldType", IsNullable = false)]
public FieldTypesFieldType[] FieldTypes
{
get
{
return this.fieldTypesField;
}
set
{
this.fieldTypesField = value;
}
}
[System.Xml.Serialization.XmlArray(ElementName ="Position",Namespace = "http://ns")]
[System.Xml.Serialization.XmlArrayItem("Field", typeof(PositionField[]), IsNullable = false)]
public PositionField[][] Position
{
get
{
return this.positionField;
}
set
{
this.positionField = value;
}
}
}
For creating this class, I've used the "Paste special" function of Visual Studio. But also with the svcutil tool I get same problem.

I've solved the problem. I should edit automatically generated proxy client class. I've replaced all nested arrays [][] with List<T> and serialization works again. here's example:
wrong generated part of code:
private PositionField[][] positionField;
public PositionField[][] Position
{
get
{
return this.positionField;
}
set
{
this.positionField = value;
}
}
edited part of code:
private List<PositionField> positionField;
public List<PositionField> Position
{
get
{
return this.positionField;
}
set
{
this.positionField = value;
}
}

Related

Set grammatical sequence UWP

I recreated a minimal example from GitHub's SpeechRecognitionAndSynthesis from the Scenario_SRGSConstraint.xaml.cs scenario using the grammar I created in an xml file called grammar.
What I would like to solve would be the sequence of words with which to start the action. I recreated the model so that I could choose two colors: red and green for a rectangle background.
Now what I have to say (I will use words in Italian by necessity) to start the action after pressing the button I must pronounce the color first, between red and green and then background to start the action.
I would like to be able to pronounce the background first (then sfondo) and then the color (then rosso o verde), I tried in various ways to modify the grammar.xml several times without success.
I wanted to ask at this point what changes I have to make to start the action by saying the sentence for example: red background or green background ... so as to pronounce the word background (then sfondo) first and then red or green (then rosso o verde) word.
Finally I would like to ask if I need to change only the grammar.xml or even the Code Behind.
MainPage.xaml.cs:
private SpeechRecognizer speechRecognizer;
private IAsyncOperation<SpeechRecognitionResult> recognitionOperation;
private ResourceContext speechContext;
private ResourceMap speechResourceMap;
private Dictionary<string, Color> colorLookup = new Dictionary<string, Color>
{
{ "COLOR_RED", Colors.Red }, {"COLOR_GREEN", Colors.Green}
};
public MainPage()
{
InitializeComponent();
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
bool permissionGained = await AudioCapturePermissions.RequestMicrophonePermission();
if (permissionGained)
{
Language speechLanguage = SpeechRecognizer.SystemSpeechLanguage;
string langTag = speechLanguage.LanguageTag;
speechContext = ResourceContext.GetForCurrentView();
speechContext.Languages = new string[] { langTag };
speechResourceMap = ResourceManager.Current.MainResourceMap.GetSubtree("LocalizationSpeechResources");
await InitializeRecognizer();
}
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
if (speechRecognizer != null)
{
if (speechRecognizer.State != SpeechRecognizerState.Idle)
{
if (recognitionOperation != null)
{
recognitionOperation.Cancel();
recognitionOperation = null;
}
}
speechRecognizer.StateChanged -= SpeechRecognizer_StateChanged;
this.speechRecognizer.Dispose();
this.speechRecognizer = null;
}
}
private async Task InitializeRecognizer()
{
if (speechRecognizer != null)
{
speechRecognizer.StateChanged -= SpeechRecognizer_StateChanged;
this.speechRecognizer.Dispose();
this.speechRecognizer = null;
}
try
{
string languageTag = SpeechRecognizer.SystemSpeechLanguage.LanguageTag;
StorageFile grammarFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///grammar.xml"));
speechRecognizer = new SpeechRecognizer(SpeechRecognizer.SystemSpeechLanguage);
speechRecognizer.StateChanged += SpeechRecognizer_StateChanged;
SpeechRecognitionGrammarFileConstraint grammarConstraint = new SpeechRecognitionGrammarFileConstraint(grammarFile);
speechRecognizer.Constraints.Add(grammarConstraint);
SpeechRecognitionCompilationResult compilationResult = await speechRecognizer.CompileConstraintsAsync();
}
catch (Exception ex) { string message = ex.Message; }
}
private async void SpeechRecognizer_StateChanged(SpeechRecognizer sender, SpeechRecognizerStateChangedEventArgs args)
{
}
private async void RecognizeWithoutUI_Click(object sender, RoutedEventArgs e)
{
try
{
recognitionOperation = speechRecognizer.RecognizeAsync();
SpeechRecognitionResult speechRecognitionResult = await recognitionOperation;
if (speechRecognitionResult.Status == SpeechRecognitionResultStatus.Success)
{
HandleRecognitionResult(speechRecognitionResult);
}
}
catch (TaskCanceledException exception)
{
System.Diagnostics.Debug.WriteLine("TaskCanceledException caught while recognition in progress (can be ignored):");
System.Diagnostics.Debug.WriteLine(exception.ToString());
}
}
/// <summary>
/// Uses the result from the speech recognizer to change the colors of the shapes.
/// </summary>
/// <param name="recoResult">The result from the recognition event</param>
private void HandleRecognitionResult(SpeechRecognitionResult recoResult)
{
// Check the confidence level of the recognition result.
if (recoResult.Confidence == SpeechRecognitionConfidence.High ||
recoResult.Confidence == SpeechRecognitionConfidence.Medium)
{
if (recoResult.SemanticInterpretation.Properties.ContainsKey("KEY_BACKGROUND") && recoResult.SemanticInterpretation.Properties["KEY_BACKGROUND"][0].ToString() != "...")
{
string backgroundColor = recoResult.SemanticInterpretation.Properties["KEY_BACKGROUND"][0].ToString();
colorRectangle.Fill = new SolidColorBrush(getColor(backgroundColor));
}
}
}
/// <summary>
/// Creates a color object from the passed in string.
/// </summary>
/// <param name="colorString">The name of the color</param>
private Color getColor(string colorString)
{
Color newColor = Colors.Transparent;
if (colorLookup.ContainsKey(colorString))
{
newColor = colorLookup[colorString];
}
return newColor;
}
grammar.xml:
<?xml version="1.0" encoding="utf-8" ?>
<grammar xml:lang="it-IT" root="colorChooser"
tag-format="semantics/1.0" version="1.0"
xmlns="http://www.w3.org/2001/06/grammar">
<rule id="background_Color">
<item>
<item>
<ruleref uri="#color"/>
</item>
sfondo
</item>
</rule>
<rule id="colorChooser">
<one-of>
<item>
<item>
<ruleref uri="#background_Color"/>
<tag> out.KEY_BACKGROUND=rules.latest(); </tag>
</item>
</item>
</one-of>
</rule>
<rule id="color">
<one-of>
<item>
rosso <tag> out="COLOR_RED"; </tag>
</item>
<item>
verde <tag> out="COLOR_GREEN"; </tag>
</item>
</one-of>
</rule>
</grammar>
Thanks in advance for the help.
--Update--
With this setting it is wrong ... I also tried to set playCommands with items that have exit tags but it does not run correctly (I update my post to highlight my test with your suggestion) The problem is that " out.KEY_BACKGROUND = rules.latest (); " must be inserted somewhere to start the action because in the code behind it is executed through this key: KEY_BACKGROUND.
Codice grammar.xml provato da me con il tuo suggerimento:
<?xml version="1.0" encoding="utf-8" ?>
<grammar xml:lang="it-IT" root="playCommands"
tag-format="semantics/1.0" version="1.0"
xmlns="http://www.w3.org/2001/06/grammar">
​
<rule id="background_Color">
<item>
sfondo​
</item>​
</rule>​
​
<rule id="playCommands">
<item>
<ruleref uri="#background_Color" />​
</item>
<item>
<ruleref uri="#color" />​
<tag> out.KEY_BACKGROUND=rules.latest(); </tag>
</item>
</rule>​
​
<rule id="color">
<one-of>
<item>
rosso <tag> out="COLOR_RED"; </tag>​
</item>​
<item>
verde <tag> out="COLOR_GREEN"; </tag>​
</item>​
</one-of>​
</rule>
​
</grammar>
--Update1--
I tried your code and I think that the grammar.xml logic is correct, but in the code behind it gives me an error here:
recognitionOperation = speechRecognizer.RecognizeAsync();
In the method RecognizeWithoutUI_Click
And the error is this:
The text associated with this error code could not be found.
Here is the complete project: Test Grammar UWP
If you want to the elements must be listed in the order that the user will speak the command, you can create a top-level rule element that references both the background and color rules to create a flexible collection of commands, And set the command to be the root, like below:
grammar.xml:
<grammar xml:lang="it-IT" root="playCommands"
tag-format="semantics/1.0" version="1.0"
xmlns="http://www.w3.org/2001/06/grammar">
​
<rule id="background_Color">
<item>
sfondo​
</item>​
</rule>​
​
<rule id="playCommands">
<ruleref uri="#background_Color" />​
<ruleref uri="#color" />​
</rule>​
​
<rule id="color">
<one-of>
<item>
rosso <tag> out="COLOR_RED"; </tag>​
</item>​
<item>
verde <tag> out="COLOR_GREEN"; </tag>​
</item>​
</one-of>​
</rule>
​
</grammar>
Update:
If you want to use "out.KEY_BACKGROUND = rules.latest();" You just need to change the position of the sfondo and <ruleref uri="#color"/>. In this case, it will execute the backgroundColor first and then the color.
<?xml version="1.0" encoding="utf-8" ?>
<grammar xml:lang="it-IT" root="colorChooser"
tag-format="semantics/1.0" version="1.0"
xmlns="http://www.w3.org/2001/06/grammar">
<rule id="background_Color">
<item>
sfondo
<item>
<ruleref uri="#color"/>
</item>
</item>
</rule>
<rule id="colorChooser">
<item>
<ruleref uri="#background_Color"/>
<tag> out.KEY_BACKGROUND=rules.latest(); </tag>
</item>
</rule>
<rule id="color">
<one-of>
<item>
rosso <tag> out="COLOR_RED"; </tag>
</item>
<item>
verde <tag> out="COLOR_GREEN"; </tag>
</item>
</one-of>
</rule>
</grammar>

how to class wrap a list in c# for xml serializing

How can one class wrap a list in c# for xml serializing?
I would like to add a root. maybe a class wrapper is not a good idea. And should I use a different aprouch?
When I serialize the following class:
public class Parts
{
//main class
[XmlElement("Access")]
public List<Access> AccessDB = new List<Access>
{
new Access
{
Items = new[] {
new Component { Name = "dbName" }
,new Component { Name = "DbElement" } }
, Scope = "GlobalVariable", UId = "21"
},
new Access
{
Items = new[] {
new Component { Name = "TagName" } }
, Scope = "GlobalVariable", UId = "22"
}
};
}
I get:
<Parts>
<Access Scope="Scope" UId="21">
<Symbol>
<Component Name="Name" />
<Component Name="Name" />
</Symbol>
</Access>
<Access Scope="Scope" UId="22">
<Symbol>
<Component Name="Name" />
</Symbol>
</Access>
<Part Name="PartName" UId="23" />
</Parts>
but what I need is:
<myroot>
<Parts>
<Access Scope="Scope" UId="21">
<Symbol>
<Component Name="Name" />
<Component Name="Name" />
</Symbol>
</Access>
<Access Scope="Scope" UId="22">
<Symbol>
<Component Name="Name" />
</Symbol>
</Access>
<Part Name="PartName" UId="23" />
</Parts>
</myroot>
any advice is very welcome!
If the myroot element is only required to be present in the xml output, you can add it during the serialization.
Use an XmlWriter as output target for the serialization.
Before serializing the Parts instance, you use the XmlWriter to create the myroot element.
XmlWriterSettings settings = new XmlWriterSettings { Indent = true };
StringBuilder stringBuilder = new StringBuilder();
using (var xmlWriter = XmlWriter.Create(stringBuilder, settings))
{
xmlWriter.WriteStartElement("myroot"); // Writes <myroot>
var serializer = new XmlSerializer(typeof(Parts));
var parts = new Parts();
serializer.Serialize(xmlWriter, parts);
xmlWriter.WriteEndElement(); // Writes </myroot>
}
I found that it is also possible to class wrap the other classes, but the instance of the class must be public. In code:
public class myRoot
{
public Parts Parts = new Parts();
}
and then serialize the class myRoot

C# convert JSON object to XML dynamically

I'm attempting to convert JSON sent from a web browser client to the server so I can send the data as parameters in the form of XML to an SQL database. I'm struggling to do this as I have objects inside of objects and I'm not sure how to convert them dynamically into a structured XML format. Below are examples of the JSON I am using, the possible XML formats I'm trying to turn it into (or anything close to them), and the code that I am using.
JSON:
[
{"value":50,"name":"desired_gross_margin","type":"int"},
{"value":50,"name":"desired_adjusted_gross_margin","type":"int"},
{"value":0,"name":"target_electricity_tariff_unit_charge","type":"decimal"},
{"value":0,"name":"target_electricity_tariff_standing_charge","type":"decimal"},
{"value":0,"name":"target_gas_tariff_unit_charge","type":"decimal"},
{"value":0,"name":"target_gas_tariff_standing_charge","type":"decimal"},
{"value":"10/10/2016","name":"planned_go_live_date","type":"DateTime"},
{"value":"0","name":"assumed_fuel_ratio","type":"int"},
{"value":{
"year_one":"Cold",
"year_two":"Average",
"year_three":"Warm"
},
"name":"weather_variable","type":"string"}
]
Possible XML outputs:
1:
<Filters>
<CustomerParameters>
<CustomParameter name="desired_gross_margin" type="int" value="50"/>
<CustomParameter name="desired_adjusted_gross_margin" type="int" value="50"/>
<CustomParameter name="target_electricity_tariff_unit_charge" type="decimal" value="0"/>
<CustomParameter name="target_electricity_tariff_standing_charge" type="decimal" value="0"/>
<CustomParameter name="target_gas_tariff_unit_charge" type="decimal" value="0"/>
<CustomParameter name="target_gas_tariff_standing_charge" type="decimal" value="0"/>
<CustomParameter name="planned_go_live_date" type="DateTime" value="10/10/2016"/>
<CustomParameter name="assumed_fuel_ratio" type="int" value="0"/>
<CustomParamaters name="weather_variables">
<CustomParameter name="year_one" type="string" value="Cold"/>
<CustomParameter name="year_two" type="string" value="Average"/>
<CustomParameter name="year_three" type="string" value="Cold"/>
</CustomParameters>
</CustomParameters>
</Filters>
2:
<?xml version="1.0" encoding="UTF-8" ?>
<0>
<value>50</value>
<name>desired_gross_margin</name>
<type>int</type>
</0>
<1>
<value>50</value>
<name>desired_adjusted_gross_margin</name>
<type>int</type>
</1>
<2>
<value>0</value>
<name>target_electricity_tariff_unit_charge</name>
<type>decimal</type>
</2>
<3>
<value>0</value>
<name>target_electricity_tariff_standing_charge</name>
<type>decimal</type>
</3>
<4>
<value>0</value>
<name>target_gas_tariff_unit_charge</name>
<type>decimal</type>
</4>
<5>
<value>0</value>
<name>target_gas_tariff_standing_charge</name>
<type>decimal</type>
</5>
<6>
<value>10/10/2016</value>
<name>planned_go_live_date</name>
<type>DateTime</type>
</6>
<7>
<value>0</value>
<name>assumed_fuel_ratio</name>
<type>int</type>
</7>
<8>
<value>
<year_one>Cold</year_one>
<year_two>Average</year_two>
<year_three>Warm</year_three>
</value>
<name>weather_variable</name>
<type>string</type>
</8>
</xml>
C# code:
ForecastController.cs:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using System.Web.Script.Serialization;
using System.Xml;
namespace ForecastServices.Controllers
{
public class ForecastController : ApiController
{
[HttpPost]
public List<Data> GetData(HttpRequestMessage request)
{
string connection_string = ConfigurationManager.ConnectionStrings["Database"].ConnectionString;
string sql = "DataHub.get_GrossMarginModel";
string json = request.Content.ReadAsStringAsync().Result;
//var filters2 = new JavaScriptSerializer().Deserialize<dynamic>(json); //this works but I can't turn it into XML! :(
List<Filter> filters = new JavaScriptSerializer().Deserialize<List<Filter>>(json);
string xml = Filter.getFilterListXML(filters);
List<Data> data = new List<Data>();
using(SqlConnection connection = new SqlConnection(connection_string))
{
connection.Open();
SqlCommand cmd = connection.CreateCommand();
cmd.CommandText = sql;
cmd.Parameters.Add(new SqlParameter("filter_xml", ""));
cmd.CommandType = CommandType.StoredProcedure;
var adapter = new SqlDataAdapter(cmd);
var set = new DataSet();
cmd.ExecuteNonQuery();
adapter.Fill(set);
if (set.Tables.Count > 0)
{
foreach (DataRow tableRow in set.Tables[0].Rows)
{
data.Add(new Data()
{
name = tableRow.ItemArray[0].ToString(),
year_one = (int)tableRow.ItemArray[1],
year_two = (int)tableRow.ItemArray[2],
year_three = (int)tableRow.ItemArray[3],
});
}
}
connection.Close();
}
return data;
}
}
}
Filter.cs:
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace ForecastServices.Domain
{
public class Filter
{
public string value { get; set; }
public string name { get; set; }
public string type { get; set; }
public string getXML()
{
return string.Format("<CustomParameter name=\"{0}\" type=\"{1}\" value=\"{2}\"/>", name, type, value);
}
public static string getFilterListXML(ICollection<Filter> filters)
{
StringBuilder XMLString = new StringBuilder();
XMLString.Append("<Filters><CustomerParameters>");
foreach (Filter f in filters)
{
XMLString.Append(f.getXML());
}
XMLString.Append("</CustomParameters></Filters>");
return XMLString.ToString();
}
}
}
Not building on your current code, you can take a look at this question
Using this one-liner:
XmlDocument doc = JsonConvert.DeserializeXmlNode("{\"Row\":" + json + "}", "root"); // JSON needs to be an object
You can end up with:
<root>
<Row>
<value>50</value>
<name>desired_gross_margin</name>
<type>int</type>
</Row>
<Row>
<value>50</value>
<name>desired_adjusted_gross_margin</name>
<type>int</type>
</Row>
<Row>
<value>0</value>
<name>target_electricity_tariff_unit_charge</name>
<type>decimal</type>
</Row>
<Row>
<value>0</value>
<name>target_electricity_tariff_standing_charge</name>
<type>decimal</type>
</Row>
<Row>
<value>0</value>
<name>target_gas_tariff_unit_charge</name>
<type>decimal</type>
</Row>
<Row>
<value>0</value>
<name>target_gas_tariff_standing_charge</name>
<type>decimal</type>
</Row>
<Row>
<value>10/10/2016</value>
<name>planned_go_live_date</name>
<type>DateTime</type>
</Row>
<Row>
<value>0</value>
<name>assumed_fuel_ratio</name>
<type>int</type>
</Row>
<Row>
<value>
<year_one>Cold</year_one>
<year_two>Average</year_two>
<year_three>Warm</year_three>
</value>
<name>weather_variable</name>
<type>string</type>
</Row>
</root>
Where json is the input JSON on your question, it's close to what you want (which your post says is sort of okay), but if you want to go for your 1st and 2nd options, you can simply build new XML by manipulating this (renaming the nodes, etc.).

How can I iterate on XML elements from an XML using XMLReader and bypass whitespaces?

Let say you have an XML like this:
<?xml version="1.0" encoding="utf-8"?>
<Class HashCode="307960707">
<Person>
<Class HashCode="-2020100801">
<FullName>
<FirstName>Dan</FirstName>
<LastName>K</LastName>
</FullName>
</Class>
<Age>20</Age>
<Class HashCode="-439631396">
<Address>
<Street>abc</Street>
<City>new york</City>
<ZipCode>30500</ZipCode>
<PhoneNumber>1245</PhoneNumber>
</Address>
</Class>
<Class HashCode="-1436395737">
<Person>
<Class HashCode="-1303968324">
<FullName>
<FirstName>katty</FirstName>
<LastName>G</LastName>
</FullName>
</Class>
<Age>18</Age>
<Class HashCode="-439631396">
<Address />
</Class>
<Class HashCode="307960707">
<Person />
</Class>
</Person>
</Class>
I want to be able to iterate only elements with XMLReader in the order they appear, which means class->Person-> class->FullName ,etc..
I was trying to navigate with methods like XMLReader.ReadStartElement() and it didn't work especially when I read a whitespaces like "\n" which appears to be an element also. :/
I was trying to bypass that whitespace with method XMLReader.Read() with no success.
Please help me understand how should I navigate that way.
XmlReader constructor has an overload that takes an XmlReaderSettings object. The XmlReaderSettings object has an IgnoreWhitespace property.
In order to read only the next elements you can implement an extension method on XmlReader.
Here's an example:
public static class ExtensionMethods
{
public static bool ReadNextElement(this XmlReader reader)
{
while (reader.Read())
if (reader.NodeType == XmlNodeType.Element)
return true;
return false;
}
}
And here's a little console application that will demonstrate this:
public class Program
{
public static void Main(string[] args)
{
var settings = new XmlReaderSettings();
settings.IgnoreWhitespace = true;
settings.IgnoreComments = true;
settings.IgnoreProcessingInstructions = true;
var reader = XmlReader.Create("XMLFile1.xml", settings);
while (reader.ReadNextElement())
Console.WriteLine(reader.Name);
}
}

Custom Field does not save

I've created a list (sharepoint 2010) that contains a cumstom field. The custom field inherits from SPFieldUser.
After I created a new ListItem (webfrontend) and have a look on the elements details the field is empty.
Webfronted NewItemForm
Webfronted ItemDetailsForm
Webfronted EditItemForm
My Code:
public class Vertreter_FieldType:SPFieldUser
{
public Vertreter_FieldType(SPFieldCollection fields, string fieldName)
: base(fields, fieldName)
{
}
public Vertreter_FieldType(SPFieldCollection fields, string typeName, string fieldName)
: base(fields, typeName, fieldName)
{
}
public override object GetFieldValue(string value)
{
return base.GetFieldValue(value);
}
public override string DefaultValue
{
get
{
return base.DefaultValue;
}
set
{
base.DefaultValue = value;
}
}
}
XML-fldtypes:
<FieldTypes>
<FieldType>
<Field Name="TypeName">Vertreter_FieldType</Field>
<Field Name="ParentType">User</Field>
<Field Name="TypeDisplayName">Vertreter</Field>
<Field Name="TypeShortDescription">Auswahl Vertreter</Field>
<Field Name="UserCreatable">TRUE</Field>
<Field Name="FieldTypeClass">CustomFieldTypes.Vertreter_FieldType, $SharePoint.Project.AssemblyFullName$</Field>
</FieldType>
</FieldTypes>
My Contenttype the List bases on:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
...
<Field ID="{2C338272-3BC8-45bc-B33E-5FBD1223F398}"
DisplayName="Administrator" Name="Administrator"
Type="Admin_FieldType" Required="TRUE"
UnlimitedLengthInDocumentLibrary="FALSE"
/>
<Field ID="{585CE72A-72D7-4ecc-8324-484BA1E483F1}"
DisplayName="Vertreter" Name="Vertreter"
Type="Vertreter_FieldType" Required="TRUE"
UnlimitedLengthInDocumentLibrary="FALSE"
>
</Field>
...
<FieldRefs>
...
<FieldRef ID="{2C338272-3BC8-45bc-B33E-5FBD1223F398}" Name="Administrator" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE" />
<FieldRef ID="{585CE72A-72D7-4ecc-8324-484BA1E483F1}" Name="Vertreter" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE" />
...
</FieldRefs>
</ContentType>
</Elements>
My environment: sharepoint 2010, visualstudio 2010
Thanks for your help!
Found the solution: I had to add List="UserInfo" to the FieldDefinition.
<Field ID="{585CE72A-72D7-4ecc-8324-484BA1E483F1}" DisplayName="Vertreter" Name="Vertreter" Type="Vertreter_FieldType" Required="TRUE" UnlimitedLengthInDocumentLibrary="FALSE" List="UserInfo">

Categories

Resources