I've a Repeater and I need paging, so I'm using PagedDatasource.
Given:
string tag = Request.QueryString["category"];
and tag variable is NOT empty then PagedDataSource fails paging with the following error:
Exception Details: System.Web.HttpException: Cannot compute Count for
a data source that does not implement ICollection.
at this line:
lblCurrentPage.Text = "Page: " + (CurrentPage + 1).ToString() + " of " + pagedDS.PageCount.ToString();
NOTE: When tag variable IS empty then paging works fine.
Full code below:
string tag = Request.QueryString["category"];
var ba = new DataBase.BlogAdapter();
PagedDataSource pagedDS = new PagedDataSource();
pagedDS.AllowPaging = true;
pagedDS.PageSize = 3;
if (String.IsNullOrEmpty(tag))
{
pagedDS.DataSource = ba.GetArticles(null, null);
}
else
{
var t = new DataBase.Tag() { TagName = tag };
var tec = new DataBase.TagEqualityComparer();
pagedDS.DataSource = ba.GetArticles(null, null).Where(a => a.Tags.Contains(t, tec));
CurrentPage = 0;
}
pagedDS.CurrentPageIndex = CurrentPage;
// NEXT LINE FAILS IF "tag" IS NOT EMPTY
lblCurrentPage.Text = "Page: " + (CurrentPage + 1).ToString() + " of " + pagedDS.PageCount.ToString();
You probably need to materialise the filter as a collection, e.g.
ba.GetArticles(null, null).Where(a => a.Tags.Contains(t, tec)).ToList();
IQueryable<> only implements IEnumerable, whereas IList<> implements ICollection.
Related
I created a dot.net form that uses c# code to retrieve members of an Active Directory group that a user selects from a drop-down, then displays the list of members (users is all I want) on the web page.
This works fine for groups that DO NOT contain sub-groups. When an Active Directory group contains users and sub-groups I receive an error.
I only want users of the group that the users selects from the drop-down. I don't want users from any sub-groups.
I have done lots of searching on the internet and testing various code suggestions.
public List<string> GetAllUsersFromGroup(string domain,
string group)
{
List<string> retVal = new List<string>();
DirectoryEntry entry = new DirectoryEntry(domain);
DirectorySearcher searcher = new DirectorySearcher("
(&(objectCategory=Group)(cn=" + group + "))");
searcher.SearchRoot = entry;
searcher.SearchScope = SearchScope.Subtree;
SearchResult result = searcher.FindOne();
var x = 0;
var txtCN = "";
var txtDispName = "";
var firstItem = 0; // Display Name
var secondItem = 1; // CN
var arraryResultsSize = result.Properties["member"].Count;
string[] deResultsArray = new string[arraryResultsSize];
foreach (string member in result.Properties["member"])
{
DirectoryEntry de = new DirectoryEntry(String.Concat(domain,
"/", member.ToString()));
if (de.Properties["objectClass"].Contains("user") &&
de.Properties["cn"].Count > 0)
{
deResultsArray[x] = de.Properties["displayName"]
[0].ToString() + "~" + de.Properties["cn"]
[0].ToString();
}
x = x + 1;
}
if (deResultsArray[0] != null) {
string[] sortSeperatedItems = sortLDAPUsers(deResultsArray);
for (var i = 0; i < sortSeperatedItems.Length/2; i++) {
txtDispName = "<tr><td>" + sortSeperatedItems[firstItem]
+ "</td>";
txtCN = "<td>" + sortSeperatedItems[secondItem] + "</td>
</tr>";
retVal.Add(txtDispName);
retVal.Add(txtCN);
firstItem = firstItem + 2;
secondItem = secondItem + 2;
}
} else {
txtDispName = "<tr><td>Group has no members</td>";
txtCN = "<td> </td></tr>";
retVal.Add(txtDispName);
retVal.Add(txtCN);
}
// retVal.Add("Array Size is: " + propCount);
return retVal;
}
public string[] sortLDAPUsers(string[] strArray) {
Array.Sort(strArray);
var newArraySize = (strArray.Length * 2);
string[] itemSeperated = new string[2];
string[] allSepItems = new string[newArraySize];
var arrayItemsString = "";
var xDName = 0;
var xCName = 1;
for (var i = 0; i < strArray.Length; i++) {
itemSeperated = strArray[i].Split('~');
allSepItems[xDName] = itemSeperated[0];
allSepItems[xCName] = itemSeperated[1];
arrayItemsString = arrayItemsString + "Length of allSepItems
is: " + allSepItems.Length + " Text is: " +
allSepItems[xDName] + " NetId is: " + allSepItems[xCName] +
"<br><br>";
xDName = xDName + 2;
xCName = xCName + 2;
}
return allSepItems;
}
When user selects an Active Directory group that contains users and sub-group(s), I receive the following error:
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 205: for (var i = 0; i < strArray.Length; i++) {
Line 206:
Line 207: itemSeperated = strArray[i].Split('~');
Line 208: allSepItems[xDName] = itemSeperated[0];
Line 209: allSepItems[xCName] = itemSeperated[1];
I think the error has to do with how I'm filtering or getting results in GetAllUsersFromGroup(). I don't know how to just get users from a group and not include any sub-group(s) in the results.
The problem with this filter (&(objectCategory=Group)(cn=<group>)) is that you are querying a specific group to iterate and grab all its members regardless of the type/objectClass, so you are left with users, groups and whatever.
Instead, you can request users that are members of this group directly using the proper filter :
new DirectorySearcher("(&(objectCategory=person)(memberOf=" + groupDN + "))");
Note that the memberOf attribute must match a DN, so given the passed in variable group (if the caller can't pass the actual group dn) you may have to grab it in the first place using the 1st filter.
The error you get then is another issue due to sorting, maybe comment this part until you get the proper results.
You do not need to work that hard when you could let Microsoft Active Directory do the work.
An LDAP search request with an LDAP filter to Resolve all members (including nested) Security Groups (requires at least Windows 2003 SP2)
(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=CN=GroupOne,OU=Security Groups,OU=Groups,DC=YOURDOMAIN,DC=NET)
This will return all (objectClass=user) that are members of the "GroupOne".
I've created a dynamic webpage using strictly html, javascript, and MS Access. While it was functional, locally, there were complications deploying it. Since I have ported the data to MySQL and am trying to use Visual Studio's aspx.cs to do much of what the javascript did previously.
I have a screen that populates a dynamic set of rows based on a query result (two rows per record for aesthetics), one of the cells contains a drop down menu(html select/ asp:ListBox).
When I had everything only on javascript, I could create the cell, then create its contents, then set the selected value using:
document.getElementById("StatusDD" + rowCount).value = reader.GetValue(i);
From what I've gathered so far, the rough equivalent is:
ListItem li = StatusDD1.Items.FindByValue(reader.GetValue(i));
li.Selected = true;
However, I cannot simply hardcode StatusDD1 thru StatusDDx (for one, at the beginning my hardcoded set might be larger than the number of records returned, and two eventually the rows returned will be larger than the set of hardcoded values).
So what I did was I created the following function:
protected void setSelected(string selectId, string value)
{
/*Need to put something here to make the following work*/
selectId.Items.FindByValue(value).Selected = true;
}
The selectId being passed in is the name/id of the ListBox and the value is the value coming back from the query.
It's called like:
setSelected("StatusDD" + rowCount, (string)reader.GetValue(i));
If I could, for lack of better phrase, materialize the name created by "StatusDD"+rowCount, I could pass that name in as if I was passing in a ListBox, rather than a string.
Alternatively, if there was a way to select the ListBox from an array where I could do a conditional check WHERE/IF ListBox.Name = selectId, something like the following PseudoCode:
ListBox a = ListBox.NameMatches(selectId);
a.Items.FindByValue(value).Selected = true;
Currently ListBoxes are being created by defining the box in a string and then passing that string into an HtmlTableCell:
HtmlTable myTable = new HtmlTable();
HtmlTableRow newRow;
string cellId;
string cellContents;
int rowCount = 1;
string statusDisabled = "";
while (reader.Read()){
newRow = new HtmlTableRow();
myTable.Rows.Add( newRow );
...
...
cellContents = "<asp:ListBox name='StatusDD" + rowCount + "' id='StatusDD" + rowCount + "' style='width:100%; " + statusDisabled + "' value='" + reader.GetValue(i) + "' onchange='markNeedSave(" + (rowCount + 1) + ")'><asp:ListItem value='0'></asp:ListItem><asp:ListItem value='1'>New</asp:ListItem>....asp:ListBox>";
newRow.Cells.Add(new HtmlTableCell{InnerHtml = cellContents});
}
If it helps, here's how I had it working in javascript:
while (!rs.EOF) {
rowa = table.insertRow(rowCount);
rowa.id = "RECORD" + rowCount + "a";
cell = rowa.insertCell(i + 1);
cell.id = "RECORD" + rowCount + "_CELL" + (i + 1);
for (i = 0; i < 8; i++) {
cell.innerHTML = "<select name='StatusDD" + rowCount + "' id='StatusDD" + rowCount + "' style='width:100%' value='" + rs.fields(i).value + "' onchange='markNeedSave(" + (rowCount + 1) + ")'><option value='NONE'></option><option value='New'>New</option>...</select>";
if (readonly) {
document.getElementById("StatusDD" + rowCount).disabled = true;
}
document.getElementById("StatusDD" + rowCount).value = rs.fields(i).value;
}
...
}
OK, got the ListBox to work, but as I was researching, and when I finally got it to work, I discovered that what I wanted was the DropDownList, not the ListBox, but the same fixes needed to be done in order to get either to work.
I use the following function now:
protected void setSelected(string selectId, string value)
{
PlaceHolder TCS = Page.FindControl("TestingCS") as PlaceHolder;
DropDownList ddl = TCS.FindControl(selectId) as DropDownList;
if (ddl != null)
{
ddl.SelectedValue = value;
ListItem item = ddl.Items.FindByValue(value);
if(item != null)
{ item.Selected = true;}
}
}
Also, for my cell contents that just contain data using the following is fine:
cellContents = "<someString>";
newRow.Cells.Add(new HtmlTableCell{InnerHtml = cellContents});
but for my drop down (or list box) I need to use:
cell = new HtmlTableCell();
newRow.Cells.Add(cell);
DropList = new DropDownList();
DropList.ID = "StatusDD" + rowCount;
DropList.Items.Add(new ListItem("", "0"));
DropList.Items.Add(new ListItem("New", "1"));
...
cell.Controls.Add(DropList);
setSelected(DropList.ID, (string)(reader.GetValue(i)));
A smoother solution:
protected void setSelected(DropDownList ddl, string value)
{
ListItem item = ddl.Items.FindByValue(value);
if (item != null)
{ item.Selected = true; }
}
...
protected void accessRecord()
{
...
DropList = new DropDownList();
DropList.ID = "StatusDD" + rowCount;
DropList.Attributes["onChange"] = "javascript:markNeedSave(" + rowCount + ");";
DropList.Items.Add(new ListItem("", "0"));
DropList.Items.Add(new ListItem("New", "1"));
...
cell.Controls.Add(DropList);
setSelected(DropList,(string)reader.GetValue(i));
}
...
It sounds like the function you're looking for is FindControl. This can be used from the Page, or any parent control you might have created to hold your output.
An example implementation of your setSelected method might look like this:
protected void SetSelected(string selectId, string value)
{
var lb = Page.FindControl(selectId) as ListBox;
if (lb != null)
{
var item = lb.Items.FindByValue(value)
if(item != null)
item.Selected = true;
}
}
this my code
private DataTable ParseTable(string html)
{
HtmlDocument doc = new HtmlDocument();
DataTable dt = new DataTable();
String[] datasc;
String[] valueTemp = new String[30];
int index;
doc.LoadHtml("<table><tr><td><p><input id=\"ControlGroupScheduleSelectView_AvailabilityInputScheduleSelectView_RadioButtonMkt1Fare7\" type=\"radio\" name=\"ControlGroupScheduleSelectView$AvailabilityInputScheduleSelectView$market1\" value=\"0~N~~N~RGFR~~1~X|QG~ 885~ ~~BTH~05/19/2014 07:00~KNO~05/19/2014 08:20~\" />Rp.445,000 ( N/Cls;4 )</p></td></tr></table>");
for (int z = 0; z < 4; z++)
{
var getInputSchedule = doc.DocumentNode.SelectNodes("//table//input");
datasc = new String[getInputSchedule.Count];
for (int i = 0; i < getInputSchedule.Count; i = i+1)
{
string removeClassFare = string.Empty;
String[] selectValueSplit = getInputSchedule[i].Attributes["value"].Value.Split('|');
valueTemp[i] = selectValueSplit[1];
String[] getAlphaSC = selectValueSplit[0].Split('~');
try
{
index = getInputSchedule[i].ParentNode.InnerText.IndexOf("(");
if (index != -1)
{
removeClassFare = getInputSchedule[i].ParentNode.InnerText.Substring(0, index);
removeClassFare = System.Text.Encoding.ASCII.GetString(System.Text.Encoding.ASCII.GetBytes(removeClassFare)).Replace("??", "").Replace("Rp.", "").Trim();
}
}
catch (Exception e) {
//removeClassFare = getInputSchedule[i].ParentNode.InnerText;
}
if (!dt.Columns.Contains(getAlphaSC[1]))
{
dt.Columns.Add(getAlphaSC[1], typeof(string));
}
if (i == 0)
{
datasc[i] = "<div align=\"center\"><input <input onclick='faredetail(this.value, this.name)' id=\"" + getInputSchedule[i].Attributes["id"].Value + "\" type=\"radio\" value=\"" + getInputSchedule[i].Attributes["value"].Value + "\" name=\"" + getInputSchedule[i].Attributes["name"].Value + "\"><br>" + removeClassFare + "</div>";
}
else
{
if (selectValueSplit[1].Equals(valueTemp[i - 1],StringComparison.Ordinal))
{
datasc[i] = "<div align=\"center\"><input <input onclick='faredetail(this.value, this.name)' id=\"" + getInputSchedule[i].Attributes["id"].Value + "\" type=\"radio\" value=\"" + getInputSchedule[i].Attributes["value"].Value + "\" name=\"" + getInputSchedule[i].Attributes["name"].Value + "\"><br>" + removeClassFare + "</div>";
}
else
{
break;
}
}
getInputSchedule[i].Remove();
}
datasc = datasc.Where(x => !string.IsNullOrEmpty(x)).ToArray();
dt.Rows.Add(datasc);
}
return dt;
}
if i run, error message "Object reference not set to an instance of an object.", but if i remove the ID of element like
doc.LoadHtml("<table><tr><td><p><input type=\"radio\" name=\"ControlGroupScheduleSelectView$AvailabilityInputScheduleSelectView$market1\" value=\"0~N~~N~RGFR~~1~X|QG~ 885~ ~~BTH~05/19/2014 07:00~KNO~05/19/2014 08:20~\">Rp.445,000 ( N/Cls;4 )</p></td></tr></table>");
Everything works ok.
Why does the ID attribute cause my XPath to fail?
pleasee..help..
thank you
I stand corrected. SelectNodes does return null if it can't find any nodes.
But the behavior you are witnessing has nothing to do with the id attribute (in fact, removing the id attribute causes an exception to happen sooner), and everything to do with your code.
At the end of your inner loop, you are doing this:
getInputSchedule[i].Remove();
which removes the <input> element from the HTML document.
Your outer loop is set up to execute four times, so the second time it executes, the input element is already gone, and doc.DocumentNode.SelectNodes("//table//input") returns null, and that is the cause of your error.
I'm not really sure why you're removing the input elements from the document as you go through it, or why you're looping through the whole thing 4 times, but hopefully that gets you going in the right direction.
I'm trying to achieve the same thing as this poster and I'm following what one of the answers says I need to do.
Here is my method
public void DisplayItemRangeForCurrentPage()
{
var totalRecords = ((DataView)gvMagicalSearchResults.DataSource).Count;
var endRecord = gvMagicalSearchResults.PageSize * (gvMagicalSearchResults.PageIndex + 1);
var startsRecods = endRecord - gvMagicalSearchResults.PageSize;
if (endRecord > totalRecords)
endRecord = totalRecords;
if (startsRecods == 0) startsRecods = 1;
if (endRecord == 0) endRecord = totalRecords;
var str = new StringBuilder();
str.Append((string)HttpContext.GetGlobalResourceObject("magicalResx", "GrivSearchCountMessage_Shows"));
str.Append(" " + startsRecods + " - " + endRecord + " ");
str.Append((string)HttpContext.GetGlobalResourceObject("magicalResx", "GrivSearchCountMessage_OfTotal"));
str.Append(" " + totalRecords + " ");
ltrResultsCount.Text = str.ToString();
}
No matter where I call this method it throws an "Object not set to an instance of an object" error on the var totalRecords = ((DataView)gvMagicalSearchResults.DataSource).Count; line.
I tried calling it in several GridView/ObjectDataSource events. I tried calling it in PreRender, OnLoad, Render - Alas, none of them worked...
So can anyone tell me where in the event cycle a gridview gets its datasource?
It happens on the GridView.OnDataBound:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.basedataboundcontrol.databound%28v=vs.90%29.aspx
Using the C# Facebook SDK 5.0.3 everything works fine whit the client.Get("/me").
But when retrieving the status, I should get aan arraylist "data" with all the status messages according to the facebook Graph API, but instead my data array is empty and I get a 'Index out of bounds' exception.
Does anyone have an idea what my problem could be?
if (Request.Params["code"] != null)
{
var client = new FacebookClient(GetAccessToken());
dynamic me = client.Get("/me");
imgUser.ImageUrl = "https://graph.facebook.com/" + me.id + "/picture";
lblUsername.Text = me.name;
lblHometown.Text = me.hometown.name;
lblBirthday.Text = me.birthday;
lblCurrenttown.Text = me.location.name;
lblEmail.Text = me.email;
lblOpleidingen.Text = "";
lblOpleidingen.Text += me.education[1].type + ": " + me.education[1].school.name + ", " + me.education[1].year.name + "<br />"
+ me.education[0].type + ": " + me.education[0].school.name + ", " + me.education[0].year.name;
lblSex.Text = me.gender;
dynamic status = client.get("/me/statuses");
txtStatus.Text = status.data[0].message;
}
It requires the read_stream permission. Ensure you have it.
Your permission array should look like follows:
string[] extendedPermissions = new[] { "user_about_me", "read_stream" };
if (extendedPermissions != null && extendedPermissions.Length > 0)
{
var scope = new StringBuilder();
scope.Append(string.Join(",", extendedPermissions));
parameters["scope"] = scope.ToString();
}
furthermore your second get() should be capitalized: Get()
dynamic status = client.get("/me/statuses");
dynamic status = client.Get("/me/statuses");