我的WCF服务方法多次调用

时间:2012-09-21 12:41:55

标签: c# .net silverlight mvvm

我已根据下面提到的简短直接问题更新了我的问题: 我知道MVVM的基本知识,但我不知道它的实现。 问题: -

  • 第一次所有方法,例如private void UserControl_Loaded(),void serviceClient_GetDeptIDNameCompleted(),private void cbDeptName_SelectionChanged(),void serviceClient_GetSectionsListCompleted(),private void cbDeptSections_SelectionChanged(),void serviceClient_GetSectionDetailCompleted()调用一次,顺序一次接着一个。
  • 如果我从任何组合框中更改任何选择,则每个方法都会调用几次(变量)次。

我认为这是因为执行不良或标准编码低。任何人都可以建议我做好实施。提前谢谢。

更新: - 我的a.xml

<Departments>

    <Department>

        <deptID>
            1
        </deptID>

        <deptName>
            Arts
        </deptName>

        <Sections>

            <Section>
                <sectionID>A</sectionID>
                <sectionName>Political Science</sectionName>
                <NoOfLecturers>5</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>B</sectionID>
                <sectionName>Economics</sectionName>
                <NoOfLecturers>3</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>C</sectionID>
                <sectionName>Social Studies</sectionName>
                <NoOfLecturers>7</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>D</sectionID>
                <sectionName>History</sectionName>
                <NoOfLecturers>5</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>E</sectionID>
                <sectionName>Geography</sectionName>
                <NoOfLecturers>2</NoOfLecturers>
            </Section>

        </Sections>

    </Department>

    <Department>

        <deptID>
            2
        </deptID>

        <deptName>
            Sciences
        </deptName>

        <Sections>

            <Section>
                <sectionID>A</sectionID>
                <sectionName>Physics</sectionName>
                <NoOfLecturers>10</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>B</sectionID>
                <sectionName>Mathematics</sectionName>
                <NoOfLecturers>2</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>C</sectionID>
                <sectionName>Chemistry</sectionName>
                <NoOfLecturers>6</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>D</sectionID>
                <sectionName>Botany</sectionName>
                <NoOfLecturers>5</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>E</sectionID>
                <sectionName>Zeology</sectionName>
                <NoOfLecturers>4</NoOfLecturers>
            </Section>

        </Sections>

    </Department>

    <Department>

        <deptID>
            3
        </deptID>

        <deptName>
            Commerce
        </deptName>

        <Sections>

            <Section>
                <sectionID>A</sectionID>
                <sectionName>Accounting</sectionName>
                <NoOfLecturers>3</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>B</sectionID>
                <sectionName>Marketing</sectionName>
                <NoOfLecturers>2</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>C</sectionID>
                <sectionName>Human Resources</sectionName>
                <NoOfLecturers>5</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>D</sectionID>
                <sectionName>Finance</sectionName>
                <NoOfLecturers>5</NoOfLecturers>
            </Section>

        </Sections>

    </Department>

    <Department>

        <deptID>
            4
        </deptID>

        <deptName>
            Library
        </deptName>

        <Sections>

            <Section>
                <sectionID>A</sectionID>
                <sectionName>Incharge</sectionName>
                <NoOfLecturers>3</NoOfLecturers>
            </Section>

            <Section>
                <sectionID>B</sectionID>
                <sectionName>Clerk</sectionName>
                <NoOfLecturers>3</NoOfLecturers>
            </Section>

        </Sections>

    </Department>

</Departments>

我的WCFService.cs类(Service1.svc.cs)

// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IService1
    {
        XmlDocument doc;

        string xmlPath = @"D:\WcfService1\WcfService1\Resources\a.xml";

        public Dictionary<string, string> GetDeptIDName()
        {
            try
            {
                if (!File.Exists(xmlPath))
                {
                    return null;
                }
                else
                {
                    Dictionary<string, string> depIDName = new Dictionary<string, string>();
                    doc = new XmlDocument();
                    doc.Load(xmlPath);
                    XmlNodeList nl = doc.GetElementsByTagName("Department");

                    foreach (XmlNode node in nl)
                    {
                        string id = (node.FirstChild.InnerXml).Replace("\r", "").Replace("\n", "").Replace("\t", "");
                        string name = (node.FirstChild.NextSibling.InnerXml).Replace("\r", "").Replace("\n", "").Replace("\t", "");
                        depIDName.Add(id, name);
                    }

                    return depIDName;
                }
            }
            catch (Exception)
            {
                return null;
            }
        }

        public List<string> GetSectionsList(string deptName)
        {
            try
            {
                if (!File.Exists(xmlPath))
                {
                    return null;
                }
                else
                {
                    List<string> lstSectionList = new List<string>();
                    doc = new XmlDocument();
                    doc.Load(xmlPath);
                    XmlNodeList nl = doc.GetElementsByTagName("Department");

                    foreach (XmlNode node in nl)
                    {
                        string name = (node.FirstChild.NextSibling.InnerXml).Replace("\r", "").Replace("\n", "").Replace("\t", "");
                        if (name == deptName)
                        {
                            UpdateSectionsList(ref lstSectionList, node.LastChild);
                        }
                    }

                    return lstSectionList;
                }
            }
            catch (Exception)
            {
                return null;
            }
        }

        private void UpdateSectionsList(ref List<string> lstSectionList,
                                        XmlNode xmlNode)
        {
            XmlNodeList nl = xmlNode.ChildNodes;

            foreach (XmlNode xNode in nl)
            {
                foreach (XmlNode sectionNode in (XmlNodeList)xNode.ChildNodes)
                {
                    if ("sectionID" == sectionNode.Name)
                    {
                        lstSectionList.Add(sectionNode.InnerXml);
                    }
                }
            }
        }

        /// <summary>
        /// Get all the sections detail.
        /// </summary>
        /// <param name="deptName"></param>
        /// <param name="sectionID"></param>
        /// <returns></returns>
        public CompositeType GetSectionDetail(string deptName,
                                              string sectionID)
        {
            try
            {
                if (!File.Exists(xmlPath))
                {
                    return null;
                }
                else
                {
                    CompositeType compositeObj = new CompositeType();

                    doc = new XmlDocument();

                    doc.Load(xmlPath);

                    XmlNodeList nl = doc.GetElementsByTagName("Department");

                    foreach (XmlNode node in nl)
                    {
                        string name = (node.FirstChild.NextSibling.InnerXml).
                                       Replace("\r", "").
                                       Replace("\n", "").
                                       Replace("\t", "");

                        if (name == deptName)
                        {
                            UpdateSectionDetail(out compositeObj,
                                                GetSectionNodes(node.LastChild,
                                                                sectionID));
                        }
                    }

                    return compositeObj;
                }
            }
            catch (Exception)
            {
                return null;
            }
        }

        private void UpdateSectionDetail(out CompositeType compositeObj,
                                         XmlNode xmlNode)
        {
            compositeObj =
                new CompositeType();

            compositeObj.SectionID = 
                xmlNode.FirstChild.InnerXml;

            compositeObj.SectionName = 
                xmlNode.LastChild.PreviousSibling.InnerXml;

            compositeObj.SectionLecturers =
                xmlNode.LastChild.InnerXml;
        }

        private XmlNode GetSectionNodes(XmlNode xmlNode,
                                        string sectionID)
        {
            try
            {
                XmlNodeList nl = xmlNode.ChildNodes;

                XmlNode returnNode = xmlNode;

                foreach (XmlNode xNode in nl)
                    foreach (XmlNode sectionNode in (XmlNodeList)xNode.ChildNodes)
                        if (("sectionID" == sectionNode.Name)
                                        &&
                            (sectionNode.InnerXml == sectionID))
                        {
                            returnNode = xNode;
                        }

                return returnNode;
            }
            catch(Exception)
            {
                return null;
            }
        }
    }

IService1.cs接口

// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        Dictionary<string, string> GetDeptIDName();

        [OperationContract]
        List<string> GetSectionsList(string deptName);

        [OperationContract]
        CompositeType GetSectionDetail(string deptName, string sectionID);

        // TODO: Add your service operations here
    }

    // Use a data contract as illustrated in the sample below to add composite types to service operations.
    [DataContract]
    public class CompositeType
    {
        string sectionID = string.Empty, sectionName = string.Empty, NoOfLectures = string.Empty;

        [DataMember]
        public string SectionID
        {
            get
            {
                return sectionID; 
            }
            set 
            {
                sectionID = value; 
            }
        }

        [DataMember]
        public string SectionName
        {
            get
            {
                return sectionName;
            }
            set
            {
                sectionName = value;
            }
        }
        [DataMember]
        public string SectionLecturers
        {
            get
            {
                return NoOfLectures;
            }
            set
            {
                NoOfLectures = value;
            }
        }
    }

MainPage.xaml.cs类

 public partial class MainPage : UserControl
    {
        Service1Client serviceClient = new Service1Client();

        public MainPage()
        {
            InitializeComponent();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            serviceClient.GetDeptIDNameCompleted += new EventHandler<GetDeptIDNameCompletedEventArgs>(serviceClient_GetDeptIDNameCompleted);
            serviceClient.GetDeptIDNameAsync();
        }

        void serviceClient_GetDeptIDNameCompleted(object sender, GetDeptIDNameCompletedEventArgs e)
        {
            cbDeptName.ItemsSource = e.Result;
            cbDeptName.SelectedItem = cbDeptName.Items[0];
        }

        private void cbDeptName_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //Remove square brackets from the List box item.
            string lstBoxItem = Regex.Replace(cbDeptName.SelectedValue.ToString(),
                                              @"[\[\]\s]",
                                              string.Empty);

            //Split the list box item into two parts by considering the (,)
            //to separate the DICOM ID and Patient name.
            string[] strItems = (lstBoxItem).Split(Convert.ToChar(","));

            serviceClient.GetSectionsListCompleted += new EventHandler<GetSectionsListCompletedEventArgs>(serviceClient_GetSectionsListCompleted);
            serviceClient.GetSectionsListAsync(strItems[1]);
        }

        void serviceClient_GetSectionsListCompleted(object sender, GetSectionsListCompletedEventArgs e)
        {
            cbDeptSections.ItemsSource = e.Result;
            cbDeptSections.SelectedItem = cbDeptSections.Items[0];
            //serviceClient.GetSectionDetailCompleted += new EventHandler<GetSectionDetailCompletedEventArgs>(serviceClient_GetSectionDetailCompleted);
            //serviceClient.GetSectionDetailAsync(strItems[1], cbDeptSections.SelectedItem.ToString());
        }

        private void cbDeptSections_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (null == cbDeptSections.SelectedItem)
                return;

            lbSectionDetail.Items.Clear();

            //Remove square brackets from the List box item.
            string lstBoxItem = Regex.Replace(cbDeptName.SelectedValue.ToString(),
                                              @"[\[\]\s]",
                                              string.Empty);

            //Split the list box item into two parts by considering the (,)
            //to separate the DICOM ID and Patient name.
            string[] strItems = (lstBoxItem).Split(Convert.ToChar(","));

            serviceClient.GetSectionDetailCompleted += new EventHandler<GetSectionDetailCompletedEventArgs>(serviceClient_GetSectionDetailCompleted);
            serviceClient.GetSectionDetailAsync(strItems[1], cbDeptSections.SelectedItem.ToString());
        }

        void serviceClient_GetSectionDetailCompleted(object sender, GetSectionDetailCompletedEventArgs e)
        {
            CompositeType compositeObj = e.Result;
            //lbSectionDetail.Items.Clear();
            lbSectionDetail.Items.Add(compositeObj.SectionID);
            lbSectionDetail.Items.Add(compositeObj.SectionName);
            lbSectionDetail.Items.Add(compositeObj.SectionLecturers);
        }
    }

MainPage.xaml中

<StackPanel>

        <StackPanel        
            x:Name      ="LayoutRoot"
            Background  ="White"
            Orientation ="Horizontal"
            >

            <ComboBox
                x:Name                      ="cbDeptID"
                MinWidth                    ="50"
                HorizontalContentAlignment  ="Center"
                DisplayMemberPath           ="Key"
                SelectedValue               ="{Binding ElementName=cbDeptName, Path=SelectedValue, Mode=TwoWay}"
                />

            <ComboBox
                x:Name              ="cbDeptName"
                MinWidth            ="50"
                DisplayMemberPath   ="Value"
                SelectionChanged    ="cbDeptName_SelectionChanged"
                />

            <ComboBox
                x:Name              ="cbDeptSections"
                MinWidth            ="100"
                SelectionChanged    ="cbDeptSections_SelectionChanged"
                />

        </StackPanel>

        <ListBox
            x:Name                                      ="lbSectionDetail"
            ScrollViewer.HorizontalScrollBarVisibility  ="Auto"
            ScrollViewer.VerticalScrollBarVisibility    ="Auto"
            />

clientaccesspolicy.xml

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
    <cross-domain-access>
        <policy>
            <allow-from http-request-headers="SOAPAction">
                <domain uri="*"/>
            </allow-from>
            <grant-to>
                <resource path="/" include-subpaths="true"/>
            </grant-to>
        </policy>
    </cross-domain-access>
</access-policy>

1 个答案:

答案 0 :(得分:3)

我认为多次通话的罪魁祸首可能是

serviceClient.GetSectionDetailCompleted += new EventHandler<GetSectionDetailCompletedEventArgs>(serviceClient_GetSectionDetailCompleted);

在我看来,您正在多次注册完成事件,但从未注销它。您调用cbDeptName_SelectionChangedcbDeptName_SelectionChanged的次数越多,创建的事件处理程序就越多。当您的服务返回一个响应时,它们都会被调用。

编辑: 第一次加载应用程序时调用这些方法的原因是,当绑定组合框控件时,它们会自动将所选项目更改为列表中的第一项,从而调用SelectionChanged事件。

编辑2: 为了避免对同一事件进行多次调用,您应该在Loaded事件中注册该事件,就像执行serviceClient.GetDeptIDNameCompleted

一样

您的加载事件应如下所示:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    // Put these here instead of where they are now
    serviceClient.GetSectionsListCompleted += new EventHandler<GetSectionsListCompletedEventArgs>(serviceClient_GetSectionsListCompleted);
    serviceClient.GetSectionDetailCompleted += new EventHandler<GetSectionDetailCompletedEventArgs>(serviceClient_GetSectionDetailCompleted);

    serviceClient.GetDeptIDNameCompleted += new EventHandler<GetDeptIDNameCompletedEventArgs>(serviceClient_GetDeptIDNameCompleted);
    serviceClient.GetDeptIDNameAsync();
}

不要忘记从代码中的这些行中删除这些行。