Use Foreach loop in MVC - c#

How can I process the foreach loop in MVC. In the bellow controller I am calling a method called SendSimpleMessage() which sends an email to its parameter input but on my controller I am unable to use foreach properly.
[HttpPost]
public ActionResult EmailCampaignProcess(FormCollection collection)
{
//var userType = Request["userType"];
//var emailContent = Request["emailContent"];
//SendSimpleMessage();
//ViewBag.Message = "Hello " + Request["userType"];
var Emails = db.Users.Where(d => d.Subscriptions.Any(x => x.Status == true)).Select(u => u.Email).ToArray();
foreach (Emails as Email) {
SendSimpleMessage(Email);
}
}

Your code is wrong, a foreach loop should look like
foreach (var currentEmail in Emails) { //where var can be your Class maybe Email
SendSimpleMessage(currentEmail);
}
Generally a foreach looks like:
foreach(T objectName in YourCollection){
//T is your class
//objectName is the way you access the object within your loop
//in references the list
//YourCollection is IEnumerable<T>
}

Defintion of ForEach Statement
The for each statement is used to iterate through a collection. You can modify elements in a collection, but you cannot add or delete elements.The statements are executed for each element in the array or collection. After the iteration has been completed for all the elements in the collection, control is transferred to the statement that follows the for each block
Syntax:
for each (type identifier in expression)
{
statements
}
Parameters type
The type of identifier.
identifier
The iteration variable that represents the collection element. When identifier is a Tracking Reference Operator, you can modify the element.
expression
An array expression or collection. The collection element must be such that the compiler can convert it to the identifier type.
statements
One or more statements to be executed.
Simple Example:
string[] countries = { "india", "US", "UK" };
foreach (string value in countries )
{
Console.WriteLine(value);
}
In the same way your code will change like below:
[HttpPost]
public ActionResult EmailCampaignProcess(FormCollection collection)
{
//var userType = Request["userType"];
//var emailContent = Request["emailContent"];
//SendSimpleMessage();
//ViewBag.Message = "Hello " + Request["userType"];
var Emails = db.Users.Where(d => d.Subscriptions.Any(x => x.Status == true)).Select(u => u.Email).ToArray();
foreach (string SingleEmail in Emails) {
SendSimpleMessage(SingleEmail);
}
// Or if you are not sure about the outcome type you can use the var keyword like below
foreach (var SingleEmail in Emails) {
SendSimpleMessage(SingleEmail);
}
}
Hope the above information was helpful

Related

Variable in foreach loop does not exist outside the loop

Sorry, this is pretty basic but for the life of me I have not been able to solve it:
I have this:
public static IHtmlString HrefLangLinks(this PageData currentPage)
{
var availablePageLanguages = currentPage.ExistingLanguages.Select(culture => culture.Name).ToArray();
foreach (string listitem in availablePageLanguages)
{
var Output = string.Join(",", listitem);
}
// Dictionary<String, String>
return new HtmlString(Output.ToString());
}
I would like to get the results of the foreach loop outputted in the return value. But Visual Studio informs me that "Output" (the instance in my return value) does not exist in the current context.
I thought I could solve this by adding var Output =""; outside of my foreach loop but that did not work.
Define Output before going into the foreach loop and then assign it a value:
var Output = "";
foreach (string listitem in availablePageLanguages)
{
Output = string.Join(",", listitem);
}
Apart from that I wonder if you really need a for loop in this case as you should also be able to this at once if availablePageLanguages is an array of string (string[]):
var Output = String.Join(" ", availablePageLanguages));

Use enumerations extension methods to shorten code

I want to checkmark some listview items from a given array. How could the code below be shortend with enumeration extension methods.
foreach (Team SelectedTeam in value.Teams)
{
foreach (ListViewItem LVItem in TeamLstVw.Items)
{
Team Team = (Team)LVItem.Tag;
if (SelectedTeam.Equals(Team))
LVItem.Selected = true;
}
}
You could eradicate the outer foreach loop, by using Linq methods inside the inner foreach loop. In this case, you could just check if the current LVItem.Tag is contained inside value.Teams
foreach (ListViewItem LVItem in TeamLstVw.Items)
{
var Team = (Team)LVItem.Tag;
//I'd personally compare an identifier here. Like an Id property
//.Any(x => x.Id == Team.Id)
//Or use .Contains(): value.Teams.Contains(Team)
if(value.Teams.Any(x => x == Team)) {
LVItem.Selected = true;
}
}

Column name included in each list/array item (LINQ CSV reader)

I am using this CSV reader in attempt to print out Name, lastname and SSN from my CSV file:
static void Main(string[] args)
{
var query = File.ReadLines(#"C:\CSV\ToAdd.csv")
.SelectMany(line => line.Split(';'))
.Where(csvLine => !String.IsNullOrWhiteSpace(csvLine))
.Select(csvLine => new { data = csvLine.Split(',') })
.Select(s => new
{
Name = s.data[0],
Lastname = s.data[1],
SSN = s.data[2]
});
foreach (var item in query)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
So far I have had a bit of success, but the problem is it keeps printing out the name of the column as well:
{ Name = Hej, Lastname = Hoj, SSN= 950505-1432 }
{ Name = Huj, Lastname = Hij, SSN= 940304-1332 }
which part of the code is making it so it gets printed out like that instead of printing out only the records?
When you print it this way:
foreach (var item in query)
{
Console.WriteLine(item);
}
It uses the ToString() implemented by .Net for anonymous types generated by the compiler. It's implementation is to print the data in that format of property name + value.
When you want to do instead is give a specific format for when printing:
Using String Interpolation of C# 6 (which is just syntactic sugar
for string.Format) you can do it like this:
foreach (var item in query)
{
Console.WriteLine($"{item.Name} {item.Lastname}, {item.SSN}");
}
Using another overload of the Console.WriteLine:
foreach (var item in data)
{
Console.WriteLine("{0} {1}, {2}",item.Name, item.Lastname, item.SSN);
}
3.Or if you project to a defined type and not an anonymous type you can override the ToString of the object and then your code from the question will work

Updating sort column in ASP.NET with Request.QueryString Array

I'm passing a list of guids in a GET request from a JQuery Ajax call.
on my ASP.NET controller side I want to iterate through the list and update the Display_Sort column to match my newly sorted list.
My ID is a Guid and I'm getting a type error in the following code, because it's a string that I'm passing to the Db. However, I can't seem to convert the item(string) into a Guid.
I've tried Guid(item) and it would allow the constructor. Not sure what I'm missing.
Here is the code:
//REORDER HOME ASSETS
public ActionResult ReOrderHome()
{
using (var db = new IFEntities())
{
var myString = Request.QueryString;
var i = 1;
foreach (var item in myString)
{
var myObj = db.HomeContents.Find(item);
myObj.display_order = i;
db.SaveChanges();
i++;
}
}
You can convert item to GUID and then compare like this.
var myObj = db.HomeContents.Find(new Guid(item));
Or, you can use select instead of find. Syntax for select --
foreach (var item in myString)
{
var myObj = db.HomeContents.Select(p => p.<GUID_COLUMN_NAME> == item);
myObj.display_order = i;
db.SaveChanges();
i++;
}
Replace GUID_COLUMN_NAME with actual column name.

C# Linq to XML - Return multiple children

I have this xml:
<?xml version="1.0" encoding="utf-8" ?>
<Interfaces>
<Interface>
<Name>Account Lookup</Name>
<PossibleResponses>
<Response>Account OK to process</Response>
<Response>Overridable restriction</Response>
</PossibleResponses>
</Interface>
<Interface>
<Name>Balance Inquiry</Name>
<PossibleResponses>
<Response>Funds available</Response>
<Response>No funds</Response>
</PossibleResponses>
</Interface>
</Interfaces>
I need to retrieve the possible responses for an interface:
// Object was loaded with XML beforehand
public class Interfaces : XElement {
public List<string> GetActionsForInterface(string interfaceName) {
List<string> actionList = new List<string>();
var actions = from i in this.Elements("Interface")
where i.Element("Name").Value == interfaceName
select i.Element("PossibleResponses").Element("Response").Value;
foreach (var action in actions)
actionList.Add(action);
return actionList;
}
}
The result should be a list such as this (for interface 'Account Lookup'):
Account OK to process
Overridable restriction
But its only returning the first value - 'Account OK to process'. What is wrong here?
Edit:
I changed my method:
public List<string> GetActionsForInterface(string interfaceName) {
List<string> actionList = new List<string>();
var actions = from i in this.Elements("interface")
where i.Element("name").Value == interfaceName
select i.Element("possibleresponses").Elements("response").Select(X => X.Value);
foreach (var action in actions)
actionList.Add(action);
return actionList;
}
But now I get 2 errors on line 'actionList.Add(action);':
The best overloaded method match for System.Collections.Generic.List<string>.Add(string)' has some invalid arguments
Argument 1: cannot convert from 'System.Collections.Generic.IEnumerable<char>' to 'string'
I suppose the select many is casting the results into something else then strings?
Edit:
To fix the last error:
foreach (var actions in query)
foreach(string action in actions)
actionList.Add(action);
Apparently there is an array within an array here.
This
select i.Element("PossibleResponses").Element("Response")
returns the first "response" element. Use Elements instead.
You then need to select many to get the values.
doc.Root.Elements("Interface").Select(e=>new {
Name = e.Element("Name").Value,
PossibleResponses = e.Element("PossibleResponses").Elements("Response").select(e2=>e2.Value)
});
static List<string> GetActionsForInterface(string interfaceName)
{
var doc = XDocument.Parse(xml);
List<string> actionList = new List<string>();
var actions = doc.Root
.Elements("Interface")
.Where(x => x.Element("Name").Value == interfaceName).
Descendants("Response").Select(x => x.Value);
foreach (var action in actions)
actionList.Add(action);
return actionList;
}

Categories

Resources