What I am trying to do is load an xml file into my mvc application but regardless of how I implement it, it always returns a count of zero, I know the way im doing isnt exactly the best by storing the xml loader in the configuration class which is made by the migrations method but it was working and now it has stopped quoting "only part of the address can be reached" I was wondering if there was a way of fixing this?
Catalog.cs
public class CatalogController : BaseController
{
// GET: Catalog
public ActionResult Index()
{
List<Category> Categories = DbContext.Categories.OrderBy(c => c.Name).ToList();
int NumberofBooks = DbContext.Books.Count();
List<PublicationThumbnail> bookItems = GetBookThumbNails(5);
HomeViewModel homeViewModel = new HomeViewModel(Categories, NumberofBooks, bookItems);
return View(homeViewModel);
}
public ActionResult Search(string c = null, string t = null)
{
string searchMessage = (t == null ? "Publications" : t);
if (c != null)
{
searchMessage += " in " + c;
}
List<PublicationThumbnail> imageThumbNail =
FilterPublications(c, t).Select(p => new PublicationThumbnail(p)).ToList();
SearchViewModel searchViewModel = new SearchViewModel()
{
FilterMessage = searchMessage,
Thumbnails = imageThumbNail,
ResultsCount = imageThumbNail.Count
};
return View(searchViewModel);
}
public ActionResult View(int id)
{
Publication foundPublications = DbContext.Publications.Find(id);
if (foundPublications != null)
{
Account currentUser = null;
if (User.Identity.IsAuthenticated)
{
currentUser = AccountManager.GetCurrentUser(User);
}
return View(new PublicationViewModel(foundPublications, currentUser));
}
return HttpNotFound();
}
[Authorize]
public ActionResult Download(int id)
{
Account account = AccountManager.GetCurrentUser(User);
if (account != null && (account.Subscribed() || account.PurchasedItem(id)))
{
Publication publication = DbContext.Publications.FirstOrDefault(p => p.Id == id);
return View(publication);
}
return HttpNotFound();
}
private List<Publication> FilterPublications(string category, string publicationType)
{
List<Publication> results = new List<Publication>();
if (publicationType != null)
{
if (publicationType.ToLower() == "books")
{
results.AddRange(DbContext.Books);
}
}
else
{
results.AddRange(DbContext.Publications);
}
if (category != null)
{
Category categoryMatch = DbContext.Categories.FirstOrDefault(c => c.Name == category);
if (categoryMatch != null)
{
results = results.Where(p => p.Categories.Contains(categoryMatch)).ToList();
}
}
return results;
}
private List<PublicationThumbnail> GetBookThumbNails(int count)
{
List<Book> books = DbContext.Books.Take(Math.Min(count, DbContext.Books.Count())).ToList();
return books.Select(j => new PublicationThumbnail(j)).ToList();
}
}
Books.xml
<?xml version="1.0" encoding="utf-8" ?>
<Books>
<Book>
<Title>The Rabbit Who Wants to Fall Asleep: A New Way of Getting Children to Sleep</Title>
<Description>The groundbreaking No. 1 bestseller is sure to turn nightly bedtime battles into a loving and special end-of-day ritual. This child-tested, parent-approved story uses an innovative technique that brings a calm end to any child's day.</Description>
<Authors>Carl-Johan Forssén Ehrlin</Authors>
<Chapters>4</Chapters>
<Edition>1</Edition>
<PublicationDate>2016-05-21T10:50:23.5602265-04:00</PublicationDate>
<PublicationFormat>PDF</PublicationFormat>
<FileLocation>App_Data/Publications</FileLocation>
<ISBN>978-3-319-30715-2</ISBN>
<Categories>
<Category>
<Name>Other</Name>
</Category>
</Categories>
<ThumbnailLocation>TheRabbit.jpg</ThumbnailLocation>
<Price>4.00</Price>
</Book>
</Books>
Configuration class
internal sealed class Configuration : DbMigrationsConfiguration<HullUniversityPress.DataAccessLayer.HullPressContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(HullPressContext context)
{
if (context.Books.Count() == 0)
{
SeedPublicationCategories(context);
SeedBooks(context);
SeedAccounts(context);
SeedSubscriptions(context);
}
}
private XDocument LoadXmlDoc(string fileName)
{
XDocument xmlDoc = XDocument.Load("HullUniversityPress/App_Data/" + fileName);
return xmlDoc;
}
private void SeedBooks(HullPressContext context)
{
XDocument xmlDoc = LoadXmlDoc("Books.xml");
foreach (XElement j in xmlDoc.Root.Elements("Book"))
{
Book newBook = new Book()
{
Title = j.Element("Title").Value,
Description = j.Element("Description").Value,
ISBN = j.Element("ISBN").Value,
FileLocation = j.Element("FileLocation").Value,
ThumbnailLocation = j.Element("ThumbnailLocation").Value,
Chapters = int.Parse(j.Element("Chapters").Value),
Edition = int.Parse(j.Element("Edition").Value),
Langauge = (Language)Enum.Parse(typeof(Language), j.Element("Language").Value),
Authors = j.Element("Authors").Value,
Price = decimal.Parse(j.Element("Price").Value),
PublicationFormat = (PublicationFormat)Enum.Parse(typeof(PublicationFormat), j.Element("PublicationFormat").Value),
PublicationDate = DateTime.Parse(j.Element("PublicationDate").Value)
};
ParseCategories(newBook, context, j.Element("Categories"));
context.Books.Add(newBook);
}
}
private void ParseCategories(Publication publication, HullPressContext context, XElement categoryRoot)
{
publication.Categories = new List<Category>();
foreach (XElement category in categoryRoot.Elements("Category"))
{
string categoryName = category.Element("Name").Value;
Category match = context.Categories.Local.FirstOrDefault(c => c.Name == categoryName);
if (match != null)
{
publication.Categories.Add(match);
match.Publications.Add(publication);
}
else throw new Exception("Unidentified category: " + category.Element("Name").Value + ", Categories: " + context.Categories.Local.Count());
}
}
private void SeedPublicationCategories(HullPressContext context)
{
context.Categories.AddOrUpdate(
new Category("Other")
);
}
private void SeedAccounts(HullPressContext context)
{
context.Accounts.AddOrUpdate(
new Account("Customer#Customer.com", "Hello12345")
);
}
private void SeedSubscriptions(HullPressContext context)
{
Account account = context.Accounts.Local.FirstOrDefault(u => u.Email == "Customer#Customer.com");
Book bookSub = context.Books.Local.FirstOrDefault();
if (account != null && bookSub != null)
{
context.Purchases.Add(new Purchase()
{
Account = account,
Publication = bookSub,
Format = PublicationFormat.PDF
});
}
}
}
Any sort of help / pointed in the right direct would be greatly received.
I'm not sure how that code ever worked,I've re-created the problem on my side and changed this line:
XDocument xmlDoc = XDocument.Load("HullUniversityPress/App_Data/" + fileName);
to this:
XDocument xmlDoc = XDocument.Load(Server.MapPath("~/HullUniversityPress/App_Data/" + fileName));
Now the XDocument is being loaded with the content of Books.xml:
Related
I am trying to perform validation using custom class attributes. I have to keep my model validation rules inside XML files. Custom Class attribute specifies the path to the XML file and custom attributes will contain the logic to read XML files and get the validation rules for that class. When I will call Model.Isvalidate() that time Validation will get executed. I already have this working in .Net 4.5 MVC application. The same thing I am trying in .Net 6 its not working.
public class CustomDynamicModelValidatorProvider : DataAnnotationsModelValidatorProvider,IModelValidatorProvider
{
protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, IEnumerable<ModelValidatorProvider> validatorProviders, IEnumerable<Attribute> attributes)
{
string resourceKeyPath = string.Empty;
IList<Attribute> newAttributes = new List<Attribute>(attributes);
CustomDynamicValidatorsAttribute resourceMapperAttr = attributes.FirstOrDefault(a => a is CustomDynamicValidatorsAttribute) as CustomDynamicValidatorsAttribute;
if (resourceMapperAttr == null)
{
System.Reflection.MemberInfo classInfo = metadata.ContainerType;
if (classInfo != null)
{
var resourceMapperRootAttr = classInfo.GetCustomAttributes(typeof(ResourceMappingRootAttribute), false).FirstOrDefault() as ResourceMappingRootAttribute;
if (resourceMapperRootAttr != null)
{
resourceKeyPath = resourceMapperRootAttr.Path + "." + metadata.PropertyName;
}
}
}
else
{
resourceKeyPath = resourceMapperAttr.ResourceKeyPath;
}
if (!string.IsNullOrEmpty(resourceKeyPath))
{
string[] validators = ResourceManager.GetValidators(resourceKeyPath).Replace(" ", "").Split(',');
var maxLength = ResourceManager.GetMaxLength(resourceKeyPath);
if (!string.IsNullOrEmpty(maxLength))
{
var required = new MaxLengthAttribute(maxLength.ToInteger());
required.ErrorMessage = string.Format(CustomAttributeHelper.GetResourceText("Shared.Messages.MaximumLengthExceeded"), maxLength);
newAttributes.Add(required);
}
for (int i = 0; i < validators.Length; i++)
{
if (string. Equals(validators[i], "required", StringComparison.OrdinalIgnoreCase))
{
var required = new CustomRequiredAttribute();
newAttributes.Add(required);
}
else if (validators[i].StartsWith("email", StringComparison.OrdinalIgnoreCase))
{
var email = new CustomEmailAttribute();
newAttributes.Add(email);
}
}
}
return base.GetValidators(metadata,validatorProviders);
}
public static IDictionary<string, object> GetValidatorAttributes(string validators)
{
IDictionary<string, object> attributes = new Dictionary<string, object>();
string[] validatorList = !string.IsNullOrEmpty(validators) ? validators.Replace(" ", "").Split(',') : new string[] { };
foreach (var item in validatorList)
{
if (!attributes.Keys.Contains("data-val"))
{
attributes.Add("data-val", "true");
}
if (string.Equals(item, "required", StringComparison.OrdinalIgnoreCase))
{
attributes.Add("data-val-required", CustomAttributeHelper.GetResourceText("Shared.Messages.Mandatory"));
}
else if (item.StartsWith("email", StringComparison.OrdinalIgnoreCase))
{
attributes.Add("data-val-email", CustomAttributeHelper.GetResourceText("Shared.Messages.vEmailField"));
}
else if (item.StartsWith("phone", StringComparison.OrdinalIgnoreCase))
{
attributes.Add("data-val-phone", CustomAttributeHelper.GetResourceText("Shared.Messages.vPhoneField"));
}
else if (item.StartsWith("zipcode", StringComparison.OrdinalIgnoreCase))
{
attributes.Add("data-val-zipcode", CustomAttributeHelper.GetResourceText("Shared.Messages.vZipCodeField"));
}
else if (item.StartsWith("mark", StringComparison.OrdinalIgnoreCase))
{
string min = string.Empty;
string max = string.Empty;
string rangeValidatorMessage = string.Empty;
if (item.Contains("-"))
{
var rangeArray = item.Split('-');
if (rangeArray.Length > 2)
{
min = rangeArray[1];
max = rangeArray[2];
rangeValidatorMessage = CustomAttributeHelper.GetResourceText("Shared.Messages.NumberRange");
}
else
{
max = rangeArray[1];
rangeValidatorMessage = CustomAttributeHelper.GetResourceText("Shared.Messages.vNumericLimited");
}
}
else
{
max = "10000";
}
if (!string.IsNullOrWhiteSpace(min))
{
attributes.Add("data-val-range-min", min);
}
attributes.Add("data-val-range-max", max);
attributes.Add("data-val-range", rangeValidatorMessage);
}
else if (item.StartsWith("number", StringComparison.OrdinalIgnoreCase))
{
attributes.Add("data-val-number", CustomAttributeHelper.GetResourceText("Shared.Messages.NumberRange"));
}
else if (item.StartsWith("number", StringComparison.OrdinalIgnoreCase))
{
attributes.Add("data-val-decimal", string.Format(CustomAttributeHelper.GetResourceText("Shared.Messages.DecimalRange"), CustomAttributeHelper.GetResourceText("Shared.Limits.Decimal")));
}
else if (item.StartsWith("file-", StringComparison.OrdinalIgnoreCase))
{
attributes.Add("data-val-filetype", item.Split('-')[1]);
}
}
return attributes;
}
public void CreateValidators(ModelValidatorProviderContext context)
{
}
}
I have a controller that calls an api to get a list of Positions and Employees . First it puts the api results into a model class - IDMSElements (1). Then the controller takes the IDMSElements object and converts it to a PositionSlots object (2). Then the PositionSlots object needs to be updated with additional data from a database (3). So in simplified version of my controller I have:
(1) IDMSElements elements = getslots.CopyDocToElements(doc);
(2) PositionSlots myslots = (PositionSlots)elements;
(3) myslots.UpdateDetails(db);
I am concerned about the myslots.UpdateDetails(db) because additional code in the controller depends on UpdateDetails having been run. I would like the UpdateDetails to be run by default when creating the PositionSlots object. But I think multiple database calls in a constructor probably should not be done. How can I make it so the UpdateDetails is automatically invoked after the PositionSlots object is instantiated?
Thank you very much!
Controller:
[Authorize]
public class PSListController : Controller
{
private static readonly log4net.ILog _logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private PositionControlContext db = new PositionControlContext();
private GetPositionSlots getslots = new GetPositionSlots();
...
public async Task<ActionResult> ByCostCenter(int costCenter)
{
string ssapiuri = getslots.BuildAPIuri($"/current/?UDAKunit={costCenter.ToString()}");
_logger.Debug($"{ssapiuri.ToString()}");
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
HttpResponseMessage result = await getslots.GetDataFromIDMSapi(ssapiuri);
stopWatch.Stop();
_logger.Debug($"Response received. Milliseconds elapsed: {stopWatch.Elapsed.TotalMilliseconds.ToString()}");
if (result.StatusCode != HttpStatusCode.OK)
{
_logger.Debug("Error retrieving data from API. Milliseconds elapsed: " + stopWatch.Elapsed.TotalMilliseconds.ToString());
throw new HttpException(404, "NotFound");
}
stopWatch.Restart();
XDocument doc = XDocument.Load(result.Content.ReadAsStreamAsync().Result);
stopWatch.Stop();
_logger.Debug($"API result loaded into XDocument. Milliseconds elapsed: {stopWatch.Elapsed.TotalMilliseconds.ToString()}\n");
_logger.Debug(doc.ToString());
IDMSElements elements = getslots.CopyDocToElements(doc);
XMLDocStats docstats = new XMLDocStats(elements);
_logger.Debug(docstats.ToString());
PositionSlots myslots = (PositionSlots)elements;
myslots.UpdateDetails(db);
//because this is dependent upon UpdatePositionSlotId having been run
//need to find a way to force UpdateDetails to run other than calling from Controller??
var mainPositionSlots = myslots.PositionsCurrentAndActive;
var budget = db.Database.SqlQuery<Budget>("GetBudgetForCostCenter #costCenter = {0}", costCenter);
List<Budget> budgetRows = budget.ToList();
JobClassGroups jobClassGroups = new JobClassGroups(mainPositionSlots, budgetRows);
Department dept = db.Departments.AsNoTracking().Where(d => d.CostCenter == costCenter).SingleOrDefault();
var model = new ByCostCenter_vm(dept, myslots, jobClassGroups);
ViewBag.stats = docstats.ToString();
return View("ByCostCenter", model);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
IDMSElements Class:
public class IDMSElements
{
//properties
public ICollection<IDMSElementData> Elements { get; set; }
//constructors
public IDMSElements() { }
public IDMSElements(ICollection<IDMSElementData> elList)
{
Elements = elList;
}
//methods
public static explicit operator PositionSlots(IDMSElements obj)
{
//this is assuming we are looking at a list of elements
//that contains the "current" positions
Dictionary<string, PositionSlotDetail> positionSlots = new Dictionary<string, PositionSlotDetail>();
var sorted = from element in obj.Elements
orderby element.positionNbr
select element;
foreach (IDMSElementData el in sorted)
{
if (!positionSlots.ContainsKey(el.positionNbr))
{
PositionSlotDetail psd = new PositionSlotDetail
{
CostCenter = Int32.Parse(el.UDAKunit),
CostCenter_7Char = el.UDAKunit,
PositionNumber = el.positionNbr,
PositionSlotId = 0,
JobClassId = el.jobClassCode.Replace("-", ""),
JobClassFullDisplayCd = string.Empty,
JobTitle = string.Empty,
SalaryGradeCd = string.Empty,
FTE_percent = el.FTEpercent / 100,
EmployeeId = el.employeeID,
EmployeeName = String.Empty,
PositionEffDate = el.positionEffDate,
PositionEffDateNext = el.positionEffDateNext,
PositionBeginDate = el.positionBeginDate,
PositionEndDate = el.positionEndDate,
DirectLeaderID = string.Empty,
DirectLeaderName = string.Empty,
DirectLeaderNetID = string.Empty,
FLSAstatusCode = el.FLSAstatusCode,
FLSAstatusDesc = el.FLSAstatusDesc,
EmploymentTypeCode = el.employmentTypeCode,
EmploymentTypeDesc = el.employmentTypeDesc,
IsOverloaded = false,
};
positionSlots[el.positionNbr] = psd;
}
Assignment newAssignment = new Assignment
{
PvID = el.employeeID,
AssignBeginDate = el.assignBeginDate,
AssignEndDate = el.assignEndDate,
AssignEffDate = el.assignEffDate,
AssignEffDateNext = el.assignEffDateNext,
};
PositionSlotDetail thePSD = positionSlots[el.positionNbr];
thePSD.Assignments.Add(newAssignment);
if (thePSD.Assignments.Any(assignment => Regex.IsMatch(assignment.PvID, #"^\d+$")))
{
thePSD.Status = "FILLED";
if (thePSD.Assignments.Where(assignment => Regex.IsMatch(assignment.PvID, #"^\d+$")).Count() > 1)
{
thePSD.IsOverloaded = true;
}
}
else
{
thePSD.Status = "VACANT";
}
}
var output = new PositionSlots(positionSlots.Values.ToList());
return output;
}
...
}
PositionSlots class:
public class PositionSlots
{
//Constructor
public PositionSlots(ICollection<PositionSlotDetail> pslist)
{
Positions = pslist;
}
//properites
public ICollection<PositionSlotDetail> Positions { get; }
private bool DetailsUpdated { get; set; } = false;
public IEnumerable<PositionSlotDetail> PositionsCurrentAndActive
{
get
{
return from position in Positions
where position.PositionSlotId > 0 && position.PositionEndDate >= DateTime.Today
select position;
}
}
public IEnumerable<PositionSlotDetail> PositionsNotFoundInPositionControl
{
get
{
return from position in Positions
where position.PositionSlotId == 0
select position;
}
}
public IEnumerable<PositionSlotDetail> PositionsClosed
{
get
{
return from psd in Positions
where psd.PositionEndDate < DateTime.Today
&& psd.PositionSlotId > 0
select psd;
}
}
public decimal ActualFTETotal
{
get
{
return (from position in PositionsCurrentAndActive
from assignment in position.Assignments
where position.Assignments.Count() >= 1 && (!assignment.PvID.Equals("VACANT"))
select position.FTE_percent).Sum();
}
}
public int FilledTotal
{
get
{
return PositionsCurrentAndActive.Where(x => x.Status == "FILLED").Count();
}
}
public int VacantTotal
{
get
{
return PositionsCurrentAndActive.Where(x => x.Status == "VACANT").Count();
}
}
public int OverloadedTotal
{
get
{
return PositionsCurrentAndActive.Where(x => x.IsOverloaded).Count();
}
}
//methods
public void UpdateDetails(PositionControlContext db)
{
if (!DetailsUpdated)
{
UpdateJobClassificationInfo(db);
UpdateEmployeeName(db);
UpdatePositionSlotId(db); //if not found, PositionSlotId = 0
//UpdateIsBudgeted(db);
UpdateDirectLeader(db);
DetailsUpdated = true;
}
else
{
return;
}
}
private void UpdateJobClassificationInfo(PositionControlContext db)
{
string[] jobClassIds = (from x in Positions select x.JobClassId).Distinct().ToArray();
var JobClassList = (from jc in db.JobClassifications where jobClassIds.Contains(jc.JobClassId) select jc).ToDictionary(jc => jc.JobClassId, jc => jc, StringComparer.OrdinalIgnoreCase);
foreach (PositionSlotDetail psd in Positions)
{
if (!string.IsNullOrWhiteSpace(psd.JobClassId) && !psd.JobClassId.Equals("MISSING"))
{
JobClassification jobClassification;
if (JobClassList.TryGetValue(psd.JobClassId, out jobClassification))
{
psd.JobClassFullDisplayCd = jobClassification.JobClassFullDisplayCd;
psd.JobTitle = jobClassification.JobTitle;
psd.SalaryGradeCd = jobClassification.SalaryGradeCd;
}
else
{
psd.JobClassFullDisplayCd = ($"{psd.JobClassId} not found in view V_JobClassifications.");
psd.JobTitle = ($"{psd.JobClassId} not found in view V_JobClassifications.");
psd.SalaryGradeCd = "--";
}
}
else
{
psd.JobClassFullDisplayCd = "MISSING";
psd.JobTitle = "MISSING";
}
}
return;
}
private void UpdateEmployeeName(PositionControlContext db)
{
string[] empIdsStr = (from position in Positions
from assignment in position.Assignments
where (!assignment.PvID.Equals("VACANT"))
select assignment.PvID).Distinct().ToArray();
// Positions.SelectMany(x => x.Assignments).SelectMany(x => x.PvID).ToArray();
//string[] empIdsStr = (from x in Positions where (!x.EmployeeId.Contains("VACANT")) select x.EmployeeId).Distinct().ToArray();
//int[] empIdsInt = Array.ConvertAll(empIdsStr, int.Parse);
var EmployeeList = (from emp in db.IdAM_personLU where empIdsStr.Contains(emp.pvID) select emp).ToDictionary(emp => emp.pvID,
emp => emp.EmployeeFullName, StringComparer.OrdinalIgnoreCase);
EmployeeList["VACANT"] = "VACANT";
foreach (PositionSlotDetail psd in Positions)
{
string empName;
if (EmployeeList.TryGetValue(psd.EmployeeId, out empName))
{
psd.EmployeeName = empName;
}
else
{
psd.EmployeeName = ($"{psd.EmployeeId} not found in Employee table.");
}
foreach (Assignment emp in psd.Assignments)
{
string empName2;
if (EmployeeList.TryGetValue(emp.PvID, out empName2))
{
emp.EmpDisplayName = empName2;
}
else
{
emp.EmpDisplayName = ($"{psd.EmployeeId} not found in Employee table.");
}
}
}
return;
}
private void UpdateDirectLeader(PositionControlContext db)
{
string[] empIdsStr = (from x in Positions where (!x.EmployeeId.Contains("VACANT")) select x.EmployeeId).Distinct().ToArray();
//int[] empIdsInt = Array.ConvertAll(empIdsStr, int.Parse);
Dictionary<string, IdAM_arborLU> DirectLeader = new Dictionary<string, IdAM_arborLU>();
var EmployeeDirectLeaderList = (from emp in db.IdAM_arborLU where empIdsStr.Contains(emp.emp_pvID) select emp).ToDictionary(emp => emp.emp_pvID,
emp => emp, StringComparer.OrdinalIgnoreCase);
foreach (PositionSlotDetail psd in Positions)
{
if (psd.EmployeeId != "VACANT") //will just leave DirectLeaderId and DirectLeaderName as string.Empty
{
IdAM_arborLU supervisor;
if (EmployeeDirectLeaderList.TryGetValue(psd.EmployeeId, out supervisor))
{
psd.DirectLeaderName = supervisor.sup_name;
psd.DirectLeaderID = supervisor.sup_pvID;
psd.DirectLeaderNetID = supervisor.sup_netID;
}
else
{
psd.DirectLeaderName = ($"{psd.EmployeeId} not found in Arbor table.");
}
}
foreach (Assignment emp in psd.Assignments)
{
if (psd.EmployeeId != "VACANT")
{
IdAM_arborLU supervisor2;
if (EmployeeDirectLeaderList.TryGetValue(psd.EmployeeId, out supervisor2))
{
emp.DirectLeaderName = supervisor2.sup_name;
emp.DirectLeaderID = supervisor2.sup_pvID;
emp.DirectLeaderNetID = supervisor2.sup_netID;
}
else
{
emp.DirectLeaderName = ($"{psd.EmployeeId} not found in Arbor table.");
emp.DirectLeaderID = "--";
emp.DirectLeaderNetID = "--";
}
}
}
}
return;
}
private void UpdatePositionSlotId(PositionControlContext db)
{
string[] posnumber = (from x in Positions
select x.PositionNumber).ToArray();
var slots = (from ps1 in db.PositionSlots
where posnumber.Contains(ps1.PositionNumber)
select ps1).ToDictionary(ps => ps.PositionNumber.Trim(), ps => ps.PositionSlotId, StringComparer.OrdinalIgnoreCase);
foreach (PositionSlotDetail psd in Positions)
{
int posSlotId = 0;
if (slots.TryGetValue(psd.PositionNumber, out posSlotId))
{
psd.PositionSlotId = posSlotId;
}
}
return;
}
private void UpdateIsBudgeted(PositionControlContext db)
{
string[] posnumber = (from x in Positions
select x.PositionNumber).ToArray();
var slots = (from ps1 in db.PositionSlots
where posnumber.Contains(ps1.PositionNumber)
select ps1).ToDictionary(ps => ps.PositionNumber.Trim(), ps => ps.IsBudgeted, StringComparer.OrdinalIgnoreCase);
foreach (PositionSlotDetail psd in Positions)
{
bool isbudgeted = false;
if (slots.TryGetValue(psd.PositionNumber, out isbudgeted))
{
psd.IsBudgeted = isbudgeted;
}
}
return;
}
}
you can achieve this by writing a method:
IDMSElement.ToPositionSlot(db)
and then use it as follow:
PositionSlots myslots = elements.Select(x => x.ToPositionSlot(db))
I'm having trouble converting a Query Expression found here: http://www.oak3.org/crm/workflow-activity-checking-duplicate-instances/
into a linq query. To put it simply, the goal is if two workflows get triggered at the same time, only let one go through sorted by most recent. Currently my linq version will sometimes cancel a workflow even if it is the only one running. I know I need to utilize the input parameter somehow (to tell it what workflow to compare to), and I'm sure there could be more issues. Any help is greatly appreciated.
[Input("Current workflow")]
[ReferenceTarget("workflow")]
public InArgument<EntityReference> workflowReferenceInput { get; set; }
[Output("Is first workflow")]
public OutArgument<Boolean> isFirstWorkflow { get; set; }
protected override void Execute(CodeActivityContext executionContext)
{
ITracingService tracer = executionContext.GetExtension<ITracingService>();
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
try
{
Entity entity = (Entity)context.InputParameters["Target"];
isFirstWorkflow.Set(executionContext, false);
var wfReference = workflowReferenceInput.Get(executionContext);
var wfEntity = service.Retrieve("workflow", wfReference.Id, new ColumnSet ( "name" ));
ConditionExpression ce1 = new ConditionExpression();
ce1.AttributeName = "statuscode";
ce1.Operator = ConditionOperator.In;
ce1.Values.Add(0);
ce1.Values.Add(10);
ce1.Values.Add(20);
ce1.Values.Add(21);
ce1.Values.Add(22);
FilterExpression fe1 = new FilterExpression();
fe1.Conditions.Add(ce1);
QueryExpression qe = new QueryExpression();
qe.EntityName = AsyncOperation.EntityLogicalName;
qe.ColumnSet = new ColumnSet();
qe.Criteria = new FilterExpression();
qe.Criteria.AddFilter(fe1);
var childFilter = qe.Criteria.AddFilter(LogicalOperator.And);
childFilter.AddCondition("operationtype", ConditionOperator.Equal, 10);
childFilter.AddCondition("name", ConditionOperator.Equal, wfEntity["name"]);
LinkEntity link = new LinkEntity
{
LinkFromEntityName = AsyncOperation.EntityLogicalName,
LinkToEntityName = Quote.EntityLogicalName,
LinkFromAttributeName = "regardingobjectid",
LinkToAttributeName = "quoteid"
};
link.LinkCriteria.AddCondition("quoteid", ConditionOperator.Equal, context.PrimaryEntityId.ToString());
DataCollection<Entity> result = service.RetrieveMultiple(qe).Entities;
var list = result.ToList().OrderBy(c => c.Id);
for (var i = 0; i < list.Count(); i++)
{
var item = list.ElementAt(i);
if(item.Id == context.OperationId && i == 0)
{
isFirstWorkflow.Set(executionContext, true);
}
}
}
catch (Exception e)
{
throw new InvalidPluginExecutionException(e.Message);
}
}
into this:
public class WorkflowChecker: CodeActivity
{
[Input("Current workflow")]
[ReferenceTarget("workflow")]
public InArgument<EntityReference> workflowReferenceInput { get; set; }
[Output("Is first workflow")] public OutArgument<Boolean> isFirstWorkflow { get; set; }
protected override void Execute(CodeActivityContext executionContext)
{
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
try
{
var ok = WorkflowChecker(context.PrimaryEntityId, context.OperationId);
isFirstWorkflow.Set(executionContext, ok);
}
catch (Exception e)
{
throw new InvalidPluginExecutionException(e.Message);
}
}
}
which calls:
public static bool WorkflowChecker(Guid workflowContextId,
Guid asyncOperationId)
{
var someReturnValue = false;
var listOfWorkflowIds = new List<Guid>();
try
{
var query = from async in AsyncOperationSet
join b in BSet on async.RegardingObjectId.Id equals b.Id
where b.Id.Equals(workflowContextId)
&& (async.StateCode.Equals(0)
|| async.StateCode.Equals(1)
|| async.StateCode.Equals(2))
select new {async.AsyncOperationId};
foreach (var x in query)
{
if (x.AsyncOperationId != Guid.Empty)
{
listOfWorkflowIds.Add(x.AsyncOperationId.Value);
}
}
listOfWorkflowIds.Sort();
if (listOfWorkflowIds.First() == asyncOperationId)
{
someReturnValue = true;
}
}
catch (Exception e)
{
Console.WriteLine("Error in Workflow Checker: " + e);
}
return someReturnValue;
}
I've added the following lines to the workflow library then passed the parameter into the call to compare by name and so far it appears to be working successfully:
var wfReference = workflowReferenceInput.Get(executionContext);
var wfEntity = service.Retrieve("workflow", wfReference.Id, new ColumnSet("name"));
var test = wfEntity["name"];
Hi I'm trying to call the Get method in my CategoryController from my WareController. How would I do that.
I've tried this in my WareController
// GET: api/Ware?category=5
public List<WareDTO> GetByCategroy(int id)
{
BLLServiceGateway<List<WareDTO>> gate = new BLLServiceGateway<List<WareDTO>>();
var item = gate.Get(path + "?category=" + id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
public IHttpActionResult ViewItems(int id)
{
var model = new WareModel()
{
wares = GetByCategroy(id),
currentCategory = Redirect("api/category/" + id) /// This is were I want to get the category object
};
}
return Ok(model);
and my CategoryController looks like this
// GET: api/Categories/5
public CategoryDTO Get(int id)
{
BLLServiceGateway<CategoryDTO> gate = new BLLServiceGateway<CategoryDTO>();
var item = gate.Get(path + id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
API controller are just classes, so you easily can do this:
currentCategory = new CategoryController().Get(id);
But there may me problems if you want to deal with context.
I really need your help on this guys I am stuck and not sure where to start the fix. So i have this form where the user can select a case and parties. I am supposed save and pass along the values of the selected items. I was able to save the case selections but i am having trouble saving the selected party. Here is my code snippets regarding gathering data and saving them.
CONTROLLER:
[HttpPost]
[ValidateInput(false)]
public ActionResult Create(VisitViewModel viewModel, Guid[] associatedCasesSelected, Guid[] selectedParties)
{
if (!ModelState.IsValid)
{
viewModel.Time = _timeEntryHelper.Value;
AddLookupsToViewModel(viewModel);
return View(viewModel);
}
var visitEntry = Mapper.Map<VisitViewModel, VisitEntry>(viewModel);
visitEntry.VisitDate = _timeEntryHelper.AddTimeToDate(visitEntry.VisitDate);
visitEntry.UserId = _currentUser.UserId;
visitEntry.OfficeId = _currentUser.OfficeId;
try
{
_visitEntryService.Create(visitEntry, associatedCasesSelected, selectedParties);
this.FlashInfo(string.Format(Message.ConfirmationMessageCreate, Resources.Entities.Visit.EntityName));
}
catch (RulesException ex)
{
ex.CopyTo(ModelState);
}
if (ModelState.IsValid)
return RedirectToAction("Edit", "Case", new { caseId = viewModel.CaseId });
AddLookupsToViewModel(viewModel);
return View(viewModel);
}
VisitEntryService:
public void Create(VisitEntry visitEntry,IList<Guid>caseIds, IList<Guid>partyIds )
{
EnsureValid(visitEntry);
_visitEntryRepository.Save(visitEntry);
caseIds = AddCurrentCaseToCases(visitEntry.CaseId, caseIds,partyIds);
foreach (var caseId in caseIds.Distinct())
{
var visit = new Visit {CaseId = caseId, VisitEntryId = visitEntry.VisitEntryId};
_visitService.Create(visit);
}
}
VisitEntryRepository:
public void Save(VisitEntry visitEntry)
{
if (visitEntry.VisitEntryId == Guid.Empty)
{
visitEntry.VisitEntryId = Guid.NewGuid();
visitEntry.DateCreated = DateTime.Now;
DataContext.VisitEntries.InsertOnSubmit(visitEntry);
}
else
{
var currentVisitEntry = Get(visitEntry.VisitEntryId);
if (currentVisitEntry == null) throw RepositoryExceptionFactory.Create("VisitEntry", "VisitEntryId");
currentVisitEntry.DateModified = DateTime.Now;
currentVisitEntry.VisitDate = visitEntry.VisitDate;
currentVisitEntry.VisitType =
DataContext.VisitTypes.SingleOrDefault(vt => vt.VisitTypeId == visitEntry.VisitTypeId);
currentVisitEntry.Note = visitEntry.Note;
}
DataContext.SubmitChanges();
}
I am not sure how to get this to save the selected party as it is saving the case information and selected case. Thanks for any feedback!
The save call is a bit earlier so your changes made after your fire SubmitChanges, move the SubmitChanges to the end you should good to go I believe
UPDATE
what I mean is change code like following and see if that helps
CONTROLLER:
[HttpPost]
[ValidateInput(false)]
public ActionResult Create(VisitViewModel viewModel, Guid[] associatedCasesSelected, Guid[] selectedParties)
{
if (!ModelState.IsValid)
{
viewModel.Time = _timeEntryHelper.Value;
AddLookupsToViewModel(viewModel);
return View(viewModel);
}
var visitEntry = Mapper.Map<VisitViewModel, VisitEntry>(viewModel);
visitEntry.VisitDate = _timeEntryHelper.AddTimeToDate(visitEntry.VisitDate);
visitEntry.UserId = _currentUser.UserId;
visitEntry.OfficeId = _currentUser.OfficeId;
try
{
_visitEntryService.Create(visitEntry, associatedCasesSelected, selectedParties);
this.FlashInfo(string.Format(Message.ConfirmationMessageCreate, Resources.Entities.Visit.EntityName));
DataContext.SubmitChanges();
}
catch (RulesException ex)
{
ex.CopyTo(ModelState);
}
if (ModelState.IsValid)
return RedirectToAction("Edit", "Case", new { caseId = viewModel.CaseId });
AddLookupsToViewModel(viewModel);
return View(viewModel);
}
VisitEntryRepository:
public void Save(VisitEntry visitEntry)
{
if (visitEntry.VisitEntryId == Guid.Empty)
{
visitEntry.VisitEntryId = Guid.NewGuid();
visitEntry.DateCreated = DateTime.Now;
DataContext.VisitEntries.InsertOnSubmit(visitEntry);
}
else
{
var currentVisitEntry = Get(visitEntry.VisitEntryId);
if (currentVisitEntry == null) throw RepositoryExceptionFactory.Create("VisitEntry", "VisitEntryId");
currentVisitEntry.DateModified = DateTime.Now;
currentVisitEntry.VisitDate = visitEntry.VisitDate;
currentVisitEntry.VisitType =
DataContext.VisitTypes.SingleOrDefault(vt => vt.VisitTypeId == visitEntry.VisitTypeId);
currentVisitEntry.Note = visitEntry.Note;
}
}