I've been working on a programmatic solution to edit the IPGrant table in IIS.
As it stands, I can View the IPGrant list Correctly, and CAN add to it.
However, I cannot remove or replace items in the IPGrant list.
MSDN and such recommend that you write (the values of the old list + the new value) to the List, however I'm finding I'm getting a HResult of "Cannot create file with that name, file already exists".
Adding to the list only works for me If I pass in the new value only.
After some reading:
http://www.west-wind.com/weblog/posts/59731.aspx
http://www.aspdev.org/articles/web.config/
http://www.codeproject.com/KB/security/iiswmi.aspx
http://www.codeproject.com/KB/security/iiswmi.aspx?msg=1739049
http://blogs.msdn.com/b/shawnfa/archive/0001/01/01/400749.aspx
http://msdn.microsoft.com/en-us/library/ms524322%28VS.90%29.aspx
http://www.eggheadcafe.com/software/aspnet/33215307/setting-ip-restrictions-in-iis-7.aspx
I'm finding that there is a compatability issue with IIS 7/6 and using the Metabase - in that one can only add to it, not remove.
Is there a more current method for IIS 7/7.5 that can be used (in c# please) to administrate the IPGrant table.
You can use Microsoft.Web.Administration, or AppCmd, or Javascript (COM - AHADMIN) to do that, here are a few examples on how to remove:
private static void Main() {
using(ServerManager serverManager = new ServerManager()) {
Configuration config = serverManager.GetApplicationHostConfiguration();
ConfigurationSection ipSecuritySection = config.GetSection("system.webServer/security/ipSecurity");
ConfigurationElementCollection ipSecurityCollection = ipSecuritySection.GetCollection();
ConfigurationElement addElement = FindElement(ipSecurityCollection, "add", "ipAddress", #"169.132.124.234", "subnetMask", #"255.255.255.255", "domainName", #"");
if (addElement == null) throw new InvalidOperationException("Element not found!");
ipSecurityCollection.Remove(addElement);
serverManager.CommitChanges();
}
}
private static ConfigurationElement FindElement(ConfigurationElementCollection collection, string elementTagName, params string[] keyValues) {
foreach (ConfigurationElement element in collection) {
if (String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase)) {
bool matches = true;
for (int i = 0; i < keyValues.Length; i += 2) {
object o = element.GetAttributeValue(keyValues[i]);
string value = null;
if (o != null) {
value = o.ToString();
}
if (!String.Equals(value, keyValues[i + 1], StringComparison.OrdinalIgnoreCase)) {
matches = false;
break;
}
}
if (matches) {
return element;
}
}
}
return null;
}
Using Javascript:
var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager');
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST";
var ipSecuritySection = adminManager.GetAdminSection("system.webServer/security/ipSecurity", "MACHINE/WEBROOT/APPHOST");
var ipSecurityCollection = ipSecuritySection.Collection;
var addElementPos = FindElement(ipSecurityCollection, "add", ["ipAddress", "169.132.124.234","subnetMask", "255.255.255.255","domainName", ""]);
if (addElementPos == -1) throw "Element not found!";
ipSecurityCollection.DeleteElement(addElementPos);
adminManager.CommitChanges();
function FindElement(collection, elementTagName, valuesToMatch) {
for (var i = 0; i < collection.Count; i++) {
var element = collection.Item(i);
if (element.Name == elementTagName) {
var matches = true;
for (var iVal = 0; iVal < valuesToMatch.length; iVal += 2) {
var property = element.GetPropertyByName(valuesToMatch[iVal]);
var value = property.Value;
if (value != null) {
value = value.toString();
}
if (value != valuesToMatch[iVal + 1]) {
matches = false;
break;
}
}
if (matches) {
return i;
}
}
}
return -1;
}
And Finally AppCmd.exe:
appcmd.exe set config -section:system.webServer/security/ipSecurity /-"[ipAddress='169.132.124.234',subnetMask='255.255.255.255',domainName='']" /commit:apphost
Related
So I have a fitler TextBox where I want to search for different type of docs in a grid the code where I have different type of columns such as: Date,DocId,ClientId.
For a search I write on a filter Textbox something like that DocId:2002 and It just work fine but when I try to make a multiple search for example DocId:2002 ClientId:201 It doesnt search because of the return it just does an infinite loop.
private void TextBoxFilter_TextChanged(object sender, TextChangedEventArgs e)
{
foreach (Match m in Regex.Matches((sender as TextBox).Text, pattern, options))
{
if (m.Value != "")
{
Func<String, String> untilSlash = (s) => { return filters[re.Match(s).Groups[1].ToString()] = re.Match(s).Groups[2].ToString(); };
untilSlash(m.Value);
}
}
ICollectionView cv = CollectionViewSource.GetDefaultView(this.DataGridDocList.ItemsSource);
if (filters.Count == 0)
{
cv.Filter = null;
}
else
{
cv.Filter = o =>
{
for (int i = 0; i < filters.Count; i++)
{
if (filters.ElementAt(i).Key == "Date")
{
if (DateVerify.Match(filters.ElementAt(i).Value).Success)
{
return (o as Document).DateCreated < Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString()) && (o as Document).DateCreated > Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[2].ToString());
}
else
{
var dateString = (o as Document).DateCreated.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
return dateString.Contains(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString());
}
}
if (filters.ElementAt(i).Key == "DocId")
{
return (o as Document).DocumentId.ToString().Contains(filters.ElementAt(i).Value);
}
if (filters.ElementAt(i).Key == "ClientId")
{
return (o as Document).ClientId.ToUpper().Contains(filters.ElementAt(i).Value.ToUpper());
}
}
return false;
};
filters.Clear();
}
}
So my question is how can I do an big search with all the filters at one time?
Manually I can add them 1 by 1 and it will be something like search1 && search2 && search3 but It will take too much time and It's probably not the best solution
There are many ways of building up the predicate. However my suggestion is to keep it simple and just create one method that returns true or false. It's good practice to only return once in a method.
The code below if for illustration purposes (as I'm unable to test it):
ICollectionView cv = CollectionViewSource.GetDefaultView(this.DataGridDocList.ItemsSource);
if (filters.Any())
{
cv.Filter = new Predicate<object>(PredicateFilter);
}
else
{
cv.Filter = null;
}
Then Predicate method to filter results:
public bool PredicateFilter(object docObj)
{
Document doc = docObj as Document;
var response = new List<bool>();
for (int i = 0; i < filters.Count; i++)
{
if (filters.ElementAt(i).Key == "Date")
{
if (DateVerify.Match(filters.ElementAt(i).Value).Success)
{
response.Add(doc.DateCreated < Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString()) && doc.DateCreated > Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[2].ToString()));
}
else
{
var dateString = doc.DateCreated.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
response.Add(dateString.Contains(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString()));
}
}
else if (filters.ElementAt(i).Key == "DocId")
{
response.Add(doc.DocumentId.ToString().Contains(filters.ElementAt(i).Value));
}
else if (filters.ElementAt(i).Key == "ClientId")
{
response.Add(doc.ClientId.ToUpper().Contains(filters.ElementAt(i).Value.ToUpper()));
}
}
return response.All(m => m); // if all filters came back with true, return 1 response of true else false.
}
I just wanna ask if there is someone here that have already made a breadcrumbs in Sitecore. I'm currently doing a Sitecore 8 MVC project that needs to have a breadcrumbs.
Currently I saw this website http://blog.ryanbailey.co.nz/2015/05/breadcrumbs-for-pages-in-sitecore.html. But It doesn't work for me yet because I don't know what to reference.
I just need to know how to get every item in the path of my current page I can handle it already.
Thanks
Something like this should do it:
public ICollection<Item> GetBreadcrumbs(Item current, SiteContext site)
{
Item homeItem = site.StartItem;
List<Item> breadcrumbs = new List<Item>();
while (current != null)
{
// You may want to add additional logic to opt in/out of
// the breadcrumb based on a template/field
breadcrumbs.Add(current);
if (current == homeItem)
break;
current = current.Parent;
}
breadcrumbs.Reverse();
return breadcrumbs;
}
And then:
var breadcrumbs = GetBreadcrumbs(Context.Item, Context.Site);
You can take the current item and then take all the ancestors of it.
var ancestors = currentItem.Axes.GetAncestors().ToList();
Then you can get home item and filter the ancestors to remove sitecore and content nodes.
ancestors = ancestors.SkipWhile(i => i.ID != home.Id.ToID()).ToList();
public void GetBreadcrumbs(Item ParentItem)
{
List<BredCrumbDetails> lstBreadCrumbs = new List<BredCrumbDetails>();
string strcurrenttitle = ParentItem.Name;
Item currentitem = ParentItem;
int i = 0;
while (currentitem != null)
{
var ItemTemplateid = currentitem.TemplateID.ToString();
var FolderTemplateId = "{}";
if (ItemTemplateid != FolderTemplateId) //here we are removing folders
{
BredCrumbDetails bcDetails = new BredCrumbDetails();
if (i == 0)
{
bcDetails.BCPageLink = null;
bcDetails.Title = currentitem.Name;
bcDetails.IsVisible = true;
lstBreadCrumbs.Add(bcDetails);
}
else
{
bcDetails.BCPageLink = currentitem.Paths.FullPath;
bcDetails.Title = currentitem.Name;
bcDetails.IsVisible = true;
lstBreadCrumbs.Add(bcDetails);
}
i++;
if (currentitem.Name == ("Home"))
{
break;
}
currentitem = currentitem.Parent;
}
else
{
i++;
currentitem = currentitem.Parent;
}
}
lstBreadCrumbs.Reverse();
rptCrumbs.DataSource = lstBreadCrumbs;
rptCrumbs.DataBind();
}
I have the following code:
foreach (XNode rowXml in elements.Nodes())
{
foreach (DataRow rowDB in dataSetDB.Tables[0].Rows)
{
string itemDB = rowDB[0].ToString().ToUpper();
string itemXml = rowXml.ToString().ToUpper();
if (itemDB == itemXml)
{
//If itemDB == itemXml; jump to Outer_Foreach
}
if (itemDB != itemXml)
{
//If itemDB != itemXml; jump to Outer_Foreach
}
}
How is it possible to get out of Inner-Foreach and up to Outer-Foreach, and still keep both foreach where you left it. I am looping through a DB and XML table rows. Break; completley jumps out of the Inner-Foreach and im not able to catch where I left it, so I start back on index[0], when I loop through it over and over again.
It sounds like you need 'for' loop.
int i = 0;
int k = 0;
bool shouldBreak;
var nodes = elements.Nodes();
var rows = dataSetDB.Tables[0].Rows;
for (i = 0; i < nodes.Count(); i++)
{
for(k = 0; k < rows.Count(); k++)
{
string itemDB = rows[k][0].ToString().ToUpper();
string itemXml = nodes[i].ToString().ToUpper();
if (itemDB == itemXml)
{
shouldBreak = true;
break;
}
if (itemDB != itemXml)
{
shouldBreak = true;
break;
}
}
if (toBreak)
break;
}
Now if you'll break the inner loop can know where it broke by accessing i and k
This answer is stolen from this answer here. What you want to achieve is a zip operation. For more information see the answer that I linked.
var xmlNodes = elements.Nodes();
var dbNodes = dataSetDB.Tables[0].Rows;
var xmlAndDB = xmlNodes.Zip(dbNodes , (x, d) => new { xNode = x, dNode = d });
foreach(var xd in xmlAndDB )
{
Console.WriteLine(xd.xNode + xd.dNode);
string itemDB = xd.dNode[0].ToString().ToUpper();
string itemXml = xd.xNode.ToString().ToUpper();
if (itemDB == itemXml)
{
//If itemDB == itemXml;
}
else /* if (itemDB != itemXml) */
{
//If itemDB != itemXml;
}
}
I'm curious as to the best route (more looking towards simplicity, not speed or efficiency) to sort a DropDownList in C#/ASP.NET - I've looked at a few recommendations but they aren't clicking well with me. this drop down is giving me list in alphabetical order. But I have to sort out randomly.
Note:I do not have control over how the data comes into the DropDownList - I cannot modify the SQL.
public void populateLocationList()
{
DataTable dt_locations = (DataTable)daa_addresses.GetDataByEventLocations(int_eventid);
if (dt_locations != null && dt_locations.Rows.Count > 0)
{
// Populate locations dropdown menu
// Bind locationsList instead of dt_locations
ddl_locations.DataTextField = "Key";
ddl_locations.DataValueField = "Value";
ddl_locations.DataSource = RemoveDuplicateLocations(dt_locations);
ddl_locations.DataBind();
string location = "";
// Set the selection based upon the query string
if (Request.QueryString["loc"] != null)
{
location = Request.QueryString["loc"];
locationLbl.Text = Request.QueryString["loc"];
locationID.Value = "-1";
}
if (dt_locations.Rows.Count == 1)
{
location = ddl_locations.Items[0].Text;
locationLbl.Text = location;
}
// Set location in drop down list
int int_foundlocation = 0;
bool foundLocation = false;
foreach (ListItem lsi_item in ddl_locations.Items)
{
if (lsi_item.Text.ToLower().Trim() == location.ToLower().Trim())
{
int_foundlocation = ddl_locations.Items.IndexOf(lsi_item);
foundLocation = true;
break;
}
}
ddl_locations.SelectedIndex = int_foundlocation;
if (ddl_locations.Items.Count == 1)
{
// Make location label visible.
locationLbl.Visible = true;
ddl_locations.Visible = false;
}
else
{
locationLbl.Visible = false;
ddl_locations.Visible = true;
}
//* defualt location S for short courses *//
if (!IsPostBack && !foundLocation)
{
ListItem s = ddl_locations.Items.FindByText("S");
int index = 0;
if (s != null)
{
index = ddl_locations.Items.IndexOf(s);
}
ddl_locations.SelectedIndex = index;
ddl_locations.DataBind();
}
}
}
I have to sort out randomly.
You'd have to shuffle rows, probably with something close to this code (borrowed from #configurator's answer):
internal static class Extensions
{
internal static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
T[] elements = source.ToArray();
// Note i > 0 to avoid final pointless iteration
for (int i = elements.Length - 1; i > 0; i--)
{
// Swap element "i" with a random earlier element it (or itself)
int swapIndex = rng.Next(i + 1);
yield return elements[swapIndex];
elements[swapIndex] = elements[i];
// we don't actually perform the swap, we can forget about the
// swapped element because we already returned it.
}
// there is one item remaining that was not returned - we return it now
yield return elements[0];
}
}
Assuming that RemoveDuplicateLocations returns a DataTable the binding part of your code should be changed to:
ddl_locations.DataSource = RemoveDuplicateLocations(dt_locations)
.AsEnumerable()
.Shuffle(new Random())
.CopyToDataTable();
I have the following method it creates a generic list recursively. I'm getting some interesting results. The property CurrentAllocation is always overwritten with the last value.
Here is the line in question.
courierTypeRegion.CurrentAllocation = remaining;
courierTypeRegionOutput.Add(courierTypeRegion);
Here is the whole method
public static List<CourierTypeRegion> FindClosest2(decimal quantity, decimal remaining, ICollection<CourierTypeRegion> courierTypeRegions, List<CourierTypeRegion> courierTypeRegionOutput)
{
var processed = false;
var courierOrderByDesc = courierTypeRegions.OrderByDescending(x => x.CourierType.PalletsPerTrailer).ToList();
var courierCount = courierOrderByDesc.Count();
var courierCurrent = 0;
foreach (var courierTypeRegion in courierOrderByDesc)
{
if (remaining >= courierTypeRegion.CourierType.PalletsPerTrailer && !processed)
{
courierTypeRegion.CurrentAllocation = courierTypeRegion.CourierType.PalletsPerTrailer;
courierTypeRegionOutput.Add(courierTypeRegion);
processed = true;
}
if (!processed)
{
if (courierOrderByDesc[courierCurrent + 1] != null)
{
if (remaining > courierOrderByDesc[courierCurrent + 1].CourierType.PalletsPerTrailer)
{
courierTypeRegion.CurrentAllocation = remaining;
courierTypeRegionOutput.Add(courierTypeRegion);
processed = true;
}
}
}
courierCurrent++;
}
if (!processed)
{
if (courierTypeRegions.Count > 0)
{
var courierTypeRegionRemaining =
courierTypeRegions.Where(x => x.CourierType.PalletsPerTrailer >= remaining).OrderByDescending(
x => x.CourierType.PalletsPerTrailer).SingleOrDefault();
if (courierTypeRegionRemaining != null) courierTypeRegionOutput.Add(courierTypeRegionRemaining);
processed = true;
}
}
var currentRemaining = quantity - courierTypeRegionOutput.Sum(x => x.CourierType.PalletsPerTrailer);
if (currentRemaining > 0)
{
FindClosest(quantity, currentRemaining, courierTypeRegions, courierTypeRegionOutput);
}
return courierTypeRegionOutput;
}
'CourierTypeRegion' is one instance that lives for the entire foreach loop, it is not instantiated and destroyed every loop iteration. You are repeatedly adding the same instance to your list. You end up with a list where all items reference the the last value in the loop.
You need to change your foreach loop as follows:
foreach (var courierTypeRegion in courierOrderByDesc)
{
var courierRegionCopy = courierTypeRegion;
if (remaining >= courierTypeRegion.CourierType.PalletsPerTrailer && !processed)
{
courierRegionCopy.CurrentAllocation = courierTypeRegion.CourierType.PalletsPerTrailer;
courierTypeRegionOutput.Add(courierRegionCopy);
processed = true;
}
if (!processed)
{
if (courierOrderByDesc[courierCurrent + 1] != null)
{
if (remaining > courierOrderByDesc[courierCurrent + 1].CourierType.PalletsPerTrailer)
{
courierRegionCopy.CurrentAllocation = remaining;
courierTypeRegionOutput.Add(courierRegionCopy);
processed = true;
}
}
}
courierCurrent++;
}