Simple list items validation (prevent duplicates) - c#

Hi currently I have code that get the value of of a list item and checks to see whether the value in this list (the value in a "Phone number" column) exists agains a value sugmitted by a HTML form. If the record to be entered into the list via this HTML form contains a Phone number that is already in the list, the record will not be added. This works well for the first item in the list, however when another item is added into the list with a different Phone number, the code does not seem to pick up the Phone number for the second record and so if a third record is entered with same Phone number as the second record the validation does not take place, the code keeps on looking at the first record. Here is a listing of my code:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(valueListURL))
{
using (SPWeb web = site.OpenWeb())
{
try
{
//--This is very important--
web.AllowUnsafeUpdates = true;
SPList list = web.Lists["Contact Requests"];
SPListItemCollection collsListItems = list.Items;
//Following lines of code added for validation
oreach (SPListItem objListItem in list.Items)
{
string valuePhonenumber = objListItem["Phone number"].ToString();
string valueEmailaddress = objListItem["Email address"].ToString();
SPListItem newItem = list.Items.Add();
if (TextBox3.Text != valuePhonenumber)
{
newItem["Contact name"] = TextBox1.Text;
TextBox1.Text = null;
newItem["Company"] = TextBox2.Text;
TextBox2.Text = null;
newItem["Phone number"] = TextBox3.Text;
this.TextBox3.Text = null;
newItem["Email address"] = TextBox4.Text;
TextBox4.Text = null;
newItem["Best time to call you"] = TextBox5.Text;
TextBox5.Text = null;
newItem["Enquiry subject"] = DropDownList1.SelectedItem;
this.DropDownList1.ClearSelection();
newItem["Enquiry details"] = TextBox6.Text;
this.TextBox6.Text = null;
if (RadioButton1.Checked)
newItem["Contact method"] = Label1.Text;
this.RadioButton1.Checked = false;
if (RadioButton2.Checked)
newItem["Contact method"] = Label2.Text;
this.RadioButton2.Checked = false;
newItem.Update();
}
//this.Response.Redirect(Request.RawUrl);
//Lines of code below used to insert or inject a javacript in order to close
//modeal dialog box at the press of the button
this.Page.Response.Clear();
this.Page.Response.Write("
<script type=text/javascript>window.frameElement.commonModalDialogClose(1, 1);</script>");
//this.Page.Response.Write("Submitted!"); //replacement for the above javascript
this.Page.Response.End();
}
}
catch (Exception doh)
{
DisplayError(doh);
}
}
}
});
I am thinking of using a foor loop to iterate throught the list items to check for exisiting Phone number records. I am think of putting the
if (TextBox3.Text != valuePhonenumber)
{
}
shown in the code above inside of a foor loop, but Im not sure on how to achieve this without breaking the code. Would be much appreciated if anyone could assist me with this!
Thanks in advance,
Update!!!
I am now using caml query to query the list for the required value in this case its the value entered on the HTML form into TextBox3.Text. The result of the qquery then gets stored in the object "listItemsCollection". I then use this perform a check so if the value in "TextBox3.text" is not equal to the value stored in "listItemsCollection" then the records get added to the list, if it is equal then the records does not get added. The code is listed below:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(valueListURL))
//using (SPSite site = new SPSite(webUrl))
{
using (SPWeb web = site.OpenWeb())
{
try
{
//added to resolve the issue with security validation on the page
//--This is very important--
web.AllowUnsafeUpdates = true;
SPList list = web.Lists["Contact Requests"]
SPQuery query = new SPQuery();
// try and find phone number we dont want to add in list
string camlquery = "<Where><Eq><FieldRef Name='Phone number'/>" + "<Value Type='Text'>"
+ TextBox3.Text + "</Value></Eq></Where>";
query.Query = camlquery;
SPListItemCollection listItemsCollection = list.GetItems(query);
if (TextBox3.Text != listItemsCollection.ToString()) // if it doesn't exist in list,
//we can add it records
{
SPListItem newItem = list.Items.Add();
// add code goes here
newItem["Contact name"] = TextBox1.Text;
TextBox1.Text = null;
newItem["Company"] = TextBox2.Text;
TextBox2.Text = null;
newItem["Phone number"] = TextBox3.Text;
this.TextBox3.Text = null;
newItem["Email address"] = TextBox4.Text;
TextBox4.Text = null;
newItem["Best time to call you"] = TextBox5.Text;
TextBox5.Text = null;
newItem["Enquiry subject"] = DropDownList1.SelectedItem;
this.DropDownList1.ClearSelection();
newItem["Enquiry details"] = TextBox6.Text;
this.TextBox6.Text = null;
if (RadioButton1.Checked)
newItem["Contact method"] = Label1.Text;
this.RadioButton1.Checked = false;
if (RadioButton2.Checked)
newItem["Contact method"] = Label2.Text;
this.RadioButton2.Checked = false;
newItem.Update();
}
//this.Response.Redirect(Request.RawUrl);
//Lines of code below used to insert or inject a javacript in order to close
//modeal dialog box at the press of the button
this.Page.Response.Clear();
this.Page.Response.Write("<script
type=text/javascript>window.frameElement.commonModalDialogClose(1, 1);</script>");
//this.Page.Response.Write("Submitted!"); //replacement for the above javascript
this.Page.Response.End();
}
catch (Exception doh)
{
DisplayError(doh);
}
}
}
});
I haven't done much with CAML before which is why I seem to be struggling whith something that should be so simple. Any sujestions to get this working will be hugely appreciated!
Many thanks in advance

You could achieve this using a CAML Query. You simply create a query where the phone number equals (or contains, depends on your requirements) the input from the HTML form. When you execute the query, a result set (SPListItemCollection) is returned. If this result set already contains an item, you know it's a duplicate and do not add a new item. Refer to this article if you haven't worked with CAML Queries yet:
http://sharepointmagazine.net/articles/writing-caml-queries-for-retrieving-list-items-from-a-sharepoint-list

I finally found what the problem was, after doing some reading apparently when dealing with CAML its seems better to provide the internal system name of the list column or field. In my case I was using 'Phone number' before which is why the whole thing was not working.
string camlquery = #"<Where>
<Eq>
<FieldRef Name='Phone_x0020_number'/>
<Value Type='Text'>" + TextBox3.Text + #"</Value>
</Eq>
</Where>";
query.Query = camlquery;
SPListItemCollection listItemsCollection = list.GetItems(query);
if (listItemsCollection.Count == 0) // if it doesn't exist in list, we can add it
{
}
But by simply providing the internal system name for the list column or field as shown above ('Phone_x0020_number'). The whole thing now works. After all this time breakingmy head, all that was required was the internal system name for the column.....

private bool TryGetItem(Guid key, string value, SPList list, out SPListItemCollection items)
{
SPQuery query = new SPQuery();
string #template = #"<Where>
<Eq>
<FieldRef Name='{1}'/>
<Value Type='Text'>{0}</Value>
</Eq>
</Where>";
query.Query = string.Format(#template, key.ToString("D"), value);
items = list.GetItems(query);
return items.Count > 0;
}

Related

Multiple combo boxes to query a data table issue

I'm putting together a project that has a form to fill out which then populates a query from a separate data table. It will always only grab one row based on the inputs, which is then used for a price calculation. I have two places in the code using the same setup. The first one uses a single combo box for the query and it works great, but the second part uses two combo boxes to make an "AND" query and I can't figure out why it isn't working, it doesn't seem to recognize the selections and place them into the calculation. Below is the code for that part, any help would be appreciated!
private void plant_AmountTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
try
{
plantamountResult = Convert.ToDecimal(plant_AmountTextBox.Text);
}
catch (Exception)
{
MessageBox.Show("Please enter a valid amount");
}
try
{
DataRowView rowviewpml = material_NameComboBox.SelectedItem as DataRowView;
materialNameSelection = "";
if (rowviewpml != null)
{
materialNameSelection = rowviewpml.Row["Material_Species"] as string;
}
DataRowView rowviewst = stockComboBox.SelectedItem as DataRowView;
stockSelection = "";
if (rowviewst != null)
{
stockSelection = rowviewst.Row["Stock_Type"] as string;
}
string mcSearch = "Material_Species = '" + materialNameSelection + "' AND Stock_Type = '" + stockSelection + "'";
Plant_Material_PricingTableAdapter pmpTA = new Plant_Material_PricingTableAdapter();
DataTable pmpDT = pmpTA.GetData();
DataRow[] pmpRow = pmpDT.Select(mcSearch);
foreach(DataRow row in pmpRow)
{
materialEstCost = Convert.ToDouble(pmpRow[0]["Previous_FY_Quotes"]);
}
plantestCostCalc.Text = "$" + ((decimal)materialEstCost * plantamountResult).ToString();
}
catch
{
plantestCostCalc.Text = "0";
}
}

filtered Query for objectContext Using Linq to SQL

i have tried to search some examples about my approach but all questions was not close enough to what i was trying to achieve .
for the TLDR sake , Question is : how do i make it work as in plain sql query?
using c# - Winforms with SqlCompact4 and Linq to SQL
my scenario involves a form with all the relevant Db table columns as availble filters to query
and then on text change event of each filtertextbox as a filter, the datasource of the gridview updates accordingly
and because i allow filtered search via many of them columns i was trying to avoid use of some extra
lines of code.
so lets say we only concentrate on 4 columns
custID, name, email, cellPhone
each has its corresponding TextBox.
i am trying to make a query as follows :
first i systematically collect all Textbox into a List
var AllFormsSearchFiltersTBXLst = new List<TextBox>();
code that collects all tbx on current form
var AllFormsSearchFiltersTBXLst = [currentFormHere].Controls.OfType<TextBox>();
so now i have all of textboxes as filters regardless if they have any value
then check who has some value in it
forech textbox in this filters textboxes if text length is greater than zero
it means that current filter is active
then.. a second list AllFormsACTIVESearchfiltersTBXLst will contain only active filters
what i was trying to achieve was in same way i didn't have to specify each of textbox objects
i just looped through each of them all as a collection and didn't have to specify each via it's id
now i want to make a filter on a dbContext using only those active filters
so i will not have to ask if current tbxName is email
like
query = db.Where(db=>db.email.Contains(TbxEmail.Text));
and again and again for each of 10 to 15 columns
what i have got so far is nothing that implements what i was heading to.
using (SqlCeConnection ClientsConn = new SqlCeConnection(ConfigurationManager.ConnectionStrings["Conn_DB_RCL_CRM2014"].ConnectionString))
{
System.Data.Linq.Table<ContactsClients> db = null;
// get all column names from context
var x =(System.Reflection.MemberInfo[]) typeof(ContactsClients).GetProperties();
using (DB_RCL_CRM2014Context Context = new DB_RCL_CRM2014Context(ClientsConn))
{
if (!Filtered)
db = Context.ContactsClients;//.Where(client => client.Name.Contains("fler"));
else
{
db = Context.ContactsClients;
// filters Dictionary contains the name of textBox and its value
// I've named TBX as Columns names specially so i could equalize it to the columns names when needed to automate
foreach (KeyValuePair<string,string> CurFltrKVP in FiltersDict)
{
foreach (var memberInfo in x)
{
// couldn't find out how to build the query
}
}
}
BindingSource BS_Clients = new BindingSource();
BS_Clients.DataSource = db;
GV_ClientInfo_Search.DataSource = BS_Clients;
what i normally do when working with plain sql is
foreach textbox take its value and add it into a string as filter
var q = "where " ;
foreach(tbx CurTBX in ALLFILTERTBX)
{
q +=CurTBX.Name +" LIKE '%" + CurTBX.Text + "%'";
// and some checking of last element in list off cores
}
then pass this string as a filter to the main select query ... that simple
how do i make it work as in plain sql query?
I think that you're trying to get the property of db dynamically, like: db.email according to the looped name of your textbox (here 'email'). However, I recommend you to do it some other way. I'd make a switch for each type of the property, like: email, name etc. Something like this:
// Create a list for the results
var results = new List<YourDBResultTypeHere>();
foreach(tbx CurTBX in ALLFILTERTBX)
{
switch(CurTBX.Name) {
case "email":
results.AddRange(db.Where(db => db.email.Contains(tbx.Text)).ToList());
break;
case "name":
results.AddRange(db.Where(db => db.name.Contains(tbx.Text)).ToList());
break;
}
}
try this
void UpdateGridViewData(bool Filtered=false, Dictionary<string,string> FiltersDict = null)
{
using (SqlCeConnection ClientsConn = new SqlCeConnection(ConfigurationManager.ConnectionStrings["Conn_DB_RCL_CRM2014"].ConnectionString))
{
System.Data.Linq.Table<ContactsClients> db = null;
IEnumerable<ContactsClients> IDB = null;
BindingSource BS_Clients = new BindingSource();
System.Reflection.MemberInfo[] AllDbTblClientsColumns = (System.Reflection.MemberInfo[])typeof(ContactsClients).GetProperties();
using (DB_RCL_CRM2014Context Context = new DB_RCL_CRM2014Context(ClientsConn))
{
if (!Filtered)
{
db = Context.ContactsClients;
BS_Clients.DataSource = db;
}
else
{
string fltr = "";
var and = "";
if (FiltersDict.Count > 1) and = "AND";
for (int i = 0; i < FiltersDict.Count; i++)
{
KeyValuePair<string, string> CurFltrKVP = FiltersDict.ElementAt(i);
if (i >= FiltersDict.Count-1) and = "";
for (int j = 0; j < AllDbTblClientsColumns.Length; j++)
{
if (AllDbTblClientsColumns[j].Name.Equals(CurFltrKVP.Key))
{
fltr += string.Format("{0} Like '%{1}%' {2} ", AllDbTblClientsColumns[j].Name, CurFltrKVP.Value, and);
}
}
}
try
{
IDB = Context.ExecuteQuery<ContactsClients>(
"SELECT * " +
"FROM ContactsCosmeticsClients " +
"WHERE " + fltr
);
BS_Clients.DataSource = IDB;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
GV_ClientInfo_Search.DataSource = BS_Clients;
}
}
}

CAML query to get items from SPList

I wanted to update the Name field in a list which contain 'finance' in the department list. I wrote the following code but it updates every item in the Name column whether it contains 'finance' or not.
What am i doing wrong?
SPListItemCollection Items = RiskAssesment.GetItems(new SPQuery()
{
Query = #"<where>
<Eq>
<FiledRef Name 'Department'/>
<Value Type='Text'>Finance </Value>
</Eq>
</Where>"
});
foreach (SPListItem item in Items)
{
item["Name"] = "abcdef";
item.Update();
}
FiledRef should be FieldRef. And you forgot the equal sign, it should be like this:
<FieldRef Name='Department' />
Small edit:
I'm not sure if CAML is case-sensitive, but in case it is: change the opening-where to <Where>.
SPListItemCollection Items = RiskAssesment.GetItems(new SPQuery()
{
Query = #"<Where>
<Eq>
<FieldRef Name='Department'/>
<Value Type='Text'>Finance </Value></Eq></Where>"
});
foreach (SPListItem item in Items)
{
item["Name"]="abcdef";
item.Update();
}
The below function get the folder name and id of subfolder where items stored
folder = item.folder.
Initially it will be null.
static string GetParentFolder(SPListItem itemToFind, SPFolder folder)
{
SPQuery query = new SPQuery();
// query.Query = "<OrderBy><FieldRef Name='Title'/></OrderBy>";
query.Query = "<Where><Eq><FieldRef Name=\"ID\"/><Value Type=\"Integer\">"+ itemToFind.ID +"</Value></Eq></Where>";
query.Folder = folder;
query.ViewAttributes = "Scope=\"Recursive\"";
SPListItemCollection items = itemToFind.ParentList.GetItems(query);
int intpartentFolderID=0 ;
if (items.Count > 0)
{
foreach (SPListItem item in items)
{
SPFile f = item.Web.GetFile(item.Url);
string test11 = f.ParentFolder.Name;
intpartentFolderID = f.ParentFolder.Item.ID;
//string test1 = item.File.ParentFolder.Name;
return (intpartentFolderID.ToString());
}
}
return (intpartentFolderID.ToString());
}
So I just came across this older post, and I don't have enough reputation to comment on the selected answer.
But I know that when using CAML is definitely case sensitive in SharePoint 2013.
Just means that the opening <where> should be <Where>.
Hope you got your issue solved!
The below function get the folder name and id of subfolder where items stored
folder = item.folder.
Initially it will be null.
static string GetParentFolder(SPListItem itemToFind, SPFolder folder)
{
SPQuery query = new SPQuery();
// query.Query = "<OrderBy><FieldRef Name='Title'/></OrderBy>";
query.Query = "<Where><Eq><FieldRef Name=\"ID\"/><Value Type=\"Integer\">"+ itemToFind.ID +"</Value></Eq></Where>";
query.Folder = folder;
query.ViewAttributes = "Scope=\"Recursive\"";
SPListItemCollection items = itemToFind.ParentList.GetItems(query);
int intpartentFolderID=0 ;
if (items.Count > 0)
{
foreach (SPListItem item in items)
{
SPFile f = item.Web.GetFile(item.Url);
string test11 = f.ParentFolder.Name;
intpartentFolderID = f.ParentFolder.Item.ID;
//string test1 = item.File.ParentFolder.Name;
return (intpartentFolderID.ToString());
}
}
return (intpartentFolderID.ToString());
}
Thanks
Deva- Cheraideva

google calendar api asp.net c# delete event

i have this function
private static void DeleteEvent(CalendarService service, string pTitle,DateTime pDate)
{
FeedQuery query = new FeedQuery();
query.Uri = new Uri("http://www.google.com/calendar/feeds/default/private/full");
AtomFeed calFeed = service.Query(query);
foreach (AtomEntry entry in calFeed.Entries)
{
if (pTitle.Equals(entry.Title.Text))
{
entry.Delete(); break;
}
}
}
how i can delete a event by title and date ?
These might help:
http://code.google.com/apis/calendar/data/2.0/developers_guide_dotnet.html#DeletingEvents
http://code.google.com/apis/calendar/data/2.0/developers_guide_dotnet.html#RetrievingEvents
I'd guess something like the following might work:
EventQuery query = new EventQuery("https://www.google.com/calendar/feeds/default/private/full");
query.StartDate = ...;
query.EndDate = ...;
EventFeed feed = service.Query(query);
foreach (var entry in feed.Entries)
{
if (pTitle.Equals(entry.Title.Text))
{
entry.Delete(); break;
}
}
Although the above solution will work but I would suggest another approach. Instead of traversing all the events every time and deleting if found, why not ask Google to find the specific event for you. It can be done by using ExtendedProperty using the approach below
Assign an ID (same as you set in your DB) to each event you add.
When deleting you pass the ID to delete and use Query to fetch it for you
Delete the specific event
Google.GData.Calendar.EventEntry Entry = new Google.GData.Calendar.EventEntry();
//create the ExtendedProperty and add the EventID in the new event object,
//so it can be deleted / updated later
ExtendedProperty oExtendedProperty = new ExtendedProperty();
oExtendedProperty.Name = "EventID";
oExtendedProperty.Value = GoogleAppointmentObj.EventID;
Entry.ExtensionElements.Add(oExtendedProperty);
string ThisFeedUri = "http://www.google.com/calendar/feeds/" + CalendarID
+ "/private/full";
Uri postUri = new Uri(ThisFeedUri);
//create an event query object and attach the EventID to it in Extraparameters
EventQuery Query = new EventQuery(ThisFeedUri);
Query.ExtraParameters = "extq=[EventID:" + GoogleAppointmentObj.EventID + "]";
Query.Uri = postUri;
//Find the event with the specific ID
EventFeed calFeed = CalService.Query(Query);
//if search contains result then delete
if (calFeed != null && calFeed.Entries.Count > 0)
{
foreach (EventEntry SearchedEntry in calFeed.Entries)
{
SearchedEntry.Delete();
break;
}
}

adding a user to a list programmatically

i have a list which is being populated from a program that takes user input, i am having a problem when it comes to adding a person or group to one of the columns in the list. does anybody know how to do this?
have a look at this article: http://blogs.msdn.com/b/uksharepoint/archive/2009/02/17/quick-tip-using-the-sharepoint-person-or-group-field-in-code-part-1.aspx
it shows you how to use it:
Console.WriteLine("Enter a ; delimited list of domain\alias that need to be added:");
string sAliases = Console.ReadLine(); //captures whatever the user entered
string sValueToAddToFieldInSP = ""; //used to build the full string needed for the person field
string sAllContacts = "";
using (SPSite site = new SPSite(“http://sites/site/yoursite”))
{
site.AllowUnsafeUpdates = true;
using (SPWeb web = site.RootWeb)
{
web.AllowUnsafeUpdates = true;
string[] aAliases = sAliases.Split(';');
foreach (string sAlias in aAliases)
{
SPUser user = web.EnsureUser(sAlias);
sAllContacts += user.ID.ToString() + ";#" + user.LoginName.ToString() + ";#";
}
web.Update();
}
}
if (sAllContacts.EndsWith(";#"))
{
sAllContacts = sAllContacts.Substring(0, sAllContacts.Length - 2);
}
//add the list item
SPList l = web.Lists["<name of your list>"];
SPListItem li= l.Items.Add();
li["Title"] = sAllContacts ;
li["MyPerson"] = sAllContacts ;
li.Update();
Console.WriteLine("Done");

Categories

Resources