Some types of work item updates require the updating account to be in the “Project Collection Service Accounts” group. For example, the work item server - var wiSrv = tpc.GetService<WorkItemServer>();
You have to use the command line to do this. Here’s an example:
tfssecurity /g+ "Project Collection Service Accounts" n:{domain\user} /collection:{your collection url}
In a discussion about software product versioning, the post on Semantic Versioning came up. I found the essay to reflect commonly recognized best practices. However, the value of the essay is in the concise and rigorous rules for incrementing version numbers.
I believe this is a bug where only the checkbox value is not retained when passing the model from the view to a post method.
Model
public bool CoreField { get; set; }
View
@model List<Model>
@Html.CheckBoxFor(m => m[i].CoreField,
new { @id = "cbCoreField" + i })@Html.HiddenFor(m => m[i].CoreField)
@Html.Hidden("fIsCore",
null, new { @id = "hIsCore" + i })
//has to use separate list instead of model due to MVC bug
Note the use of “fIsCore” as a separate list used to pass changes to the checkbox into the post method and the use of ModelState.SetModelValue to set the checkbox value for redisplay when the model is invalid (i.e. adding a row where the model validation rules for some other field has been violated.
Controller Post Method
[HttpPost]
public ActionResult Index(List<Model> model, List<bool> fIsCore)
{
if (!(model == null))
{
if (ModelState.IsValid)
{
int i = 0;
foreach (var item in model)
{
item.CoreField = fIsCore[i];
i++;
if (!(item.ID == 0))
{
db.Entry(item).State = EntityState.Modified;
}
else
{
db.Model.Add(item);
}
}
db.SaveChanges();
}
else
{
//ModelState.Clear(); // not needed now
int i = 0;
foreach (var item in model)
{
string key = string.Format("[{0}].CoreField", i);
item.CoreField = fIsCore[i];
ModelState.SetModelValue(key,
new ValueProviderResult(item.CoreField,
"",
CultureInfo.InvariantCulture));
i++;
}
return View(model);
}
}
return RedirectToAction("Index");
}
I found that using a loop activity to build up a filtered list clutters up the build report with repetitions of activities inside the loop. I could write a custom activity to create the list. However, rather than have to write and maintain code, it’s possible to use the DOS DIR command in the Invoke Process activity.
First, because there is no dir.exe file, you must execute a windows shell. I used “cmd” as the FileName value.
Then in the Arguments value I use the shell /c switch followed by the DIR command. It’s also possible to exclude file types from the list.
String.Format("{0} ""{1}"" {2}", "/c dir", BinariesDirectory, "/b |findstr /vi "".zip""")
I’m an MVC/jQuery noobie and this one really got my goat for while. The problem was handling the bit field in SQL Server which was treated as a checkbox field in MVC.
Here’s how you can set a checkbox value based the the user’s selection from dropdown list on the same view:
Model:
public string Field_Ref_Name { get; set; } // the dropdown list
public bool CoreField { get; set; } // the checkbox
Controller:
From the Get ActionResult method to populate the dropdown list.
ViewBag.projectConditionWitRefFieldsDropdownList =
new SelectList(refFieldList, selectedField);
The JsonResult method called by the jQuery script in the view.
public JsonResult GetFieldAttributes(string selectedField)
{
string a = selectedField;
bool b = false;
if (!(selectedField.Contains("some value")))
{
b = true;
}
var dataParms = new { aA = a, aB = b };
return Json(dataParms, JsonRequestBehavior.AllowGet);
}
View:
The script, which gets the bool from the Json result and sets the checkbox. Note I had to use the “click” event to set the checkbox. All efforts to use some sort of checked true or false approach failed. The trick is the conditional logic of the data.aB boolean return value.
<script type="text/javascript">
$(function() {
$("#ddlField").change(function() {
var selectedItem = $(this).val();
$.ajax({
cache: false,
type: "GET",
url: "@(Url.Action("GetFieldAttributes", "ConditionDetails"))",
data: { "selectedField": selectedItem},
success: function (data) {
$("#DataType").val(data.aA);
if (data.aB) {
var chk = $('#CoreField').is(':checked');
if (!(chk)) {
$("#CoreField").click();
}
}
else {
var chk = $('#CoreField').is(':checked');
if (chk) {
$("#CoreField").click();
}
}
},
error:function (xhr, ajaxOptions, thrownError){
alert('Failed to return core and type field attributes.');
}
});
});
});
</script>
From the razor code to display the page.
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<fieldset>
<legend>Condition_Details</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Field_Ref_Name)
</div>
<div class="editor-field">
@if (@ViewBag.projectFilterSelected)
{
@Html.DropDownListFor(model => model.Field_Ref_Name,
ViewBag.projectConditionWitRefFieldsDropdownList as SelectList,
string.Empty, new { @id = "ddlField", style = "font-size: .85em; font-weight: normal;" })
}
else
{
@Html.EditorFor(model => model.Field_Ref_Name)
}
@Html.ValidationMessageFor(model => model.Field_Ref_Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.DataType)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.DataType)
@Html.ValidationMessageFor(model => model.DataType)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.CoreField)
</div>
<div class="editor-field">
@Html.CheckBoxFor(model => model.CoreField)
@Html.ValidationMessageFor(model => model.CoreField)
</div>
</fieldset>
}
When a table name uses a reserved word: for example, “Action,” model validation will fail even though the model is valid. The error message from ModelState is:
“The parameter conversion from type 'System.String' to… …type failed because no type converter can convert between these types.”
For example, if a table named Action has a related table, Action_Details, where an Action may have one to many Action_Conditions, you may have a model class for Action_Details that looks like this:
public class Action_Details
{
public int ID { get; set; }
public int Action_ID { get; set; }
public string Value { get; set; }
public string ParentField { get; set; }
public string ChildField { get; set; }
public Nullable<bool> Inherit { get; set; }
public virtual Action Action { get; set; }
}
My solution was to change the related table class
public class Action_Details
{
public int ID { get; set; }
public int Action_ID { get; set; }
public string Value { get; set; }
public string ParentField { get; set; }
public string ChildField { get; set; }
public Nullable<bool> Inherit { get; set; }
//public virtual Action Action { get; set; }
// ** as "Action" is a reserved word, I had to use the
// ** fully qualified class name (i.e. UI.Models.Action)
// ** AND change the object name from Action to Action1
public virtual UI.Models.Action Action1 { get; set; }
}
Using a MVC 4 Code First project I noticed that my intermediate table between a many to many relationship was missing. In other words, Table 1 has many Table 3, and Table 3 has many Table 1. In the database schema, Table 2 is my intermediate table:
- Table 1 has many Table 2 and Table 2 has only one Table1
- Table 3 has many Table 2 and Table 2 has only one Table3, as follows:
However, as I stated earlier, I did not have a model class for Table 2. At first I was miffed, but once I was able to craft the query, I was impressed at how easy EF made this. I wanted to get a listing of Table 3 fields for a specific ProjectID (pID) in Table 1. Here’s the query :)
var Table3Qry = from t3 in db.Table3
from t2 in t3.Table1.Where(x => x.ProjectID == pID)
select new { t3.foo1, t3.foo2, t3.foo3 };
Here are some FAQs on things that were not so obvious. I’ll continue to add to this list over time.
1. Passing HtmlAttributes using @Html.ActionLink
@Html.ActionLink("Create New", "Create", null,
new { style="font-size: .75em; font-weight: normal; padding-left: 15px;" })
2. Html.EditFor with multiline and word wrap support
Use the following data annotation in the model class:
[DataType(DataType.MultilineText)]
public string TextField { get; set; }
This requies the following using statement in the model class:
using System.ComponentModel.DataAnnotations;
Multi-line and word wrap is rendered in the view without any further changes in the controller and view.
3. Pass a variable when using return RedirectToAction
return RedirectToAction("Index", null, new { foo = "some value" });
4. Insert a row and link
This was a frustrating problem that took me some time to resolve. However, the solution is very simple.
See this posting on the ASP.NET MVC forum.
5. Attach existing many-to-many entities using LINQ in the post method
I couldn’t quickly find a simple guide to help me with these basic operations.
It took me a while to work out the solution.
public ActionResult Attach(List<Class> classList, int studentID, string command)
{
if (ModelState.IsValid)
{
int l = command.IndexOf(" ");
int clickedClassID = Int32.Parse(command.Substring(0, l));
var condition = db.Conditions.Find(conditionID);
foreach (var class in classList)
{
if (class.ID == clickedClassID )
if (command.Contains("Attach"))
{
//not sure why I needed to declare the following 2 variables,
//but otherwise it didn't work
var existingClass = db.Classes.SingleOrDefault(x => x.ID == class.ID);
var existingStudent = db.Students.First(x => x.ID == studentID);
existingClass.Students.Add(existingStudent);
db.Classes.Attach(existingClass);
db.Entry(existingClass).State = EntityState.Modified;
db.Entry(existingStudent).State = EntityState.Modified;
db.SaveChanges();
}
else
}
}
return View(db.Classes.ToList());
}
6. Creating local variables in the view from the ViewBag for use in JQuery
<script>
var someStringValue = '@(ViewBag.someStringValue)';
var someNumericValue = @(ViewBag.someNumericValue);
</script>
7. Add a New Row to an Editable Index View
see Stackoverflow at:
http://stackoverflow.com/questions/15249466/mvc-4-partialviewresult-return-partialview-calls-wrong-view-url
Controller
ViewData["Projects"] = new SelectList(db.Projects.Select(r => r.ProjectName));
View
@Html.DropDownList("Projects")
There were many complicated examples, but this worked for me. However, I needed to pull from a database and manipulate the data before populating the dropdown. Here’s what I ended up with:
Controller
//retrieve the list of projects from the projects table
var ProjectQry = (from p in db.Projects orderby p.Project_Name
select new { projectName = p.Project_Name, ID = p.ID }).ToList();
//format project name and ID into single field
var projectList = from p in ProjectQry
select new { project = p.projectName + " (" + p.ID + ")" };
//send the list and return
ViewData["selection"] = new SelectList(dropdownList.Select(i => i.project), blankLine);
return View();
View
//formats and inserts a blank line as the default in the list
@Html.DropDownList(
"selection", null, string.Empty, new { style = "font-size: .85em; font-weight: normal;" })
I had a couple of minor delays setting up Entity Framework in Visual Studio 2012 Update 1.
- Reverse engineering the database failed with the following error: “A processor named 'T4VSHost' could not be found for the directive named 'CleanupBehavior'. The transformation will not be run.”
The work around for C# projects is to:
Open the File
C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes\EF.Utility.CS.ttinclude (for C#)
And Remove the First Line:
<#@ CleanupBehavior Processor="T4VSHost" CleanupAfterProcessingTemplate="true" #>
See this bug in Connect for more details.
2. Finding the reference for “using System.Data.Entity.Infrastructure.” The procedure to add this reference is:
In Visual Studio 2012, select menu item "Tools"-> Library Package Manager --> Package Manger Console
and typing there:
PM> install-package EntityFramework
See this forum post for more details.