How to get all windows groups along with their permissions using WMI C#? - windows

I am trying to read
All Groups of Users in Windows
Permissions (ACL, DACL etc) on each group.
Here is my code
public List<GroupPermissions> GetGroups()
{
var scope = new ManagementScope("\\\\.\\ROOT\\cimv2");
var sQuery = new SelectQuery("Select * from Win32_SecurityDescriptor");
var secDesc = new List<GroupPermissions>();
try
{
var mSearcher = new ManagementObjectSearcher(scope,sQuery);
foreach (ManagementObject mObject in mSearcher.Get())
{
var sDObj = new GroupPermissions();
var aceList = new List<ACE>();
var saceList = new List<ACE>();
var aceobjs = (ManagementObjectCollection)mObject["DACL"];
var aceobjsS = (ManagementObjectCollection)mObject["SACL"];
var gpTt = (ManagementObject)mObject["Group"];
var ownerTt = (ManagementObject)mObject["Owner"];
var sids = (UInt16[]) gpTt["SID"];
var osids= (UInt16[]) ownerTt["SID"];
var groupTrustee = new Trustee()
{
Domain =Convert.ToString(gpTt["Domain"]),
Name = Convert.ToString(gpTt["Name"]),
SIDString = Convert.ToString(gpTt["SIDString"]),
SidLength = Convert.ToUInt32(gpTt["SidLength"]),
SID = sids
};
var ownerTrustee = new Trustee()
{
Domain =Convert.ToString(ownerTt["Domain"]),
Name = Convert.ToString(ownerTt["Name"]),
SIDString = Convert.ToString(ownerTt["SIDString"]),
SidLength = Convert.ToUInt32(ownerTt["SidLength"]),
SID = osids
};
foreach (ManagementObject ace in aceobjs)
{
var dTrustee = (ManagementObject)ace["Trustee"];
var daclSids= (UInt16[]) dTrustee ["SID"];
var daclTrustee = new Trustee()
{
Domain =Convert.ToString(gpTt["Domain"]),
Name = Convert.ToString(gpTt["Name"]),
SIDString = Convert.ToString(gpTt["SIDString"]),
SidLength = Convert.ToUInt32(gpTt["SidLength"]),
SID = daclSids
};
aceList.Add(new ACE()
{
AccessMask = Convert.ToUInt32(ace["AccessMask"]),
AceFlags = Convert.ToUInt32(ace["AceFlags"]),
GuidInheritedObjectType = Convert.ToString(ace["GuidInheritedObjectType"]),
AceType = Convert.ToUInt32(ace["AceType"]),
GuidObjectType = Convert.ToString(ace["GuidObjectType"]),
Trustee = daclTrustee
});
}
foreach (ManagementObject sace in aceobjsS)
{
var dTrustee = (ManagementObject)sace["Trustee"];
var daclSids = (UInt16[])dTrustee["SID"];
var daclTrustee = new Trustee()
{
Domain = Convert.ToString(gpTt["Domain"]),
Name = Convert.ToString(gpTt["Name"]),
SIDString = Convert.ToString(gpTt["SIDString"]),
SidLength = Convert.ToUInt32(gpTt["SidLength"]),
SID = daclSids
};
saceList.Add(new ACE()
{
AccessMask = Convert.ToUInt32(sace["AccessMask"]),
AceFlags = Convert.ToUInt32(sace["AceFlags"]),
GuidInheritedObjectType = Convert.ToString(sace["GuidInheritedObjectType"]),
AceType = Convert.ToUInt32(sace["AceType"]),
GuidObjectType = Convert.ToString(sace["GuidObjectType"]),
Trustee = daclTrustee
});
}
sDObj.ControlFlags = Convert.ToUInt32(mObject["ControlFlags"] ?? 0);
sDObj.DACL = aceList.ToArray();
sDObj.Group = groupTrustee;
sDObj.Owner = ownerTrustee;
sDObj.SACL = saceList.ToArray();
secDesc.Add(sDObj);
}
}
catch (Exception ex)
{
}
return secDesc;
}
and dependent classes that i have created (in copy of WMI classes)
public class GroupPermissions
{
public UInt32 ControlFlags;
public ACE[] DACL;
public Trustee Group;
public Trustee Owner;
public ACE[] SACL;
}
public class ACE
{
public UInt32 AccessMask;
public UInt32 AceFlags;
public UInt32 AceType;
public string GuidInheritedObjectType;
public string GuidObjectType;
public Trustee Trustee;
};
public class Trustee
{
public string Domain;
public string Name;
public UInt16[] SID;
public UInt32 SidLength;
public string SIDString;
};
It returns nothing. The list object is empty. I am definitely doing something wrong. Can some one please help me out?

Related

Add fax number to exchage contanct using EWS API from FAX and Scan

I try Mictosoft example to create and and contact to exchange server using EWS and strangly mark as invalid while try using fax number for sending using Windows Fax and Scan (wfs.exe).
So , Does anybody know how should I set fax number in EWS that can be usable for sending fax in fax and scan?
After a lot of exprementing and invaestigating using OutlookSpy I found out I should add a # before number to be recognizable by Windows Fax and Scan. This is my final code.
public static ExchangeService GetService(string emailUser = defaultUser, string pass = defaultPass)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
//service.AutodiscoverUrl(emailUser, RedirectionUrlValidationCallback);
service.Url = new Uri("https://xs3.domain.net/EWS/Exchange.asmx");
service.Credentials = new WebCredentials(emailUser, pass);
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
return service;
}
public static bool IsValidEmail(string email)
{
try
{
var addr = new System.Net.Mail.MailAddress(email);
return addr.Address == email;
}
catch
{
return false;
}
}
public static void AddOrUpdateContact(ExchangeService service, string id, Dictionary<string, string> dataRecord, string targetFolder = defaultCotactsFolder, bool faxOnly = false)
{
Folder parentFolder;
FindFoldersResults folderItems = service.FindFolders(
WellKnownFolderName.Contacts,//parent folder
new SearchFilter.IsEqualTo(FolderSchema.DisplayName, targetFolder),
new FolderView(1)// return first 1 records
);
if (folderItems != null && folderItems.Count() > 0)
{//folder found!
parentFolder = folderItems.First() as Folder;
}
else
{//folder NOT found!
return;
}
ExtendedPropertyDefinition CustomProperty = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "BusinessFax", MapiPropertyType.String);
FindItemsResults<Item> contactItems = service.FindItems(
parentFolder.Id,
new SearchFilter.IsEqualTo(ContactSchema.NickName, id),
new ItemView(1)
);
bool doesExist = contactItems != null && contactItems.Count() > 0;
Contact contact;
if (doesExist)
{//contact found!
contact = contactItems.First() as Contact;
}
else
{
// Create the contact.
contact = new Contact(service);
}
// Specify the name and how the contact should be filled.
contact.CompanyName = name;
contact.NickName = id;
contact.PhoneNumbers[PhoneNumberKey.BusinessFax] = "#"+dataRecord["COD_FAX_SUPID"];
contact.FileAsMapping = FileAsMapping.Company;
if (!faxOnly)
{
// Specify the business, home, and car phone numbers.
contact.PhoneNumbers[PhoneNumberKey.BusinessPhone] = dataRecord["COD_TEL_SUPID"];
if (IsValidEmail(dataRecord["EMAIL_SUPID"]))
{
// Specify two email addresses.
contact.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress(dataRecord["EMAIL_SUPID"]);
}
contact.PhysicalAddresses[PhysicalAddressKey.Home] = new PhysicalAddressEntry()
{
Street = dataRecord["DES_STREET_SUPID"],
City = dataRecord["DES_TOWN_SUPID"],
CountryOrRegion = dataRecord["DES_COUNTRY_SUPID"],
PostalCode = dataRecord["COD_POST_SUPID"] + (String.IsNullOrWhiteSpace(dataRecord["NUM_BOX_SUPID"]) ? "" : $", PostBox: {dataRecord["NUM_BOX_SUPID"]}"),
}
}
if (doesExist)
{ //contact found!
contact.Update(ConflictResolutionMode.AlwaysOverwrite);
}
else
{
//save new!
contact.Save(parentFolder.Id);
}
}
Usage Example:
ExchangeService service = ContatctUpdaterLib.ContatcUpdater.GetService("USER#DONAMAIN.COM","123456");
//GetUserData return user data record as a Dictionary<string,string>
var data = GetUserData();
AddOrUpdateContact(service, dataRecord["COD_SUP_SUPID"], dataRecord, "Contacts(Fax Only)" ,true);

Programmatically cloning Octopus Deploy Process steps and modifyng the cloned steps

We are developing a Pipeline for which we have to add over 100 steps and modify two things for each step: Step Name and PackageID.
Rather than going through the pain of doing this via the UI, we’d like to do this programmatically.
Below is some C# I’ve sketched out for this (I’m a C# developer with extremely limited PowerShell skills, that’s why I did this in C#).
The lines above the comment “From here on is where I'm fuzzy” are working code, but the lines below the comment are just pseudocode.
Can someone explain to me how to write the lines below the comment (or, the PowerShell equivalent)?
I wasn’t able to find API calls for this.
Thanks
namespace ODClientExample
{
class Program
{
static void Main(string[] args)
{
List<string> ListOfWindowsServices = new List<string>();
ListOfWindowsServices.Add("svc1");
ListOfWindowsServices.Add("svc2");
ListOfFWindowsServices.Add("svc3");
var server = "https://mysite.whatever/";
var apiKey = "API-xxxxxxxxxxxxxxxxxx"; // I generated this via the Octopus UI
var endpoint = new OctopusServerEndpoint(server, apiKey);
var repository = new OctopusRepository(endpoint);
var project = repository.Projects.FindByName("Windows Services");
// From here on is where I'm fuzzy:
//
var procesSteps = GetProcessSteps(project);
var processStepToClone = GetProcesStepByName(processSteps, "SomeProcessStep");
foreach (string svcName in ListofSvcNames)
{
processStepToClone.StepName = svcName;
processStepToClone.PackageID = svcName;
}
}
}
}
I've made a little more progress. I'm now able to access the Steps in the Process, and add a Step. However, when my code calls repository.DeploymentProcesses.Modify, I get this exception:
Please provide a value for the package ID.
Please select the feed that this package will be downloaded from.
Please select one or more roles that 'svc1' step will apply to.
Here's my latest code:
static void Main(string[] args)
{
List<string> ListOfFexWindowsServices = new List<string>();
ListOfFexWindowsServices.Add("svc2");
ListOfFexWindowsServices.Add("svc3");
ListOfFexWindowsServices.Add("svc4");
string server = "https://mysite.stuff/";
string apiKey = "API-xxxxxxxxxxxxxxxxxxxxxxxx"; // I generated this via the Octopus UI
OctopusServerEndpoint endpoint = new OctopusServerEndpoint(server, apiKey);
OctopusRepository repository = new OctopusRepository(endpoint);
ProjectResource projectResource = repository.Projects.FindByName("MyProject");
DeploymentProcessResource deploymentProcess = repository.DeploymentProcesses.Get(projectResource.DeploymentProcessId);
var projectSteps = deploymentProcess.Steps;
DeploymentStepResource stepToClone = new DeploymentStepResource();
foreach (DeploymentStepResource step in projectSteps)
{
if (step.Name == "svc1")
{
stepToClone = step;
break;
}
}
foreach (string serviceName in ListOfFexWindowsServices)
{
DeploymentStepResource newStep = new DeploymentStepResource();
PopulateNewStep(newStep, stepToClone, serviceName);
deploymentProcess.Steps.Add(newStep);
repository.DeploymentProcesses.Modify(deploymentProcess);
}
}
static void PopulateNewStep(DeploymentStepResource newStep, DeploymentStepResource stepToClone, string serviceName)
{
newStep.Name = serviceName;
newStep.Id = Guid.NewGuid().ToString();
newStep.StartTrigger = stepToClone.StartTrigger;
newStep.Condition = stepToClone.Condition;
DeploymentActionResource action = new DeploymentActionResource
{
Name = newStep.Name,
ActionType = "Octopus.TentaclePackage",
Id = Guid.NewGuid().ToString(),
};
PopulateActionProperties(action);
newStep.Actions.Add(action);
// ISSUE: Anything else to do (eg, any other things from stepToClone to copy, or other stuff to create)?
newStep.PackageRequirement = stepToClone.PackageRequirement;
}
static void PopulateActionProperties(DeploymentActionResource action)
{
action.Properties.Add(new KeyValuePair<string, PropertyValueResource>("Octopus.Action.WindowsService.CustomAccountPassword", "#{WindowsService.Password}"));
// TODO: Repeat this sort of thing for each Action Property you see in stepToClone.
}
void Main()
{
var sourceProjectName = "<source project name>";
var targetProjectName = "<target project name>";
var stepToCopyName = "<step name to copy>";
var repo = GetOctopusRepository();
var sourceProject = repo.Projects.FindByName(sourceProjectName);
var targetProject = repo.Projects.FindByName(targetProjectName);
if (sourceProject != null && targetProject != null)
{
var sourceDeploymentProcess = repo.DeploymentProcesses.Get(sourceProject.DeploymentProcessId);
var targetDeploymentProcess = repo.DeploymentProcesses.Get(targetProject.DeploymentProcessId);
if (sourceDeploymentProcess != null && targetDeploymentProcess != null)
{
Console.WriteLine($"Start copy from project '{sourceProjectName}' to project '{targetProjectName}'");
CopyStepToTarget(sourceDeploymentProcess, targetDeploymentProcess, stepToCopyName);
// Update or add the target deployment process
repo.DeploymentProcesses.Modify(targetDeploymentProcess);
Console.WriteLine($"End copy from project '{sourceProjectName}' to project '{targetProjectName}'");
}
}
}
private OctopusRepository GetOctopusRepository()
{
var octopusServer = Environment.GetEnvironmentVariable("OCTOPUS_CLI_SERVER");
var octopusApiKey = Environment.GetEnvironmentVariable("OCTOPUS_CLI_API_KEY");
var endPoint = new OctopusServerEndpoint(octopusServer, octopusApiKey);
return new OctopusRepository(endPoint);
}
private void CopyStepToTarget(DeploymentProcessResource sourceProcess, DeploymentProcessResource targetProcess, string sourceStepName, bool includeChannels = false, bool includeEnvironments = false)
{
var sourceStep = sourceProcess.FindStep(sourceStepName);
if (sourceStep == null)
{
Console.WriteLine($"{sourceStepName} not found in {sourceProcess.ProjectId}");
return;
}
Console.WriteLine($"-> copy step '{sourceStep.Name}'");
var stepToAdd = targetProcess.AddOrUpdateStep(sourceStep.Name);
stepToAdd.RequirePackagesToBeAcquired(sourceStep.RequiresPackagesToBeAcquired);
stepToAdd.WithCondition(sourceStep.Condition);
stepToAdd.WithStartTrigger(sourceStep.StartTrigger);
foreach (var property in sourceStep.Properties)
{
if (stepToAdd.Properties.ContainsKey(property.Key))
{
stepToAdd.Properties[property.Key] = property.Value;
}
else
{
stepToAdd.Properties.Add(property.Key, property.Value);
}
}
foreach (var sourceAction in sourceStep.Actions)
{
Console.WriteLine($"-> copy action '{sourceAction.Name}'");
var targetAction = stepToAdd.AddOrUpdateAction(sourceAction.Name);
targetAction.ActionType = sourceAction.ActionType;
targetAction.IsDisabled = sourceAction.IsDisabled;
if (includeChannels)
{
foreach (var sourceChannel in sourceAction.Channels)
{
targetAction.Channels.Add(sourceChannel);
}
}
if (includeEnvironments)
{
foreach (var sourceEnvironment in sourceAction.Environments)
{
targetAction.Environments.Add(sourceEnvironment);
}
}
foreach (var actionProperty in sourceAction.Properties)
{
if (targetAction.Properties.ContainsKey(actionProperty.Key))
{
targetAction.Properties[actionProperty.Key] = actionProperty.Value;
}
else
{
targetAction.Properties.Add(actionProperty.Key, actionProperty.Value);
}
}
}
}
The above code sample is available in the Octopus Client Api Samples

Dynamics CRM Solution Import via SDK is not working

I have the below code that imports a solution into CRM Dynamics.
The code executes successfully and the import job data returns a result of success. How ever when I look for the solution in Settings->Solutions it is not there. Can anyone suggest a fix?
private void ImportSolution(string solutionPath)
{
byte[] fileBytes = File.ReadAllBytes(solutionPath);
var request = new ImportSolutionRequest()
{
CustomizationFile = fileBytes,
ImportJobId = Guid.NewGuid()
};
var response = _settings.DestinationSourceOrgService.Execute(request);
var improtJob = new ImportJob(_settings);
var importJobResult = improtJob.GetImportJob(request.ImportJobId);
var data = importJobResult.Attributes["data"].ToString();
var jobData = new ImportJobData(data);
var filePath = $#"{this._settings.SolutionExportDirectory}\Logs\";
var fileName = $#"{filePath}{jobData.SolutionName}.xml";
Directory.CreateDirectory(filePath);
File.WriteAllText(fileName, data);
PrintResult(jobData.Result, jobData.SolutionName);
}
public class ImportJob
{
private readonly ConfigurationSettings _settings;
public ImportJob(ConfigurationSettings settings)
{
_settings = settings;
}
public Entity GetImportJob(Guid importJobId)
{
var query = new QueryExpression
{
EntityName = "importjob",
ColumnSet = new ColumnSet("importjobid", "data", "solutionname"),
Criteria = new FilterExpression()
};
var result = _settings.DestinationSourceOrgService.Retrieve("importjob", importJobId, new ColumnSet("importjobid", "data", "solutionname", "progress"));
return result;
}
}
Thre ImportSolutionResponse does not contain any information as per the screen shot below.

PLSQL parsing using Oracle.VsDevTools.SqlAndPlsqlParser

I downloaded Oracle Developer Tools for Visual studio and explored the libraries (.dll). I need to parse the PLSQL scripts to get the SQL Statements in that and using the visitors to visit the nodes. I found Oracle.VsDevTools.SqlAndPlsqlParser library and explored further and tried to parse the PLSQL scripts. Please refer the below code.
string plSQLScript="CREATE TABLE Student(Age int);";
List<LexerToken> tokens= LexerToken.Parse(plSQLScript, false, true);
But the above code gives tokens only, I need PLSQL parser.
Is there any possible way to parser the PLSQL scripts and get the sql statements. Also I need to explicit visit the sql statements like CreateTableVisitor, CreateProcedureVisitor, etc.
I already created the parser for TSQL files by exploring Microsoft SQL library called Microsoft.SqlServer.TransactSql.ScriptDom and using the below mentioned code for parsing.
TSql100Parser parser = new TSql100Parser(true);
IList<ParseError> error;
using (TextReader tr = new StreamReader(filePath))
{
TSqlFragment fragment = parser.Parse(tr, out error);
tr.Close();
}
And using TSqlFragmentVisitor to visit the sql statements. Please refer the below mentioned code.
public override void ExplicitVisit(CreateTableStatement node)
{
//----Coding----
}
I want the same for PLSQL by using Oracle.VsDevTools.SqlAndPlsqlParser library.
Please let me know if there any possibility for this.
Thanks,Sivaprakash.
With some reflection used it's possible. The parser, nodes and grammar classes are internal. I made small example for you:
private static Assembly odacDevAssembly = Assembly.Load("Oracle.VsDevTools.14.0");
private static Type parseNodeType = odacDevAssembly.GetType("Oracle.VsDevTools.SqlAndPlsqlParser.ParseNode");
void Main()
{
var parserType = odacDevAssembly.GetType("Oracle.VsDevTools.SqlAndPlsqlParser.OracleSqlEarley");
var parser = Activator.CreateInstance(parserType);
const string sqlScriptText = "DECLARE x NUMBER; BEGIN SELECT DUMMY INTO :DUMMY FROM DUAL T1; x := 1; SELECT DUMMY INTO :DUMMY FROM DUAL T2; x := 2; INSERT INTO T3 (C) VALUES (1); x := 3; END;";
var tokens = LexerToken.Parse(sqlScriptText);
var parserGrammar = parserType.GetProperty("EarleyGrammar").GetValue(parser);
var allSymbols = (string[])parserGrammar.GetType().GetField("m_vAllSymbols", BindingFlags.Public | BindingFlags.Instance).GetValue(parserGrammar);
var sqlStatementIndex = -1;
for (var i = 0; i < allSymbols.Length; i++)
{
if (allSymbols[i] == "unlabeled_nonblock_stmt")
{
sqlStatementIndex = i;
break;
}
}
var parseTree = parserType.GetMethod("Parse").Invoke(parser, new object[] { sqlScriptText, tokens });
//parseTree.GetType().GetMethod("PrintTree", new Type[] { parserGrammar.GetType() }).Invoke(parseTree, new object[] { parserGrammar });
var commandNodes = GetDescendants(parseTree).Where(d => GetPayloadIn(d) == sqlStatementIndex);
foreach (var commandNode in commandNodes)
{
var commandText = GetCommandText(commandNode, sqlScriptText, tokens);
Console.WriteLine(commandText);
}
}
private static string GetCommandText(object parseNode, string sqlScriptText, List<LexerToken> tokens)
{
var from = (int)parseNodeType.GetProperty("From").GetValue(parseNode);
var to = (int)parseNodeType.GetProperty("To").GetValue(parseNode) - 1;
var begin = tokens[from].m_vBegin;
return sqlScriptText.Substring(begin, tokens[to].m_vEnd - begin);
}
private static IEnumerable<object> GetDescendants(object parseNode)
{
yield return parseNode;
foreach (var child in GetChildren(parseNode))
foreach (var descendant in GetDescendants(child))
yield return descendant;
}
private static int GetPayloadIn(object parseNode)
{
return (int)parseNodeType.GetProperty("PayloadIn").GetValue(parseNode);
}
private static IEnumerable<object> GetChildren(object parseNode)
{
return (IEnumerable<object>)parseNodeType.GetMethod("Children").Invoke(parseNode, null);
}
UPDATE:
I'm not exactly sure what do you want to achieve but I hope it will be at least somehow helpful:
private static Assembly odacDevAssembly = Assembly.Load("Oracle.VsDevTools.14.0");
private static Type parseNodeType = odacDevAssembly.GetType("Oracle.VsDevTools.SqlAndPlsqlParser.ParseNode");
void Main()
{
var parserType = odacDevAssembly.GetType("Oracle.VsDevTools.SqlAndPlsqlParser.OracleSqlEarley");
var parser = Activator.CreateInstance(parserType);
const string sqlScriptText = "DECLARE x NUMBER; BEGIN SELECT DUMMY INTO :DUMMY FROM DUAL T1; x := 1; SELECT DUMMY INTO :DUMMY FROM DUAL T2; x := 2; INSERT INTO T3 (C) VALUES (1); x := 3; END;";
var tokens = LexerToken.Parse(sqlScriptText);
var parserGrammar = parserType.GetProperty("EarleyGrammar").GetValue(parser);
var allSymbols = (string[])parserGrammar.GetType().GetField("m_vAllSymbols", BindingFlags.Public | BindingFlags.Instance).GetValue(parserGrammar);
const int sqlStatementIndex = 4453; // unlabeled_nonblock_stmt
var parseTree = parserType.GetMethod("Parse").Invoke(parser, new object[] { sqlScriptText, tokens });
//parseTree.GetType().GetMethod("PrintTree", new Type[] { parserGrammar.GetType() }).Invoke(parseTree, new object[] { parserGrammar });
var commandNodes = GetDescendants(parseTree)
.Select(n => ParseNodeFactory.CreateNode(n, sqlScriptText, tokens))
.Where(n => n != null);
var visitor = new GrammarNodeVisitor();
foreach (var commandNode in commandNodes)
{
commandNode.Accept(visitor);
}
}
public static class ParseNodeFactory
{
private const int queryBlockIndex = 3849; // query_block
private const int insertIndex = 3136; // insert
public static IParseNode CreateNode(object parseNode, string sqlScriptText, List<LexerToken> tokens)
{
var symbolIndex = GetPayloadIn(parseNode);
var parseData = new ParseData { ParseNode = parseNode, SqlScriptText = sqlScriptText, Tokens = tokens };
switch (symbolIndex)
{
case queryBlockIndex:
return new QueryBlock { ParseData = parseData };
case insertIndex:
return new Insert { ParseData = parseData };
default:
return null;
}
}
}
public class GrammarNodeVisitor : IParseNodeVisitor
{
public void VisitQueryBlock(QueryBlock queryBlock)
{
Console.WriteLine($"Visited query block: {GetCommandText(queryBlock.ParseData.ParseNode, queryBlock.ParseData.SqlScriptText, queryBlock.ParseData.Tokens)}");
}
public void VisitInsert(Insert insert)
{
Console.WriteLine($"Visited insert command: {GetCommandText(insert.ParseData.ParseNode, insert.ParseData.SqlScriptText, insert.ParseData.Tokens)}");
}
}
public interface IParseNodeVisitor
{
void VisitQueryBlock(QueryBlock queryBlock);
void VisitInsert(Insert insert);
}
public interface IParseNode
{
ParseData ParseData { get; }
void Accept(IParseNodeVisitor visitor);
}
public class ParseData
{
public object ParseNode { get; set; }
public string SqlScriptText { get; set; }
public List<LexerToken> Tokens { get; set; }
}
public class QueryBlock : IParseNode
{
public ParseData ParseData { get; set; }
public void Accept(IParseNodeVisitor visitor)
{
visitor.VisitQueryBlock(this);
}
}
public class Insert : IParseNode
{
public ParseData ParseData { get; set; }
public void Accept(IParseNodeVisitor visitor)
{
visitor.VisitInsert(this);
}
}
private static string GetCommandText(object parseNode, string sqlScriptText, List<LexerToken> tokens)
{
var from = (int)parseNodeType.GetProperty("From").GetValue(parseNode);
var to = (int)parseNodeType.GetProperty("To").GetValue(parseNode) - 1;
var begin = tokens[from].m_vBegin;
return sqlScriptText.Substring(begin, tokens[to].m_vEnd - begin);
}
private static IEnumerable<object> GetDescendants(object parseNode)
{
yield return parseNode;
foreach (var child in GetChildren(parseNode))
foreach (var descendant in GetDescendants(child))
yield return descendant;
}
private static int GetPayloadIn(object parseNode)
{
return (int)parseNodeType.GetProperty("PayloadIn").GetValue(parseNode);
}
private static IEnumerable<object> GetChildren(object parseNode)
{
return (IEnumerable<object>)parseNodeType.GetMethod("Children").Invoke(parseNode, null);
}

PaginatedList for pagination for MVC 3 application? Error: has some invalid arguments

I have the following code, I can figure why its invalid argument:
AuditDAL ad = new AuditDAL();
var agencies = ad.SearchAgencies("Ak001", "");
string col = param.sColumns.Split(',')[param.iSortCol_0];
string orderby = col + " " + param.sSortDir_0;
// The best overloaded method match for 'AMS.Helper.PaginatedList.PaginatedList(System.Linq.IQueryable, int, int)' has some invalid arguments C:\NexGen\AMS\DEV\Source\AMS\Controllers\AuditController.cs
var qry = new PaginatedList<AuditAgency>(agencies, param.iDisplayStart, param.iDisplayLength);
PaginatedList Code:
namespace AMS.Helper
{
public class PaginatedList<T> : List<T> {
public int PageIndex { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public int TotalPages { get; private set; }
public PaginatedList(IQueryable<T> source, int pageIndex, int pageSize) {
PageIndex = pageIndex;
PageSize = pageSize;
TotalCount = source.Count();
TotalPages = (int) Math.Ceiling(TotalCount / (double)PageSize);
this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize));
}
public bool HasPreviousPage {
get {
return (PageIndex > 0);
}
}
public bool HasNextPage {
get {
return (PageIndex+1 < TotalPages);
}
}
}
}
Search Agencies Code:
public IEnumerable<AuditAgency> SearchAgencies(string ori, string name)
{
List<AuditAgency> agencies = new List<AuditAgency>();
using (var conn = new SqlConnection(_connectionString))
{
var com = new SqlCommand();
com.Connection = conn;
com.CommandType = CommandType.StoredProcedure;
string term = "Ori";
if (!String.IsNullOrEmpty(ori))
{
term = "Ori";
com.Parameters.Add(new SqlParameter
{
ParameterName = "#ORI",
Value = ori
});
}
if (!String.IsNullOrEmpty(name))
{
term = "legal_name";
com.Parameters.Add(new SqlParameter
{
ParameterName = "#Name",
Value = name
});
}
com.CommandText = "Audit_Get_Agency_List";
var adapt = new SqlDataAdapter();
adapt.SelectCommand = com;
var dataset = new DataSet();
adapt.Fill(dataset);
agencies = (from c in dataset.Tables[0].AsEnumerable()
select new AuditAgency()
{
Agency_ID = Convert.ToInt32(c["Agency_Id"]),
Agency_Name = c["Agency_Name"].ToString(),
Agency_Ori = c["ORI"].ToString(),
COPSAuditNumber = c["COPSAuditNumber"].ToString(),
OIGAuditNumber = c["OIGAuditNumber"].ToString()
}).ToList<AuditAgency>();
return agencies;
}
}
The error should tell you where to start.
If you fire up the debugger, I think you'll find agencies is an IEnumberable, but not an IQueryable
correct it by changing the return type of SearchAgencies from IQueryable to IEnumerable
or alternatively, you can change the type of the PaginatedList to accept IEnumberables instead of IQueryables. this may be safer as IQueryable inherits from IEnumerable
(see
http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx or
Differences between IQueryable, List, IEnumerator?
for the difference between the two)

Resources