简体   繁体   English

如何从Mutliple CheckBoxList选择检索输出并将其放置在ASP.Net的电子邮件文本文件中

[英]How Can I Retrieve the Output from Mutliple CheckBoxList Selections & Place in Email Text File in ASP.Net

In my ASP.Net/C# site, I have a page which acts as a form and records the user's information. 在我的ASP.Net/C#网站上,我有一个页面,该页面充当表单并记录用户的信息。 The form then sends this information to an email, by way of a formatted text file in my App Data folder. 然后,该表格通过“我的App Data文件夹中的格式化文本文件将该信息发送到电子邮件。 All of the input appears in the email, however, when I test to select multiple checkbox items, only one selection appears -- here's the formatted text file code: 所有输入都显示在电子邮件中,但是,当我测试选择多个复选框项时,只会出现一个选择-这是格式化的文本文件代码:

Customer Name:     ##CustName##
Phone Number:      ##PhoneNumber##
Service Address:   ##Address##
City/State:        ##lstCitySelect##
ZipCode:           ##ZipCode##

Service Type:      ##ServiceType##
Service Date:      ##ServiceDate##
Service Time:      ##ServiceTime##

And here's the code-behind of the form I'm using to process all this into the email: 这是我用来将所有这些内容处理到电子邮件中的表单的代码背后:

protected void btnSubmit_Click(object sender, EventArgs e)
{
    if (Page.IsValid)
    {
        string fileName = Server.MapPath("~/App_Data/ScheduleForm.txt");
        string mailBody = File.ReadAllText(fileName);

        mailBody = mailBody.Replace("##CustName##", txtFirstName.Text + " " + txtLastName.Text);            
        mailBody = mailBody.Replace("##PhoneNumber##", txtPhone.Text);
        mailBody = mailBody.Replace("##Address##", txtAddress.Text);
        mailBody = mailBody.Replace("##lstCitySelect##", lstCitySelect.SelectedValue);
        mailBody = mailBody.Replace("##ZipCode##", txtZipCode.Text);
        mailBody = mailBody.Replace("##ServiceType##", chkServiceOption.SelectedValue);
        mailBody = mailBody.Replace("##ServiceDate##", txtDatePopulate.Text);
        mailBody = mailBody.Replace("##ServiceTime##", txtTimePopulate.Text);
        mailBody = mailBody.Replace("##Details##", txtDetails.Text);

        MailMessage myMessage = new MailMessage();
        myMessage.Subject = "Response from web site";
        myMessage.Body = mailBody;

        myMessage.From = new MailAddress("email@myemail.com", "From Sender");
        myMessage.To.Add(new MailAddress("email@myemail.com", "To Recipient"));

        SmtpClient mySmtpClient = new SmtpClient();
        mySmtpClient.Send(myMessage);

        Message.Visible = true;
        FormTable.Visible = false;
    }            
}

My issue is with the chkServiceOption CheckBoxList control not returning all selected instances of "checked boxes" in the email. 我的问题是chkServiceOption CheckBoxList控件未返回电子邮件中所有选中的“复选框”实例。 I couldn't find a class to pull out the index of selected values. 我找不到可以提取所选值索引的类。 Can some please suggest what I can use or do to accomplish this? 有人可以建议我可以使用或做些什么来实现这一目标吗? I've included screen shots of the form before submitting, and after it hits the email -- notice only one instance of a service is pulled. 在提交表单之前,以及在点击电子邮件之后,我都提供了该表单的屏幕截图-请注意,仅拉取了一项服务实例

在此处输入图片说明在此处输入图片说明

From the documentation : 文档中

To determine the selected items in the CheckBoxList control, iterate through the Items collection and test the Selected property of each item in the collection. 若要确定CheckBoxList控件中的选定项目,请遍历Items集合并测试该集合中每个项目的Selected属性。

So you have to do something like this: 因此,您必须执行以下操作:

var services = chkServiceOption.Items.Cast<ListItem>()
                                     .Where(c => c.Selected)
                                     .Select(c => c.Text);

var servicesStr = string.Join(", ", services);

This is just a LINQ-ification of the following loop: 这只是以下循环的LINQ形式:

string ret = "";

foreach(var item in checkbox.items)
{
    if(item.Selected)
    {
        if (ret.Length > 0)
        {
            ret += ", ";
        }

        ret += item.Text;
    }
}

The idea is that you have to loop through each of the items in the CheckBoxList , check whether they are selected, then add them to a collection. 这个想法是,您必须遍历CheckBoxList中的每个项目,检查是否已选中它们,然后将它们添加到集合中。 I chose a comma-separated string for my "collection" in this example since I figured that's what you'd want in your email, but you can see how it could be any other type of collection as well. 在本示例中,我选择了一个逗号分隔的字符串作为“收藏”,因为我认为这就是您希望在电子邮件中使用的字符串,但是您也可以看到它也可以是任何其他类型的收藏。

Edit: 编辑:

This is just addressing a request in comments to explain the LINQ query. 这只是解决注释中的请求以解释LINQ查询。

There are four basic steps I took here. 我在这里采取了四个基本步骤。 I'll just go over each. 我将逐一讨论。

  1. chkServiceOption.Items : This is the same for the foreach as LINQ. chkServiceOption.Itemsforeach与LINQ相同。 I assume you understand where that's coming from. 我想你知道那是哪里来的。
  2. .Cast<ListItem>() : Here's where we start doing interesting things. .Cast<ListItem>() :这是我们开始做有趣的事情的地方。 The ListItemCollection class only implements IEnumerable , not the IEnumerable<T> that's required for LINQ queries to run. ListItemCollection类仅实现IEnumerable ,而不实现LINQ查询运行所需的IEnumerable<T> Thus, we have to cast each element to be of type ListItem . 因此,我们必须将每个元素ListItem转换为ListItem类型。 Behind the scenes, this is basically just a foreach loop that iterates over the ListItemCollection and casts each element. 在幕后,这基本上只是一个遍历ListItemCollection并强制转换每个元素的foreach循环。
  3. .Where(c => c.Selected) : Here's where we start using LINQ. .Where(c => c.Selected) :这是我们开始使用LINQ的地方。 We're now dealing with an IEnumerable<ListItem> , so we can run queries based on that knowledge. 现在,我们正在处理IEnumerable<ListItem> ,因此我们可以基于该知识运行查询。 The code behind here loops through each element, then only returns the elements that pass the predicate. 此处的代码循环遍历每个元素,然后仅返回通过谓词的元素。 In our case, that means it only returns the ones where c.Selected , which is just a well-known syntactic shortcut for c.Selected == true . 在我们的例子中,这意味着它仅返回c.Selected所在的c.Selected ,这只是c.Selected == true的众所周知的语法快捷方式。
  4. .Select(c => c.Text) : Now we have only the elements that we want, but they're still all typed as ListItem which isn't particularly useful to users. .Select(c => c.Text) :现在,我们只有想要的元素,但是它们仍然都以ListItem类型输入,这对用户并不是特别有用。 We want the text of each ListItem (checkbox), so we loop through each item and select the value of the Text property. 我们需要每个ListItem的文本(复选框),因此我们遍历每个项目并选择Text属性的值。
  5. string.Join : This isn't really LINQ-y either, but basically now we just want to put in a comma between each element so that it better-resembles a human-readable list. string.Join :这也不是真正的LINQ-y,但是基本上现在我们只想在每个元素之间放入一个逗号,以便它更好地类似于人类可读的列表。

The issue is that chkServiceType option can have multiple (or no) selected values, not just the one. 问题是chkServiceType选项可以有多个(或没有)选定的值,而不仅仅是一个。 Your code is looking for a single value when you need to iterate of the control's item collection to see if a child item is selected. 当您需要迭代控件的项目集合以查看是否选择了子项目时,您的代码正在寻找一个值。 I am a bit rusty on it but it should look something like: 我对此有些生疏,但看起来应该像这样:

   foreach(var item in checkbox.items)
   {
      if(item.Selected)
      {
          //Do Something
      }
   }
chkServiceOption.Items[0].Selected

chkServiceOption.Items[1].Selected

chkServiceOption.Items[2].Selected

chkServiceOption.Items[0].Text 

Examine those in the debugger or just append to email so you can see the values...... 检查调试器中的内容或仅将其附加到电子邮件中,以便您可以看到值...

The semantics of chkServiceOption.SelectedValue suggest to me that it refers, in fact, to a singular value, which would explain the behaviour you're seeing. chkServiceOption.SelectedValue的语义向我暗示,实际上,它指的是一个奇异值,它将解释您所看到的行为。 You'll probably need to loop through the items in the CheckBoxList and test whether each is checked. 您可能需要遍历CheckBoxList中的项目并测试是否已选中每个项目。 Try something like this: 尝试这样的事情:

string serviceOptionTxt = "";
for (int i = 0; i < chkServiceOption.Items.Count; i++)
{
    if (chkServiceOption.Items[i].Selected)
        serviceOptionTxt += chkServiceOption.Items[i].Value + " ";
        // Or possibly?
        //serviceOptionTxt += chkServiceOption.Items[i].Text + " ";
    }
}
mailBody = mailBody.Replace("##ServiceType##", serviceOptionTxt);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM