How to call web Services in C# - c#
I am calling web services and returning into list but I am not able to do same.
I want to bind drop down list with web services.
I have added INITIATORS_LIST class which contain all field which I want to bind in Drop down list like Companies, Countries, Divisions, Location... So on. How can I achieve any alternate method may I accept please ?
Sample JSON Data
{"Companies":[{"ACTIVE":true,"COMPANY_ID":1,"CompanyCode":"1000","CompanyName":"Almarai Company","CountryCode":"SAU","CountryName":"Saudi Arabia","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"},{"ACTIVE":true,"COMPANY_ID":6,"CompanyCode":"4000","CompanyName":"Almarai Co. Bahrain WLL","CountryCode":"BAH","CountryName":"Bahrain","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"},{"ACTIVE":true,"COMPANY_ID":8,"CompanyCode":"5000","CompanyName":"Bustan Al Khaleej Est.","CountryCode":"UAE","CountryName":"United Arab Emirates","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"},{"ACTIVE":true,"COMPANY_ID":11,"CompanyCode":"5200","CompanyName":"ALMARAI EMIRATES COMPANY L.L.C","CountryCode":"UAE","CountryName":"United Arab Emirates","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"},{"ACTIVE":true,"COMPANY_ID":15,"CompanyCode":"6000","CompanyName":"Al Kharafi Brothers","CountryCode":"KWT","CountryName":"Kuwait","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"},{"ACTIVE":true,"COMPANY_ID":18,"CompanyCode":"7000","CompanyName":"Arabian Planets Company","CountryCode":"OMN","CountryName":"Oman","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"}],"Countries":[{"COUNTRY_ACTIVE":true,"COUNTRY_M_ID":1,"CountryCode":"SAU","CountryName":"Saudi Arabia","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"},{"COUNTRY_ACTIVE":true,"COUNTRY_M_ID":3,"CountryCode":"UAE","CountryName":"United Arab Emirates","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"},{"COUNTRY_ACTIVE":true,"COUNTRY_M_ID":4,"CountryCode":"BAH","CountryName":"Bahrain","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"},{"COUNTRY_ACTIVE":true,"COUNTRY_M_ID":5,"CountryCode":"OMN","CountryName":"Oman","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"},{"COUNTRY_ACTIVE":true,"COUNTRY_M_ID":7,"CountryCode":"KWT","CountryName":"Kuwait","DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales"}],"Divisions":[{"ACTIVE":true,"CompanyCode":null,"CompanyName":null,"CountryCode":null,"CountryName":null,"DB_CONNECTION_STRING":null,"DivisionCode":"1000","DivisionId":1,"DivisionName":"Sales","WEB_URL":null}],"Locations":
ALM_COUNTRY_M class:
public partial class ALM_COUNTRY_M : object, System.Runtime.Serialization.IExtensibleDataObject,
System.ComponentModel.INotifyPropertyChanged {
[System.NonSerializedAttribute()]
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private bool COUNTRY_ACTIVEField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private int COUNTRY_M_IDField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string CountryCodeField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string CountryNameField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string DivisionCodeField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private int DivisionIdField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string DivisionNameField;
[global::System.ComponentModel.BrowsableAttribute(false)]
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public bool COUNTRY_ACTIVE {
get {
return this.COUNTRY_ACTIVEField;
}
set {
if ((this.COUNTRY_ACTIVEField.Equals(value) != true)) {
this.COUNTRY_ACTIVEField = value;
this.RaisePropertyChanged("COUNTRY_ACTIVE");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public int COUNTRY_M_ID {
get {
return this.COUNTRY_M_IDField;
}
set {
if ((this.COUNTRY_M_IDField.Equals(value) != true)) {
this.COUNTRY_M_IDField = value;
this.RaisePropertyChanged("COUNTRY_M_ID");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string CountryCode {
get {
return this.CountryCodeField;
}
set {
if ((object.ReferenceEquals(this.CountryCodeField, value) != true)) {
this.CountryCodeField = value;
this.RaisePropertyChanged("CountryCode");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string CountryName {
get {
return this.CountryNameField;
}
set {
if ((object.ReferenceEquals(this.CountryNameField, value) != true)) {
this.CountryNameField = value;
this.RaisePropertyChanged("CountryName");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string DivisionCode {
get {
return this.DivisionCodeField;
}
set {
if ((object.ReferenceEquals(this.DivisionCodeField, value) != true)) {
this.DivisionCodeField = value;
this.RaisePropertyChanged("DivisionCode");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public int DivisionId {
get {
return this.DivisionIdField;
}
set {
if ((this.DivisionIdField.Equals(value) != true)) {
this.DivisionIdField = value;
this.RaisePropertyChanged("DivisionId");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string DivisionName {
get {
return this.DivisionNameField;
}
set {
if ((object.ReferenceEquals(this.DivisionNameField, value) != true)) {
this.DivisionNameField = value;
this.RaisePropertyChanged("DivisionName");
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
INITIATORS_LIST Class:
public partial class INITIATORS_LIST : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
[System.NonSerializedAttribute()]
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private Almarai.GiveAway.GetInitiatorList.ALM_COMPANY_M[] CompaniesField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private Almarai.GiveAway.GetInitiatorList.ALM_COUNTRY_M[] CountriesField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private Almarai.GiveAway.GetInitiatorList.ALM_DIVISION_M[] DivisionsField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private Almarai.GiveAway.GetInitiatorList.LOCATION[] LocationsField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private Almarai.GiveAway.GetInitiatorList.REGION[] RegionsField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private Almarai.GiveAway.GetInitiatorList.ALM_WKFLW_TYPE_M[] WorkflowTypesField;
[global::System.ComponentModel.BrowsableAttribute(false)]
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public Almarai.GiveAway.GetInitiatorList.ALM_COMPANY_M[] Companies {
get {
return this.CompaniesField;
}
set {
if ((object.ReferenceEquals(this.CompaniesField, value) != true)) {
this.CompaniesField = value;
this.RaisePropertyChanged("Companies");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public Almarai.GiveAway.GetInitiatorList.ALM_COUNTRY_M[] Countries {
get {
return this.CountriesField;
}
set {
if ((object.ReferenceEquals(this.CountriesField, value) != true)) {
this.CountriesField = value;
this.RaisePropertyChanged("Countries");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public Almarai.GiveAway.GetInitiatorList.ALM_DIVISION_M[] Divisions {
get {
return this.DivisionsField;
}
set {
if ((object.ReferenceEquals(this.DivisionsField, value) != true)) {
this.DivisionsField = value;
this.RaisePropertyChanged("Divisions");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public Almarai.GiveAway.GetInitiatorList.LOCATION[] Locations {
get {
return this.LocationsField;
}
set {
if ((object.ReferenceEquals(this.LocationsField, value) != true)) {
this.LocationsField = value;
this.RaisePropertyChanged("Locations");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public Almarai.GiveAway.GetInitiatorList.REGION[] Regions {
get {
return this.RegionsField;
}
set {
if ((object.ReferenceEquals(this.RegionsField, value) != true)) {
this.RegionsField = value;
this.RaisePropertyChanged("Regions");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public Almarai.GiveAway.GetInitiatorList.ALM_WKFLW_TYPE_M[] WorkflowTypes {
get {
return this.WorkflowTypesField;
}
set {
if ((object.ReferenceEquals(this.WorkflowTypesField, value) != true)) {
this.WorkflowTypesField = value;
this.RaisePropertyChanged("WorkflowTypes");
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
Reference:
public Almarai.GiveAway.GetInitiatorList.INITIATORS_LIST GetInitiatorsListByWorkflow(string userId, string WorkflowTypeCode) {
return base.Channel.GetInitiatorsListByWorkflow(userId, WorkflowTypeCode);
}
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IMasterDataService/GetInitiatorsListByWorkflow", ReplyAction="http://tempuri.org/IMasterDataService/GetInitiatorsListByWorkflowResponse")]
[System.ServiceModel.FaultContractAttribute(typeof(Almarai.GiveAway.GetInitiatorList.CustomFaultException), Action="http://tempuri.org/IMasterDataService/GetInitiatorsListByWorkflowCustomFaultExcep" +
"tionFault", Name="CustomFaultException", Namespace="http://schemas.datacontract.org/2004/07/Almarai.Web.Services.MasterData")]
Almarai.GiveAway.GetInitiatorList.INITIATORS_LIST GetInitiatorsListByWorkflow(string userId, string WorkflowTypeCode);
Country class: (Should I change this class for Each different field like Company, Country, Region....so on)
public class CountryList
{
public CountryList(INITIATORS_LIST data)
{
ExtensionData = data;
}
public INITIATORS_LIST ExtensionData { get; internal set; }
}
My Method: (How should I modify my method)
[WebMethod]
public static List<CountryList> GetCountriesName(string UserID)
{
GetInitiatorList.MasterDataServiceClient oClient = new GetInitiatorList.MasterDataServiceClient();
string userid = "approver01";
string work = "4";
List<CountryList> countries = oClient.GetInitiatorsListByWorkflow(userid, work); // Error on this line
foreach (Country c in countries)
{
lst.Add(c.Name);
}
return lst; //Error on this line
}
I am not able to Add into list is there other approch ?
I know due to return type am not able to do but
The GetInitiatorsListByWorkflow method returns a Almarai.GiveAway.GetInitiatorList.INITIATORS_LIST object, not a List<CountryList>. Likewise your GetCountriesName method returns List<CountryList>, not whatever the type of your (undefined in the code shown) lst variable is. That's why you have errors - you can't just randomly assign objects to variables which are the wrong type.
Anyway it seems that for your countries list you actually want to use two properties from the ALM_COUNTRY_M class. The INITIATORS_LIST contains an array of objects of that type.
So what you really need to do is get the array of ALM_COUNTRY_M objects from the INITIATORS_LIST returned by the GetInitiatorsListByWorkflow method, and loop through them, and for each one, create an equivalent instance of CountryList, set its properties using the values in the ALM_COUNTRY_M object, and add that to the list to be returned.
Something like this (untested):
[WebMethod]
public static List<CountryList> GetCountriesName(string UserID)
{
GetInitiatorList.MasterDataServiceClient oClient = new GetInitiatorList.MasterDataServiceClient();
string userid = "approver01";
string work = "4";
Almarai.GiveAway.GetInitiatorList.INITIATORS_LIST initiatorsList = oClient.GetInitiatorsListByWorkflow(userid, work); //get data from webservice
Almarai.GiveAway.GetInitiatorList.ALM_COUNTRY_M[] countryMList = initiatorsList.Countries; //get list of countries from the data returned by the webservice
List<CountryList> countries = new List<CountryList>(); //create an empty list which will be populated with data from the webservice
//loop through list of countries returned from webservice
foreach (Almarai.GiveAway.GetInitiatorList.ALM_COUNTRY_M country in countryMList)
{
//add new instance of CountryList using fields from the webservice class
countries.Add(new CountryList() {
CountryCode = country.CountryCode,
CountryName = country.CountryName
});
}
return countries; //return the completed list of countries
}
The CountryList class should be defined more like this:
public class CountryList
{
public string CountryCode { get; set; }
public string CountryName { get; set; }
}
P.S. It would be more meaningful to rename the CountryList class to Country, since each object only represents a single country. It's the List<> part which defines a list. But that's a separate issue for you to decide.
Related
How to store IExtensibleDataObject into list in C#
I want to call web services and store in List but not able to add i know the return type is not matching for both. May i know how to consume web service and store in List. I have class which inherit with object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged Should I use LINQ. Signature of GetInitiatorsListByWorkflow: public Almarai.GiveAway.GetInitiatorList.INITIATORS_LIST GetInitiatorsListByWorkflow(string userId, string WorkflowTypeCode) { return base.Channel.GetInitiatorsListByWorkflow(userId, WorkflowTypeCode); } Refrence: [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IMasterDataService/GetInitiatorsListByWorkflow", ReplyAction="http://tempuri.org/IMasterDataService/GetInitiatorsListByWorkflowResponse")] [System.ServiceModel.FaultContractAttribute(typeof(Almarai.GiveAway.GetInitiatorList.CustomFaultException), Action="http://tempuri.org/IMasterDataService/GetInitiatorsListByWorkflowCustomFaultExcep" + "tionFault", Name="CustomFaultException", Namespace="http://schemas.datacontract.org/2004/07/Almarai.Web.Services.MasterData")] Almarai.GiveAway.GetInitiatorList.INITIATORS_LIST GetInitiatorsListByWorkflow(string userId, string WorkflowTypeCode); My class : public partial class INITIATORS_LIST : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged { [System.NonSerializedAttribute()] private System.Runtime.Serialization.ExtensionDataObject extensionDataField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Almarai.GiveAway.GetInitiatorList.ALM_COMPANY_M[] CompaniesField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Almarai.GiveAway.GetInitiatorList.ALM_COUNTRY_M[] CountriesField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Almarai.GiveAway.GetInitiatorList.ALM_DIVISION_M[] DivisionsField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Almarai.GiveAway.GetInitiatorList.LOCATION[] LocationsField; [global::System.ComponentModel.BrowsableAttribute(false)] public System.Runtime.Serialization.ExtensionDataObject ExtensionData { get { return this.extensionDataField; } set { this.extensionDataField = value; } } [System.Runtime.Serialization.DataMemberAttribute()] public Almarai.GiveAway.GetInitiatorList.ALM_COMPANY_M[] Companies { get { return this.CompaniesField; } set { if ((object.ReferenceEquals(this.CompaniesField, value) != true)) { this.CompaniesField = value; this.RaisePropertyChanged("Companies"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Almarai.GiveAway.GetInitiatorList.ALM_COUNTRY_M[] Countries { get { return this.CountriesField; } set { if ((object.ReferenceEquals(this.CountriesField, value) != true)) { this.CountriesField = value; this.RaisePropertyChanged("Countries"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Almarai.GiveAway.GetInitiatorList.ALM_DIVISION_M[] Divisions { get { return this.DivisionsField; } set { if ((object.ReferenceEquals(this.DivisionsField, value) != true)) { this.DivisionsField = value; this.RaisePropertyChanged("Divisions"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Almarai.GiveAway.GetInitiatorList.LOCATION[] Locations { get { return this.LocationsField; } set { if ((object.ReferenceEquals(this.LocationsField, value) != true)) { this.LocationsField = value; this.RaisePropertyChanged("Locations"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Almarai.GiveAway.GetInitiatorList.REGION[] Regions { get { return this.RegionsField; } set { if ((object.ReferenceEquals(this.RegionsField, value) != true)) { this.RegionsField = value; this.RaisePropertyChanged("Regions"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Almarai.GiveAway.GetInitiatorList.ALM_WKFLW_TYPE_M[] WorkflowTypes { get { return this.WorkflowTypesField; } set { if ((object.ReferenceEquals(this.WorkflowTypesField, value) != true)) { this.WorkflowTypesField = value; this.RaisePropertyChanged("WorkflowTypes"); } } } public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; if ((propertyChanged != null)) { propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } } My method: [WebMethod] public static List<INITIATORS_LIST> GetCountriesName(string UserID) { GetInitiatorList.MasterDataServiceClient oClient = new GetInitiatorList.MasterDataServiceClient(); List<INITIATORS_LIST> lst = new List<INITIATORS_LIST>(); var INITIATORS_LIST = new INITIATORS_LIST() { ExtensionData = oClient.GetInitiatorsListByWorkflow("SAU", "SaudiArebia")//Error on this Line }; return lst; }
System.NullReferenceException when using WSDL in C# SOAP Request
Another Similar But cant figure out Problem Tried the answer which worked for previous question in this same post, Which was for Arrays. Over here it is lookups and iv tried the below but its still not working. Iv also tried createCustomerRequest.CustomerDetails.Title[0].Code[0] = cloneTitleCode[0]; All the [0] iv switched them around and took them off too and tried all the combinations still doesnt work. //Security settings to match server using this line: - Dsoapui.https.protocols=SSLv3,TLSv1.2 ... BasicHttpsBinding httpsBinding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport); //Using the security settings to create the client which will let us send/recieve the requests... CustomerServiceClient soapClient = new CustomerServiceClient("BasicHttpsBinding_ICustomerService"); //Set credentials for the client... soapClient.ClientCredentials.UserName.UserName = username; soapClient.ClientCredentials.UserName.Password = password; //Create instances of requesting and recieving data from the server for customerDetails... CreateCustomer createCustomer = new CreateCustomer(); CreateCustomerRequest createCustomerRequest = new CreateCustomerRequest(); CreateCustomerResponse createCustomerResponse = new CreateCustomerResponse(); //Set customer details request (so whatever will be included in the request to recieve the info)... createCustomerRequest.UserName = username; createCustomerRequest.Password = password; createCustomerRequest.SystemToken = "2fa192c3-1215-41f9-be71-2ba6e279494e"; //Get current time to generate unique customer number... string currentTime = DateTime.Now.ToLongTimeString(); string cleanTime = Regex.Replace(currentTime, "[^A-Za-z0-9 ]", ""); //For WSDL arrays create the array and instance then use it like below... createCustomerRequest.CustomerDetails.Title = new CustomerServiceWSDL.LookupItem(); createCustomerRequest.CustomerDetails = new CreateCustomer(); createCustomerRequest.CustomerDetails.CustomerNumber = "001" + cleanTime; createCustomerRequest.CustomerDetails.FirstName = cloneFirstName; createCustomerRequest.CustomerDetails.Surname = cloneSurName; createCustomerRequest.CustomerDetails.Title.Code = cloneTitleCode; WSDL Reference for everything im playing with in this code: [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] [System.Runtime.Serialization.DataContractAttribute(Name="CreateCustomer", Namespace= + WEBAPI)] [System.SerializableAttribute()] public partial class CreateCustomer : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged { [System.NonSerializedAttribute()] private System.Runtime.Serialization.ExtensionDataObject extensionDataField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.LookupItem BranchField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.LookupItem BusinessSourceField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.ContactInformation ContactDetailsField; [System.Runtime.Serialization.OptionalFieldAttribute()] private string CreatedByField; [System.Runtime.Serialization.OptionalFieldAttribute()] private System.Nullable<System.DateTime> CreationDateField; [System.Runtime.Serialization.OptionalFieldAttribute()] private System.Nullable<decimal> CreditLimitField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.Residence CurrentAddressField; [System.Runtime.Serialization.OptionalFieldAttribute()] private string CustomerNumberField; [System.Runtime.Serialization.OptionalFieldAttribute()] private System.DateTime DateOfBirthField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.LookupItem EmploymentStatusField; [System.Runtime.Serialization.OptionalFieldAttribute()] private string FirstNameField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.Gender GenderField; [System.Runtime.Serialization.OptionalFieldAttribute()] private string IdNumberField; [System.Runtime.Serialization.OptionalFieldAttribute()] private string InitialsField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.LookupItem MaritalStatusField; [System.Runtime.Serialization.OptionalFieldAttribute()] private string NationalInsuranceNumberField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.LookupItem NationalityField; [System.Runtime.Serialization.OptionalFieldAttribute()] private bool NoMailMarketingField; [System.Runtime.Serialization.OptionalFieldAttribute()] private System.Nullable<int> NoOfChildrenField; [System.Runtime.Serialization.OptionalFieldAttribute()] private bool NoThirdPartyMarketingField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.LookupItem OccupationField; [System.Runtime.Serialization.OptionalFieldAttribute()] private string PreviousNameField; [System.Runtime.Serialization.OptionalFieldAttribute()] private System.Nullable<System.DateTime> ReviewDateField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.LookupItem StatusField; [System.Runtime.Serialization.OptionalFieldAttribute()] private string SurnameField; [System.Runtime.Serialization.OptionalFieldAttribute()] private Account_Status.CustomerServiceWSDL.LookupItem TitleField; [global::System.ComponentModel.BrowsableAttribute(false)] public System.Runtime.Serialization.ExtensionDataObject ExtensionData { get { return this.extensionDataField; } set { this.extensionDataField = value; } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.LookupItem Branch { get { return this.BranchField; } set { if ((object.ReferenceEquals(this.BranchField, value) != true)) { this.BranchField = value; this.RaisePropertyChanged("Branch"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.LookupItem BusinessSource { get { return this.BusinessSourceField; } set { if ((object.ReferenceEquals(this.BusinessSourceField, value) != true)) { this.BusinessSourceField = value; this.RaisePropertyChanged("BusinessSource"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.ContactInformation ContactDetails { get { return this.ContactDetailsField; } set { if ((object.ReferenceEquals(this.ContactDetailsField, value) != true)) { this.ContactDetailsField = value; this.RaisePropertyChanged("ContactDetails"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public string CreatedBy { get { return this.CreatedByField; } set { if ((object.ReferenceEquals(this.CreatedByField, value) != true)) { this.CreatedByField = value; this.RaisePropertyChanged("CreatedBy"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public System.Nullable<System.DateTime> CreationDate { get { return this.CreationDateField; } set { if ((this.CreationDateField.Equals(value) != true)) { this.CreationDateField = value; this.RaisePropertyChanged("CreationDate"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public System.Nullable<decimal> CreditLimit { get { return this.CreditLimitField; } set { if ((this.CreditLimitField.Equals(value) != true)) { this.CreditLimitField = value; this.RaisePropertyChanged("CreditLimit"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.Residence CurrentAddress { get { return this.CurrentAddressField; } set { if ((object.ReferenceEquals(this.CurrentAddressField, value) != true)) { this.CurrentAddressField = value; this.RaisePropertyChanged("CurrentAddress"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public string CustomerNumber { get { return this.CustomerNumberField; } set { if ((object.ReferenceEquals(this.CustomerNumberField, value) != true)) { this.CustomerNumberField = value; this.RaisePropertyChanged("CustomerNumber"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public System.DateTime DateOfBirth { get { return this.DateOfBirthField; } set { if ((this.DateOfBirthField.Equals(value) != true)) { this.DateOfBirthField = value; this.RaisePropertyChanged("DateOfBirth"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.LookupItem EmploymentStatus { get { return this.EmploymentStatusField; } set { if ((object.ReferenceEquals(this.EmploymentStatusField, value) != true)) { this.EmploymentStatusField = value; this.RaisePropertyChanged("EmploymentStatus"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public string FirstName { get { return this.FirstNameField; } set { if ((object.ReferenceEquals(this.FirstNameField, value) != true)) { this.FirstNameField = value; this.RaisePropertyChanged("FirstName"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public string Surname { get { return this.SurnameField; } set { if ((object.ReferenceEquals(this.SurnameField, value) != true)) { this.SurnameField = value; this.RaisePropertyChanged("Surname"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.Gender Gender { get { return this.GenderField; } set { if ((this.GenderField.Equals(value) != true)) { this.GenderField = value; this.RaisePropertyChanged("Gender"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public string IdNumber { get { return this.IdNumberField; } set { if ((object.ReferenceEquals(this.IdNumberField, value) != true)) { this.IdNumberField = value; this.RaisePropertyChanged("IdNumber"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public string Initials { get { return this.InitialsField; } set { if ((object.ReferenceEquals(this.InitialsField, value) != true)) { this.InitialsField = value; this.RaisePropertyChanged("Initials"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.LookupItem MaritalStatus { get { return this.MaritalStatusField; } set { if ((object.ReferenceEquals(this.MaritalStatusField, value) != true)) { this.MaritalStatusField = value; this.RaisePropertyChanged("MaritalStatus"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public string NationalInsuranceNumber { get { return this.NationalInsuranceNumberField; } set { if ((object.ReferenceEquals(this.NationalInsuranceNumberField, value) != true)) { this.NationalInsuranceNumberField = value; this.RaisePropertyChanged("NationalInsuranceNumber"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.LookupItem Nationality { get { return this.NationalityField; } set { if ((object.ReferenceEquals(this.NationalityField, value) != true)) { this.NationalityField = value; this.RaisePropertyChanged("Nationality"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public bool NoMailMarketing { get { return this.NoMailMarketingField; } set { if ((this.NoMailMarketingField.Equals(value) != true)) { this.NoMailMarketingField = value; this.RaisePropertyChanged("NoMailMarketing"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public System.Nullable<int> NoOfChildren { get { return this.NoOfChildrenField; } set { if ((this.NoOfChildrenField.Equals(value) != true)) { this.NoOfChildrenField = value; this.RaisePropertyChanged("NoOfChildren"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public bool NoThirdPartyMarketing { get { return this.NoThirdPartyMarketingField; } set { if ((this.NoThirdPartyMarketingField.Equals(value) != true)) { this.NoThirdPartyMarketingField = value; this.RaisePropertyChanged("NoThirdPartyMarketing"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.LookupItem Occupation { get { return this.OccupationField; } set { if ((object.ReferenceEquals(this.OccupationField, value) != true)) { this.OccupationField = value; this.RaisePropertyChanged("Occupation"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public string PreviousName { get { return this.PreviousNameField; } set { if ((object.ReferenceEquals(this.PreviousNameField, value) != true)) { this.PreviousNameField = value; this.RaisePropertyChanged("PreviousName"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public System.Nullable<System.DateTime> ReviewDate { get { return this.ReviewDateField; } set { if ((this.ReviewDateField.Equals(value) != true)) { this.ReviewDateField = value; this.RaisePropertyChanged("ReviewDate"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.LookupItem Status { get { return this.StatusField; } set { if ((object.ReferenceEquals(this.StatusField, value) != true)) { this.StatusField = value; this.RaisePropertyChanged("Status"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.CustomerServiceWSDL.LookupItem Title { get { return this.TitleField; } set { if ((object.ReferenceEquals(this.TitleField, value) != true)) { this.TitleField = value; this.RaisePropertyChanged("Title"); } } } public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; if ((propertyChanged != null)) { propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] [System.Runtime.Serialization.DataContractAttribute(Name="LookupItem", Namespace= + APIWEB)] [System.SerializableAttribute()] public partial class LookupItem : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged { [System.NonSerializedAttribute()] private System.Runtime.Serialization.ExtensionDataObject extensionDataField; [System.Runtime.Serialization.OptionalFieldAttribute()] private string CodeField; [System.Runtime.Serialization.OptionalFieldAttribute()] private string DisplayTextField; [System.Runtime.Serialization.OptionalFieldAttribute()] private bool IsActiveField; [global::System.ComponentModel.BrowsableAttribute(false)] public System.Runtime.Serialization.ExtensionDataObject ExtensionData { get { return this.extensionDataField; } set { this.extensionDataField = value; } } [System.Runtime.Serialization.DataMemberAttribute()] public string Code { get { return this.CodeField; } set { if ((object.ReferenceEquals(this.CodeField, value) != true)) { this.CodeField = value; this.RaisePropertyChanged("Code"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public string DisplayText { get { return this.DisplayTextField; } set { if ((object.ReferenceEquals(this.DisplayTextField, value) != true)) { this.DisplayTextField = value; this.RaisePropertyChanged("DisplayText"); } } } [System.Runtime.Serialization.DataMemberAttribute()] public bool IsActive { get { return this.IsActiveField; } set { if ((this.IsActiveField.Equals(value) != true)) { this.IsActiveField = value; this.RaisePropertyChanged("IsActive"); } } } public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; if ((propertyChanged != null)) { propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } }
That's cause purchaseOnHoldSetRequest.AdditionalDetail is an Array type (mostly, from your posted code) which you haven't initialized and trying to set an item in index 0 saying purchaseOnHoldSetRequest.AdditionalDetail[0].Description which will bound to throw NullRefException Per your WSDL, the said property is array of AdditionalDetails class as seen below [System.Runtime.Serialization.DataMemberAttribute()] public Account_Status.ServiceReference2.AdditionalDetail[] AdditionalDetail { get { return this.AdditionalDetailField; } set { if ((object.ReferenceEquals(this.AdditionalDetailField, value) != true)) { this.AdditionalDetailField = value; this.RaisePropertyChanged("AdditionalDetail"); } } } Thus you need to initialize it first purchaseOnHoldSetRequest.UserName = "username"; purchaseOnHoldSetRequest.Password = "password"; purchaseOnHoldSetRequest.SystemToken = "systemtoken"; purchaseOnHoldSetRequest.AgreementReference = customerAgreementNumberComboBox.Text; purchaseOnHoldSetRequest.AdditionalDetail = new AdditionalDetail[3]; // here And then access it likewise you are doing purchaseOnHoldSetRequest.AdditionalDetail[0] = new AdditionalDetail(); purchaseOnHoldSetRequest.AdditionalDetail[0].Description = "1";
Getting new items added to an Observable Collection of a custom class
I have a set of classes that I am using to deserialize JSON into. My program will periodically look for changes to this JSON file, and if it finds any, will push the new data to the properties of these classes using reflection. I need to find any new items added to the collection of the Item2 class (SocialExportJSON.SocialExportData.Item2) after a successful update. My JSON classes look like this (there are more but I want to avoid too big a wall of code): public class Item2 : INotifyPropertyChanged { [JsonProperty("type")] private string type; public string Type { get { return type; } set { if (type != value) { type = value; RaisePropertyChanged("Type"); } } } [JsonProperty("id")] private string id; public string ID { get { return id; } set { if (id != value) { id = value; RaisePropertyChanged("ID"); } } } [JsonProperty("postedIso8601")] private string postedIso8601; public string PostedIso8601 { get { return postedIso8601; } set { if (postedIso8601 != value) { postedIso8601 = value; RaisePropertyChanged("PostedIso8601"); } } } [JsonProperty("postedTimestamp")] private object postedTimestamp; public object PostedTimestamp { get { return postedTimestamp; } set { if (postedTimestamp != value) { postedTimestamp = value; RaisePropertyChanged("PostedTimestamp"); } } } [JsonProperty("engagement")] private Engagement engagement; public Engagement Engagement { get { return engagement; } set { if (engagement != value) { engagement = value; RaisePropertyChanged("Engagement"); } } } [JsonProperty("source")] private Source2 source; public Source2 Source { get { return source; } set { if (source != value) { source = value; RaisePropertyChanged("Source"); } } } [JsonProperty("author")] private Author author; public Author Author { get { return author; } set { if (author != value) { author = value; RaisePropertyChanged("Author"); } } } [JsonProperty("content")] private Content content; public Content Content { get { return content; } set { if (content != value) { content = value; RaisePropertyChanged("Content"); } } } [JsonProperty("location")] private Location location; public Location Location { get { return location; } set { if (location != value) { location = value; RaisePropertyChanged("Location"); } } } [JsonProperty("publication")] private Publication publication; public Publication Publication { get { return publication; } set { if (publication != value) { publication = value; RaisePropertyChanged("Publication"); } } } [JsonProperty("metadata")] private Metadata metadata; public Metadata Metadata { get { return metadata; } set { if (metadata != value) { metadata = value; RaisePropertyChanged("Metadata"); } } } //Event handling public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string property) { //Console.WriteLine("Updated"); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } } public class SocialExportData : INotifyPropertyChanged { [JsonProperty("dataType")] private string dataType; public string DataType { get { return dataType; } set { if (dataType != value) { dataType = value; RaisePropertyChanged("DataType"); } } } [JsonProperty("id")] private int id; public int ID { get { return id; } set { if (id != value) { id = value; RaisePropertyChanged("ID"); } } } [JsonProperty("story")] private Story story; public Story Story { get { return story; } set { if (story != value) { story = value; RaisePropertyChanged("Story"); } } } [JsonProperty("order")] private string order; public string Order { get { return order; } set { if (order != value) { order = value; RaisePropertyChanged("Order"); } } } [JsonProperty("lifetime")] private string lifetime; public string Lifetime { get { return lifetime; } set { if (lifetime != value) { lifetime = value; RaisePropertyChanged("Lifetime"); } } } [JsonProperty("maxAge")] private int maxAge; public int MaxAge { get { return maxAge; } set { if (maxAge != value) { maxAge = value; RaisePropertyChanged("MaxAge"); } } } [JsonProperty("maxSize")] private int maxSize; public int MaxSize { get { return maxSize; } set { if (maxSize != value) { maxSize = value; RaisePropertyChanged("MaxSize"); } } } [JsonProperty("consumeCount")] private int consumeCount; public int ConsumeCount { get { return consumeCount; } set { if (consumeCount != value) { consumeCount = value; RaisePropertyChanged("ConsumeCount"); } } } [JsonProperty("consumeInterval")] private int consumeInterval; public int ConsumeInterval { get { return consumeInterval; } set { if (consumeInterval != value) { consumeInterval = value; RaisePropertyChanged("ConsumeInterval"); } } } [JsonProperty("items")] private ObservableCollection<Item2> items; public ObservableCollection<Item2> Items { get { return items; } set { if (items != value) { items = value; RaisePropertyChanged("Items"); } } } //Event handling public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string property) { //Console.WriteLine("Updated"); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } } public class SocialExportJSON : INotifyPropertyChanged { [JsonProperty("id")] private string id; public string ID { get { return id; } set { if (id != value) { id = value; RaisePropertyChanged("ID"); } } } [JsonProperty("ttl")] private int ttl; public int TTL { get { return ttl; } set { if (ttl != value) { ttl = value; RaisePropertyChanged("TTL"); } } } [JsonProperty("serial")] private long serial; public long Serial { get { return serial; } set { if (serial != value) { serial = value; RaisePropertyChanged("Serial"); } } } [JsonProperty("formatType")] private string formatType; public string FormatType { get { return formatType; } set { if (formatType != value) { formatType = value; RaisePropertyChanged("FormatType"); } } } [JsonProperty("modifiedIso8601")] private string modifiedIso8601; public string ModifiedIso8601 { get { return modifiedIso8601; } set { if (modifiedIso8601 != value) { modifiedIso8601 = value; RaisePropertyChanged("ModifiedIso8601"); } } } [JsonProperty("modifiedTimestamp")] private long modifiedTimestamp; public long ModifiedTimestamp { get { return modifiedTimestamp; } set { if (modifiedTimestamp != value) { modifiedTimestamp = value; RaisePropertyChanged("ModifiedTimestamp"); } } } [JsonProperty("timezone")] private string timezone; public string Timezone { get { return timezone; } set { if (timezone != value) { timezone = value; RaisePropertyChanged("Timezone"); } } } [JsonProperty("dataType")] private string dataType; public string DataType { get { return dataType; } set { if (dataType != value) { dataType = value; RaisePropertyChanged("DataType"); } } } [JsonProperty("exports")] private ObservableCollection<SocialExportData> exports; public ObservableCollection<SocialExportData> Exports { get { return exports; } set { if (exports != value) { exports = value; RaisePropertyChanged("Exports"); } } } //Event handling public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string property) { //Console.WriteLine("Updated"); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } } In another class, I have a method to deserialize to a global instance of my JSON class. It looks like this: public SocialExportJSON socialExportData; private async void DownloadAndDeserializeJSONAsync() { try { //Create a web client with the supplied credentials var exportClient = new WebClient { Credentials = new NetworkCredential(uName, pw), Encoding = Encoding.UTF8}; //Create a task to download the JSON string and wait for it to finish var downloadTask = Task.Run(() => exportClient.DownloadString(new Uri(eURL))); downloadTask.Wait(); //Get the string from the task var JSONString = await downloadTask; //Create a task to deserialize the JSON from the last task var DeserializeTask = Task.Run(() => JsonConvert.DeserializeObject<SocialExportJSON>(JSONString)); DeserializeTask.Wait(); SocialExportJSON sej = await DeserializeTask; //Check the timestamp first to see if we should change the data if(socialExportData == null) { //Get the data from the task socialExportData = await DeserializeTask; } else if(sej.ModifiedTimestamp != socialExportData.ModifiedTimestamp) { //Get the data from the task SocialExportJSON newData = await DeserializeTask; GetNewItems(newData); SetNewData(newData); //Call the exportUpdated event when the task has finished exportUpdated(); } } catch (Exception e) { MessageBox.Show(e.Message.ToString()); } } In my SetNewData function, shown below, I use reflection to set the properties of my global class. Because I'm setting the whole collection rather than iterating through each of the properties in each of the classes, I can't use the CollectionChanged event to find new items. public void SetNewData(SocialExportJSON newData) { //Loop through each of the properties and copy from source to target foreach (PropertyInfo pi in socialExportData.GetType().GetProperties()) { if (pi.CanWrite) { pi.SetValue(socialExportData, pi.GetValue(newData, null), null); } } } Is there a way I can modify my SetNewData function in such a way that it calls CollectionChanged? If not, what would be the best way to go about getting any new additions to my collection of Item2?
In my Main function. I create an instance of my class called SocialExport like so: SocialExport s = new SocialExport("http://example.json", "example", "example");. This class is where the global instance of my JSON class is contained, and my event handler is added like so s.socialExportData.Exports[0].Items.CollectionChanged += CollectionChanged; Then you are hooking up an event handler for the CollectionChanged event for that particular instance of ObservableCollection<Item2>. If you create a new ObservableCollection<Item2>, you obviously must hook up an event handler to this one as well. The event handler that is associated with the old object won't be invoked when new items are added to the new instance. So whenever a new ObservableCollection<Item2> is created, using deserialization or not, you should hook up a new event handler. You could probably do this in your DownloadAndDeserializeJSONAsync method. The other option would be to create only one instance of the collection and remove and add items from/to this one.
Why my ICollection is always empty?
I am trying to reach a foreach but my program never gets inside because my ICollection Coletores is always empty even if I put a lot of stuff in there. The code where I want to get inside and it is always empty (I want to get inside the second foreach): protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { if (NavigationContext.QueryString.TryGetValue("email", out email)) { //MessageBox.Show(email); List<HyperlinkButton> listaLinks = new List<HyperlinkButton>(); AppDataContext db = new AppDataContext(); int i = 0; HyperlinkButton aux = new HyperlinkButton(); foreach (Pessoa pessoa in db.Pessoas) { if (pessoa.Email == email) { foreach (Coletor coletor in pessoa.Coletores) { aux.Content = "Coletor " + (i + 1).ToString(); aux.FontSize = 24; aux.NavigateUri = new Uri("/OcorrenciasPage.xaml?coletorId=" + coletor.Id.ToString(), UriKind.RelativeOrAbsolute); listaLinks.Add(aux); i++; } } } ListBox coletores = new ListBox(); coletores.ItemsSource = listaLinks; stcList.Children.Add(coletores); } base.OnNavigatedTo(e); } Now the code that I am adding data: if (txtLat.Text != "" && txtLong.Text != "" && rdNorte.IsChecked == true || rdSul.IsChecked == true && rdLeste.IsChecked == true || rdOeste.IsChecked == true) { foreach (var pessoa in db.Pessoas) { if (pessoa.Email == email) { pessoa.Coletores.Add(coletor); } } db.Coletores.InsertOnSubmit(coletor); db.SubmitChanges(); NavigationService.Navigate(new Uri("/ColetoresPage.xaml?email=" + email, UriKind.RelativeOrAbsolute)); } Now, my Pessoa class: public class Pessoa : INotifyPropertyChanged { private int _id; [Column(IsDbGenerated = true, IsPrimaryKey = true)] public int Id { get { return _id;} set { _id = value; OnPropertyChanged("Id"); } } private string _nome; [Column] public string Nome { get { return _nome; } set { _nome = value; OnPropertyChanged("Nome"); } } private string _email; [Column] public string Email { get { return _email; } set { _email = value; OnPropertyChanged("Email"); } } private string _senha; [Column] public string Senha { get { return _senha; } set { _senha = value; OnPropertyChanged("Senha"); } } private string _profissao; [Column] public string Profissao { get { return _profissao; } set { _profissao = value; OnPropertyChanged("Profissao"); } } private int _idade; [Column] public int Idade { get { return _idade; } set { _idade = value; OnPropertyChanged("Idade"); } } private string _endereco; [Column] public string Endereco { get { return _endereco; } set { _endereco = value; OnPropertyChanged("Endereco"); } } private string _cidade; [Column] public string Cidade { get { return _cidade; } set { _cidade = value; OnPropertyChanged("Cidade"); } } private string _estado; [Column] public string Estado { get { return _estado; } set { _estado = value; OnPropertyChanged("Estado"); } } private EntitySet<Coletor> _coletores = new EntitySet<Coletor>(); [Association(Name = "FK_Coletores_PessoaColetores", Storage = "_coletores", ThisKey = "Id", OtherKey = "pessoaId")] public ICollection<Coletor> Coletores { get { return _coletores; } set { _coletores.Assign(value); } } private EntitySet<PessoaColetor> _pessoaColetores = new EntitySet<PessoaColetor>(); [Association(Name = "FK_PessoaColetores_Pessoas", Storage = "_pessoaColetores", OtherKey = "pessoaId", ThisKey = "Id")] private ICollection<PessoaColetor> PessoaColetores { get { return _pessoaColetores; } set { _pessoaColetores.Assign(value); } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string name) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(name)); } } }
The Coletores property on the Pessoa class looks alright. There is also a PessoaColetores property. Are you sure there has been no confusion between the two? Especially with intellisense one might dot or tab the wrong one. Have you put a break point on the line that actually adds coletors (second code snippet)? Maybe stuff is added to the wrong collection. Cheers, B.
Entity Framework 6.1: CRUD on Child objects
I populate a data grid with a list of objects that come from a repository like this: public static IEnumerable<Order> GetOrdersForDataGrid() { IEnumerable<Order> query; using (RSDContext = new RSDContext()) { query = context.Orders.Include(o=>o.OrderDetails).ToList(); } return query; } When I want to edit an order I pass the selected row to a new window like this: OrderEditWindow orderEdit = new OrderEditWindow(); orderEdit.SelectedOrder = SelectedOrder; orderEdit.ShowDialog(); Here I set the DataContext of the Window to: DataContext = SelectedOrder; In this window I have another data grid that binds to OrderDetails collection property of Order. The problem is on CRUD operations on OrderDetails. For example, after I add a new orderDetail like this: private void AddProductDetailButton_OnClick(object sender, RoutedEventArgs e) { if (!ValidateProductDetail()) return; var _selectedProduct = ProductAutoCompleteBox.SelectedItem as Product; var selectedProduct = ProductsRepository.GetProductById(_selectedProduct.ProductId); OrderDetail orderDetail = new OrderDetail(); orderDetail.Price = selectedProduct.Price; orderDetail.ProductCode = selectedProduct.Code; orderDetail.ProductName = selectedProduct.Name; orderDetail.Quantity = int.Parse(QuantityNumericUpDown.Value.ToString()); orderDetail.Um = selectedProduct.Um; orderDetail.Total = selectedProduct.Price * int.Parse(QuantityNumericUpDown.Value.ToString()); orderDetail.Group = selectedProduct.Subgroup.Group.Name; orderDetail.Subgroup = selectedProduct.Subgroup.Name; orderDetail.SupplierName = selectedProduct.Supplier.Name; //orderDetail.Order=SelectedOrder; //orderDetail.OrderId = SelectedOrder.OrderId; SelectedOrder.OrderDetails.Add(orderDetail); ProductAutoCompleteBox.Text = string.Empty; QuantityNumericUpDown.Value = 1; ProductAutoCompleteBox.Focus(); } and then I call the update method from repository: public static void UpdateOrder(Order order) { using (RSDContext context = new RSDContext()) { context.Orders.Attach(order); context.Entry(order).State = EntityState.Modified; context.SaveChanges(); } } I get an error about OrderId. If i set manualy the navigation property and the id I don't get an error but changes dont get saved into db. My Order model look like this: public class Order : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public Order() { _OrderDetails = new ObservableCollection<OrderDetail>(); _OrderDetails.CollectionChanged += _OrderDetails_CollectionChanged; } void _OrderDetails_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (e.NewItems != null) AttachProductChangedEventHandler(e.NewItems.Cast<OrderDetail>()); if (e.OldItems != null) CalcualteTotals(); } [NotMapped] public decimal CalculatedTotal { get { return OrderDetails.Sum(x => x.Total); } } public int OrderId { get; set; } private int _Number; public int Number { get { return _Number; } set { _Number = value; NotifyPropertyChanged("Number"); } } private DateTime _Date; public DateTime Date { get { return _Date; } set { _Date = value; NotifyPropertyChanged("Date"); } } private bool _Canceled; public bool Canceled { get { return _Canceled; } set { _Canceled = value; NotifyPropertyChanged("Canceled"); } } private string _ClientName; public string ClientName { get { return _ClientName; } set { _ClientName = value; NotifyPropertyChanged("ClientName"); } } private string _ClientPhone; public string ClientPhone { get { return _ClientPhone; } set { _ClientPhone = value; NotifyPropertyChanged("ClientPhone"); } } private string _DeliveryAddress; public string DeliveryAddress { get { return _DeliveryAddress; } set { _DeliveryAddress = value; NotifyPropertyChanged("DeliveryAddress"); } } private decimal _Transport; public decimal Transport { get { return _Transport; } set { _Transport = value; NotifyPropertyChanged("Transport"); } } private decimal _Total; public decimal Total { get { return _Total; } set { _Total = value; NotifyPropertyChanged("Total"); } } private ObservableCollection<OrderDetail> _OrderDetails; public virtual ObservableCollection<OrderDetail> OrderDetails { //get { return _OrderDetails ?? (_OrderDetails = new ObservableCollection<OrderDetail>()); } get { return _OrderDetails; } set { _OrderDetails = value; NotifyPropertyChanged("OrderDetails"); } } private void AttachProductChangedEventHandler(IEnumerable<OrderDetail> orderDetails) { foreach (var p in orderDetails) { p.PropertyChanged += (sender, e) => { switch (e.PropertyName) { case "Quantity": case "Price": case "Total": CalcualteTotals(); break; } }; } CalcualteTotals(); } public void CalcualteTotals() { NotifyPropertyChanged("CalculatedTotal"); } public void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } And my OrderDetail model look like this: public class OrderDetail : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public int OrderDetailId { get; set; } public int OrderId { get; set; } public Order Order { get; set; } private int _ProductCode; public int ProductCode { get { return _ProductCode; } set { _ProductCode = value; NotifyPropertyChanged("ProductCode"); } } private string _ProductName; public string ProductName { get { return _ProductName; } set { _ProductName = value; NotifyPropertyChanged("ProductName"); } } private string _Um; public string Um { get { return _Um; } set { _Um = value; NotifyPropertyChanged("Um"); } } private decimal _Price; public decimal Price { get { return _Price; } set { _Price = value; NotifyPropertyChanged("Price"); NotifyPropertyChanged("Total"); } } private int _Quantity; public int Quantity { get { return _Quantity; } set { _Quantity = value; NotifyPropertyChanged("Quantity"); NotifyPropertyChanged("Total"); } } private string _SupplierName; public string SupplierName { get { return _SupplierName; } set { _SupplierName = value; NotifyPropertyChanged("SupplierName"); } } private string _Subgroup; public string Subgroup { get { return _Subgroup; } set { _Subgroup = value; NotifyPropertyChanged("Subgroup"); } } private string _Group; public string Group { get { return _Group; } set { _Group = value; NotifyPropertyChanged("Group"); } } public decimal _Total; public decimal Total { get { return Quantity * Price; } set { _Total = value; NotifyPropertyChanged("Total"); } } public void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } I'm really trying to use some sort of unit of work and I don't understand how i'm supposed to apply CRUD on objects with child collections and keep the UI updated in the same time (by working in a ObservableCollection and using Binding ClientPhone, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged my parent window is updated as I type) A final working solution: using (RSDContext context = new RSDContext()) { var details = order.OrderDetails; order.OrderDetails = null; List<int> OriginalOrderDetailsIds = context.OrderDetails.Where(o => o.OrderId == order.OrderId).Select(o => o.OrderDetailId).ToList(); List<int> CurrentOrderDetailsIds = details.Select(o => o.OrderDetailId).ToList(); List<int> DeletedOrderDetailsIds = OriginalOrderDetailsIds.Except(CurrentOrderDetailsIds).ToList(); context.Entry(order).State = EntityState.Modified; foreach (var deletedOrderDetailId in DeletedOrderDetailsIds) { context.Entry(context.OrderDetails.Single(o => o.OrderDetailId == deletedOrderDetailId)).State = EntityState.Deleted; } foreach (OrderDetail detail in details) { // Add. if (detail.OrderDetailId == 0) { detail.OrderId = order.OrderId; context.Entry(detail).State = EntityState.Added; } // Update. else { context.Entry(detail).State = EntityState.Modified; } } context.SaveChanges(); }
You could do this way for adding and updating the child, but not sure about deleted order details in the ui. If you don't want to get the order from entity, you need some kind of marking in the OrderDetail for deleted OrderDetail. using (RSDContext context = new RSDContext()) { var details = order.OrderDetails; order.OrderDetails = null; context.Entry(order).State = EntityState.Modified; foreach (var detail in details) { if (detail.Id == 0) { // Adds. detail.OrderId = order.Id; context.Entry(detail).State = EntityState.Added; } else if (detail.IsDeleted) // Adds new property called 'IsDeleted' // and add [NotMapped] attribute // then mark this property as true from the UI for deleted items. { // Deletes. context.Entry(detail).State = EntityState.Deleted; } else { // Updates. context.Entry(detail).State = EntityState.Modified; } } order.OrderDetails = details; context.SaveChanges(); }