So im a bit stuck. I'm still learning all this stuff., but I had to add a csv parser to my application, which should display the results on the my alerts page. If I do
return PartialView(model, pin, tDate, stat);
It will tell me pin, tDate and stat does not exist in the current context. If I take them out, the app will run, but doesn't display the intended result.
I declared pin, tDate and stat in the UserADInfoModel.cs
here is the controller:
public ActionResult _Alerts(UserADInfoModel model, List<string> groups)
{
DataRowCollection drColl = Core.GetAlerts(model);
ViewBag.Alerts = drColl;
var path = #"Exchange Migration data 10-25-17.csv";
using (TextFieldParser csvParser = new TextFieldParser(path))
{
csvParser.CommentTokens = new string[] { "#" };
csvParser.SetDelimiters(new string[] { "," });
csvParser.HasFieldsEnclosedInQuotes = true;
// Skip the row with the column names
csvParser.ReadLine();
// Read the lines
while (!csvParser.EndOfData)
{
string[] fields = csvParser.ReadFields();
string pin = fields[0];
string tDate = fields[2];
string stat = fields[6];
}
}
return PartialView(model, pin, tDate, stat);
}
and here is the view
#if (#ViewBag.pin == Model.SAM)
{
<tr style="background-color : #ff3333; color: #ffffff">
<td style="padding-left :10px; padding-right: 10px;padding-top:2px; padding-bottom: 2px">
<p>Critical</p>
</td>
<td style="padding-left :10px; padding-right: 10px;padding-top:2px; padding-bottom: 2px">
<p>Exchange Migration</p>
</td>
<td style="padding-left :10px; padding-right: 10px;padding-top:2px; padding-bottom: 2px">
<p>Caller was set to migrate on (#ViewBag.tDate). The status of the migration is (#ViewBag.stat). Please contact Hypercare</p>
</td>
</tr>
}
#foreach (var x in ViewBag.Alerts)
{
var uClass = (x["Weight"].Contains("Warning")) ? "#ff8c1a, " : (x["Weight"].Contains("Critical")) ? "#ff3333" : "";
<tr #if (x["Weight"].Contains("Warning")) {
#MvcHtmlString.Create("style=\"background-color: #ff8c1a\"")
}
else if(x["Weight"].Contains("Critical")){
#MvcHtmlString.Create("style=\"background-color: #ff3333; color: #ffffff\"")
}>
what am I doing wrong? TIA
You declared pin, tDate and stat inside the while scope.
Decide if you want to use model (recommended) or ViewBag to pass data:
public ActionResult _Alerts(UserADInfoModel model, List<string> groups)
{
DataRowCollection drColl = Core.GetAlerts(model);
ViewBag.Alerts = drColl;
var path = #"Exchange Migration data 10-25-17.csv";
using (TextFieldParser csvParser = new TextFieldParser(path))
{
// ...
while (!csvParser.EndOfData)
{
string[] fields = csvParser.ReadFields();
model.pin = fields[0];
model.tDate = fields[2];
model.stat = fields[6];
}
}
return PartialView(model);
}
_Alerts.cshtml:
#model UserADInfoModel
#if (#Model.pin == Model.SAM)
// ...
// ... #Model.tDate ... #Model.stat ...
Related
I have a controller with two actions. One action is simply a post that updates the database. The other is the view model. However in my action that updates the database I return it back to the original view with the view model.
public ActionResult ManageMxieUsers()
{
var model = from el in aphdb.view_EmployeeList
join p in aphdb.MxieCallRevPermissions on el.Id equals p.AspNetUserUserID into gj
from sub in gj.DefaultIfEmpty()
select new vm_ManageMxieUsers { Id = el.Id, UserName = el.UserName, PermissionLevel = sub.PermissionLevel, MxieCallRevPermCustomList = aphdb.MxieCallRevPermCustomList.Where(w => w.PermissionID == sub.PermissionID ) };
ViewBag.EmployeeList = aphdb.view_EmployeeList.OrderBy(o => o.UserName);
return View(model);
}
This part works perfectly.
Here is my post method:
[HttpPost]
public ActionResult ManageMxieUsers(string userID, Int16 permissionLevel, List<string> customUserList)
{
var UserToEdit = aphdb.MxieCallRevPermissions.Where(w => w.AspNetUserUserID == userID).FirstOrDefault();
if (UserToEdit == null)
{
MxieCallRevPermissions addPerm = new MxieCallRevPermissions();
addPerm.AspNetUserUserID = userID;
addPerm.PermissionLevel = permissionLevel;
aphdb.MxieCallRevPermissions.Add(addPerm);
aphdb.SaveChanges();
if (permissionLevel == 3)
{
foreach (var id in customUserList)
{
MxieCallRevPermCustomList list = new MxieCallRevPermCustomList();
list.PermissionID = addPerm.PermissionID;
list.AspNetUserID = id;
aphdb.MxieCallRevPermCustomList.Add(list);
}
}
aphdb.SaveChanges();
#ViewBag.Success = true;
}
else
{
UserToEdit.PermissionLevel = permissionLevel;
aphdb.SaveChanges();
if (permissionLevel == 3)
{
// Remove old custom list
var customList = aphdb.MxieCallRevPermCustomList.Where(w => w.PermissionID == UserToEdit.PermissionID).ToList();
aphdb.MxieCallRevPermCustomList.RemoveRange(customList);
aphdb.SaveChanges();
foreach (var id in customUserList)
{
MxieCallRevPermCustomList list = new MxieCallRevPermCustomList();
list.PermissionID = UserToEdit.PermissionID;
list.AspNetUserID = id;
aphdb.MxieCallRevPermCustomList.Add(list);
}
aphdb.SaveChanges();
}
else
{
// Remove old custom list
var customList = aphdb.MxieCallRevPermCustomList.Where(w => w.PermissionID == UserToEdit.PermissionID).ToList();
aphdb.MxieCallRevPermCustomList.RemoveRange(customList);
aphdb.SaveChanges();
}
aphdb.SaveChanges();
#ViewBag.Success = true;
}
//aphdb.SaveChangesAsync(); // Testing ot make sure SaveChanges fired before this code.
var model = from el in aphdb.view_EmployeeList
join p in aphdb.MxieCallRevPermissions on el.Id equals p.AspNetUserUserID into gj
from sub in gj.DefaultIfEmpty()
select new vm_ManageMxieUsers { Id = el.Id, UserName = el.UserName, PermissionLevel = sub.PermissionLevel, MxieCallRevPermCustomList = aphdb.MxieCallRevPermCustomList.Where(w => w.PermissionID == sub.PermissionID) };
ViewBag.EmployeeList = aphdb.view_EmployeeList.OrderBy(o => o.UserName);
//return RedirectToAction("ManageMxieUsers"); // WORKS
return View("ManageMxieUsers", model); // ERROR NULL on AspNetUser
}
Now when I simply return View("ManageMxieUsers", model); The error comes back saying AspNetUsers is null. However when I reload this page it works just fine. When I return RedirectToAction("ManageMxieUsers"); I get no error, but of course I lose my ViewBag.
My only guess is that aphdb.SaveChanges() is not reflected instantly? Even tho I can perform a SQL query to the database and see the data has indeed been added/updated. As is referenced by reloading the current page.
So I'm at a loss as to why during this post method my view model portion comes up with null entries, but when I reload it they are populated normally.
I'm fine with leaving it as RedirectToAction, but would like to maybe understand better as to why this behavior is making it work.
Here is the view portion that breaks
<tbody>
#{ int? permissionLevel; }
#foreach (var user in Model)
{
permissionLevel = user.PermissionLevel ?? 4;
<tr>
<td>#user.Id</td>
<td>
#user.UserName
</td>
<td>#permissionLevel</td>
<td>
#foreach (var customUser in user.MxieCallRevPermCustomList)
{
#("[" + customUser.AspNetUsers.FirstName + " " + customUser.AspNetUsers.Lastname + "] ")
}
</td>
</tr>
}
</tbody>
the customUser.AspNetUsers = null when I use return View("ManageMxieUsers", model); in my [HttpPost] method.
I have created Audit trail and it works fine. you can see all the changes and even the name of the table edited. Now i want to display changes on the popup. Once the user edit some fields, i want to display fieldname,oldvalue,newvalue,username and date.Only once you click on the balloon.
I have no idea on how i can do that. I have implemented the balloon which you can click and view the changes but it doesn't work.
How can i display all the changes on the balloon
Ballon i have created: i have customize it the way i want it if there's an edit
<div class="small-chat-box fadeInRight animated">
<div class="left">
<div class="author-name">
Claim Edit <small class="chat-date">
<br>09-06-2016 12:00 pm
</small>
</div>
<div class="chat-message active">
Username: JJ
<br>fieldname: Surname
<br>oldvalue: small
<br>newvalue big
<br>date: #DateTime.Now
</div>
</div>
</div>
my audit method which works fine
public static List<ClaimAudit> GetClaimLog(SidDbContext db, int claimId)
{
--------------------
foreach (var entry in changeTrack)
{
if (entry.Entity != null)
{
string entityName = string.Empty;
string state = string.Empty;
switch (entry.State)
{
case EntityState.Modified:
entityName = ObjectContext.GetObjectType(entry.Entity.GetType()).Name;
state = entry.State.ToString();
foreach (string prop in entry.OriginalValues.PropertyNames)
{
object currentValue = entry.CurrentValues[prop];
object originalValue = entry.OriginalValues[prop];
if (!currentValue.Equals(originalValue))
{
ClaimLogs.Add(new ClaimAudit
{
tableName = entityName,
state = state,
fieldName = prop,
oldValue = Convert.ToString(originalValue),
newValue = Convert.ToString(currentValue),
userId = "JJ",
UpdateDate = DateTime.Now,
CommentsId = 1,
ClaimId = claimId
});
}
}
break;
}
}
}
calling my update function on save
public async Task<bool> UpdateClaimVehicle(ClaimVehicle vehicleModel)
{
List<ClaimAudit> ClaimLogs = new List<ClaimAudit>();
using (IBaseDataRepository<ClaimVehicle> bs = new BaseRepository<ClaimVehicle>())
{
using (SidDbContext db = new SidDbContext())
{
if (vehicleModel != null)
{
var oldClaim = db.ClaimVehicles.FirstOrDefault(x => x.ClaimId == vehicleModel.ClaimId);
oldClaim.VehicleMakeModelId = vehicleModel.VehicleMakeModelId;
oldClaim.VehicleRegistrationNumber = vehicleModel.VehicleRegistrationNumber;
oldClaim.VehicleYearModel = vehicleModel.VehicleYearModel;
oldClaim.VinNumber = vehicleModel.VinNumber;
ClaimLogs = GetClaimLog(db, oldClaim.ClaimId);
db.claimAuditLog.AddRange(ClaimLogs);
db.SaveChanges();
}
return true;
}
}
}
Here i was trying to display it on the view first,but it says model does not exist
#model Business.Models.ClaimDetailsModel
#foreach (var item in Model) //error here
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ClaimId)
</td>
</tr>
}
I'm currently working on an "Activity Report" application on a first year internship, where employees can select a specific project and assign how many hours they have worked on it per day.
The selection of projects (depending on the employees id) and the display of the page seem to be working. But here's my problem : once I click on the displayed image that is supposed to submit the form - it seems to reload the page as if nothing happened !
The View line of the submission is as following :
<% using (Html.BeginForm("ActivityInputCreate", "Project"))
{ %>
[...]
<td>
<input type="image" style="border: 0; width: 16px;" src="../../Content/Black_16x16/Save.png" onclick="this.form.submit" alt="save" />
<input type="image" style="border: 0; width: 16px;" src="../../Content/Black_16x16/Cancel.png" onclick=" window.location.href = '/Project/ActivityInputIndex'; return false;" alt="cancel" /></td>
<!-- the first line being to save and the second to cancel -->
<td>
}
I don't know how to handle a form submission but here's the controller (the first of the same name being the non [HttpPost] one :
[HttpPost]
public ActionResult ActivityInputCreate(Project objToCreate, FormCollection form)
{
string year = form["Years"];
int iyear = int.Parse(year);
string month = form["Months"];
int imonth = int.Parse(month);
string strUser = Environment.UserName.ToLower();
CalendarController c = new CalendarController();
ViewBag.ListYears = c.ListYears(iyear);
ViewBag.ListMonths = c.ListMonths(imonth);
ViewBag.ListDaysOfMonth = _service.ListDaysOfMonth(iyear.ToString(), imonth.ToString());
//nea11
Session["ActivityInputYear"] = iyear.ToString();
Session["ActivityInputMonth"] = imonth.ToString();
ProjectResourceManagerService pr = new ProjectResourceManagerService(new ModelStateWrapper(this.ModelState));
ViewBag.ProjectList = pr.ListProject();
List<IEnumerable<SelectListItem>> ddlists = new List<IEnumerable<SelectListItem>>();
foreach (string s in ViewBag.ListDaysOfMonth)
ddlists.Add(_service.ListHours(0)); //id de UserActivity à la place de 0
ViewBag.ddlists = ddlists;
//nea12
string strProject = form["Project"];
//nea13
string strSep = ";";
string strDatas = "";
int l = 0;
foreach (var jour in ViewBag.ListDaysOfMonth)
{
string nom = "Hours" + l.ToString();
strDatas += form[nom] + strSep;
l++;
}
//ajout dans la base
UserActivityDb db = new UserActivityDb(#"metadata=res://*/Models.CRA.csdl|res://*/Models.CRA.ssdl|res://*/Models.CRA.msl;provider=Microsoft OLE DB Provider for SQL server;provider connection string="data source=(local)\SQLEXPRESS;initial catalog=CRAV34;persist security info=True;user id=sa;password=as0;multipleactiveresultsets=True;App=EntityFramework"");
if (null != strProject)
db.setFormattedData(iyear, imonth, ViewBag.ListDaysOfMonth, int.Parse(strProject), strUser, strDatas, true);
IEnumerable<Project> lp = _service.List(strUser, iyear.ToString(), imonth.ToString());
lp = lp.Where(p => (true == db.ExistUserActivity(iyear, imonth, ViewBag.ListDaysOfMonth, p.ProjectId, strUser)));
//nea35
List<string[]> lstInts = new List<string[]>();
foreach (Project p in lp)
{
string strInts = db.getFormattedData(iyear, imonth, ViewBag.ListDaysOfMonth, p.ProjectId, strUser, null, 0);
string[] ints = strInts.Split(';');
lstInts.Add(ints);
}
ViewBag.ProjectInts = lstInts;
return View("ActivityInputIndex", lp);
}
I'd love to give you more precision but please keep in mind that most of the code isn't mine and is the last interns'.
TL;DR : Display of the page is fine, I want to submit once the DropDownList are filled, submission button doesn't do anything.
Thank you.
Turns out the issue came with the input of my username (through the SQL INSERT).
string strUser = User.Identity.Name;
Is used with :
command.Parameters.Add("#Login", SqlDbType.VarChar, 50).Value = sLogin;
And works just fine. The issue was not with the sending of a form (which it did receive) but the way the SQL request was built.
i am tring to get som data, from a html string using HTML Agility pack.
The row string[] i am trying to get the data from returns innerhtml like this:
<td class="street">Riksdagen</td>
<td class="number"> </td>
<td class="number"> </td>
<td class="postalcode">100 12</td>
<td class="locality">Stockholm</td>
<td class="region_code">018001</td>
<td class="county">Stockholm</td>
<td class="namnkommun">Stockholm</td>
How can i assign each class to the right addressDataModel propery?
var row = doc.DocumentNode.SelectNodes("//*[#id='thetable']/tr");
foreach (var rowItem in row)
{
var addressDataModel = new AddressDataModel
{
street = rowItem.FirstChild.InnerText,
zipCodeFrom = // Next item,
zipCodeTo = // Next item,
zipCode = // Next item,
locality = // Next item,
regionCode = // Next item,
state = // Next item,
county = // Next item
};
}
You can write something like this (make sure the node exists before use InnerText prop):
var addressDataModel = new AddressDataModel
{
street = rowItem.SelectSingleNode("./td[#class='street']").InnerText,
zipCodeFrom = // Next item,
zipCodeTo = // Next item,
zipCode = // Next item,
locality = // Next item,
regionCode = // Next item,
state = // Next item,
county = rowItem.SelectSingleNode("./td[#class='county']").InnerText
};
Reference: http://www.w3schools.com/xpath/xpath_syntax.asp
You can also refer to this if you don't want to use Xpath :
HtmlAgilityPack.HtmlDocument htmlContent = new HtmlAgilityPack.HtmlDocument();
htmlContent.LoadHtml(htmlCode);
if (htmlContent.DocumentNode != null)
{
foreach (HtmlNode n in htmlContent.DocumentNode.Descendants("div"))
{
if (n.HasAttributes && n.Attributes["class"] != null)
{
if (n.Attributes["class"].Value == "className")
{
// Do something
}
}
}
}
I have a table like this
<table border="0" cellpadding="0" cellspacing="0" id="table2">
<tr>
<th>Name
</th>
<th>Age
</th>
</tr>
<tr>
<td>Mario
</td>
<th>Age: 78
</td>
</tr>
<tr>
<td>Jane
</td>
<td>Age: 67
</td>
</tr>
<tr>
<td>James
</td>
<th>Age: 92
</td>
</tr>
</table>
And want to use HTML Agility Pack to parse it. I have tried this code to no avail:
foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//table[#id='table2']//tr"))
{
foreach (HtmlNode col in row.SelectNodes("//td"))
{
Response.Write(col.InnerText);
}
}
What am I doing wrong?
Why don't you just select the tds directly?
foreach (HtmlNode col in doc.DocumentNode.SelectNodes("//table[#id='table2']//tr//td"))
Response.Write(col.InnerText);
Alternately, if you really need the trs separately for some other processing, drop the // and do:
foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//table[#id='table2']//tr"))
foreach (HtmlNode col in row.SelectNodes("td"))
Response.Write(col.InnerText);
Of course that will only work if the tds are direct children of the trs but they should be, right?
EDIT:
var cols = doc.DocumentNode.SelectNodes("//table[#id='table2']//tr//td");
for (int ii = 0; ii < cols.Count; ii=ii+2)
{
string name = cols[ii].InnerText.Trim();
int age = int.Parse(cols[ii+1].InnerText.Split(' ')[1]);
}
There's probably a more impressive way to do this with LINQ.
I've run the code and it displays only the Names, which is correct, because the Ages are defined using invalid HTML: <th></td> (probably a typo).
By the way, the code can be simplified to only one loop:
foreach (var cell in doc.DocumentNode.SelectNodes("//table[#id='table2']/tr/td"))
{
Response.Write(cell.InnerText);
}
Here's the code I used to test: http://pastebin.com/euzhUAAh
I had to provide the full xpath. I got the full xpath by using Firebug from a suggestion by #Coda (https://stackoverflow.com/a/3104048/1238850) and I ended up with this code:
foreach (HtmlNode row in doc.DocumentNode.SelectNodes("/html/body/table/tbody/tr/td/table[#id='table2']/tbody/tr"))
{
HtmlNodeCollection cells = row.SelectNodes("td");
for (int i = 0; i < cells.Count; ++i)
{
if (i == 0)
{ Response.Write("Person Name : " + cells[i].InnerText + "<br>"); }
else {
Response.Write("Other attributes are: " + cells[i].InnerText + "<br>");
}
}
}
I am sure it can be written way better than this but it is working for me now.
I did the same project with this:
private List<PhrasalVerb> ExtractVerbsFromMainPage(string content)
{
var verbs =new List<PhrasalVerb>(); ;
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(content);
var rows = doc.DocumentNode.SelectNodes("//table[#class='idioms-table']//tr");
rows.RemoveAt(0); //remove header
foreach (var row in rows)
{
var cols = row.SelectNodes("td");
verbs.Add(new PhrasalVerb {
Uid = Guid.NewGuid(),
Name = cols[0].InnerHtml,
Definition = cols[1].InnerText,
Count =int.TryParse(cols[2].InnerText,out _) == true ? Convert.ToInt32(cols[2].InnerText) : 0
});
}
return verbs;
}
private List<Table1> getTable1Data(string result)
{
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(result);
var table1 = htmlDoc.DocumentNode.SelectNodes("//table").First();
var tbody = table1.ChildNodes["tbody"];
var lst = new List<Table1>();
foreach (var row in tbody.ChildNodes.Where(r => r.Name == "tr"))
{
var tbl1 = new Table1();
var columnsArray = row.ChildNodes.Where(c => c.Name == "td").ToArray();
for (int i = 0; i < columnsArray.Length; i++)
{
if (i == 0)
tbl1.Course = columnsArray[i].InnerText.Trim();
if (i == 1)
tbl1.Count = columnsArray[i].InnerText.Trim();
if (i == 2)
tbl1.Correct = columnsArray[i].InnerText.Trim();
}
lst.Add(tbl1);
}
return lst;
}
public class Table1
{
public string Course { get; set; }
public string Count { get; set; }
public string Correct { get; set; }
}