System.Description not present in the dictionary - c#

I'm writing a C# program that can get the fields of all the work items in an Azure DevOps organization. However, I'm having some problems with the Description field:
IList<WorkItem> workItems = new List<WorkItem>();
string uri = "https://dev.azure.com/(organization)";
var creds = new VssBasicCredential(string.Empty, "pat");
var wiql = new Wiql()
{
Query = "SELECT [Id] FROM WorkItems"
};
using (var httpClient = new WorkItemTrackingHttpClient(new Uri(uri), creds))
{
var result = httpClient.QueryByWiqlAsync(wiql).Result;
var ids = result.WorkItems.Select(item => item.Id).ToArray();
if (ids.Length == 0)
{
workItems = Array.Empty<WorkItem>();
return;
}
var fields = new[]
{
"System.Title",
"System.WorkItemType",
"System.State",
"System.TeamProject",
"System.Description"
};
workItems = httpClient.GetWorkItemsAsync(ids, fields, result.AsOf).Result;
}
Console.WriteLine("{0} Items Found: ", workItems.Count);
Console.WriteLine();
Console.WriteLine("ID\tTitle\tType\tState\tProject\tDescription");
foreach (WorkItem item in workItems)
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
item.Id,
item.Fields["System.Title"],
item.Fields["System.WorkItemType"],
item.Fields["System.State"],
item.Fields["System.TeamProject"],
item.Fields["System.Description"]);
}
Here is also the project references:
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.Client;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
This code is supposed to return all the parameters, but it gives the following exception:
"The given key 'System.Description' was not present in the dictionary."
Is there any way to solve this?

I think I found a solution: you basically have to make sure that the WI description is not null and, if it is, you want to show a custom message saying that there is no description to the WI:
foreach (WorkItem item in workItems)
{
string desc = item.Fields["System.Description"].ToString();
if (desc == string.Empty) desc = "(missing description)";
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
item.Id,
item.Fields["System.Title"],
item.Fields["System.WorkItemType"],
item.Fields["System.State"],
item.Fields["System.TeamProject"],
desc);
}
This way it will show you the description.

Related

How to know if a ID has a parent ID or not in WIQL TFS?

I have an id and I want to know if has a parentid or not by C# coding for TFS. In my TFS board there are many user stories that do not include a Feature ?
My hierarchical structure in TFS is as follows:
Feature
--->User Stories(u1,u2,u3)
--->Tasks (t1,t2,t3)
Sometimes a user story does not contain a Feature
You can get this with direct workitem query. You may create it in VS and save to local drive:
Then you may find query text in saved query:
<?xml version="1.0" encoding="utf-8"?><WorkItemQuery Version="1"><TeamFoundationServer>http://myserverandcollection</TeamFoundationServer><TeamProject>MyProject</TeamProject><Wiql>
SELECT [System.Id], [System.Links.LinkType], [System.WorkItemType], [System.Title], [System.AssignedTo], [System.State], [System.Tags] FROM WorkItemLinks WHERE ([Source].[System.Id] = 174) And ([System.Links.LinkType] = 'System.LinkTypes.Hierarchy-Reverse') And ([Target].[System.WorkItemType] = 'Feature') ORDER BY [System.Id] mode(MustContain)
</Wiql></WorkItemQuery>
Then you may create application with Microsoft.TeamFoundationServer.ExtendedClient nugate package
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QueryLinkedWIQL
{
class Program
{
static void Main(string[] args)
{
WorkItemStore _wistore = new WorkItemStore("http://myserver/myCollection");
int _id = 175;
string _wiql = String.Format("SELECT [System.Id] FROM WorkItemLinks WHERE ([Source].[System.Id] = {0}) And ([System.Links.LinkType] = 'System.LinkTypes.Hierarchy-Reverse') And ([Target].[System.WorkItemType] = 'Feature') ORDER BY [System.Id] mode(MustContain)", _id);
Query _query = new Query(_wistore, _wiql);
WorkItemLinkInfo[] _links = _query.RunLinkQuery();
if (_links.Count() == 2) //only 1 child and its parent
Console.WriteLine("Parent ID: " + _links[1].TargetId);
else
Console.WriteLine("There is no parent for ID: " + _id);
}
}
}
===========================for Relation Task->Something->Feature============
You may use tree query:
and this code:
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QueryLinkedWIQL
{
class Program
{
static void Main(string[] args)
{
WorkItemStore _wistore = new WorkItemStore("http://myserver/myCollection");
int _id = 210;
string _wiql = String.Format("SELECT [System.Id] FROM WorkItemLinks WHERE ([Source].[System.WorkItemType] = 'Feature') And ([System.Links.LinkType] = 'System.LinkTypes.Hierarchy-Forward') And ([Target].[System.Id] = {0} AND [Target].[System.WorkItemType] = 'Task') ORDER BY [System.Id] mode(Recursive,ReturnMatchingChildren)", _id);
Query _query = new Query(_wistore, _wiql);
WorkItemLinkInfo[] _links = _query.RunLinkQuery();
if (_links.Count() > 1) //first item contains feature
Console.WriteLine("Parent ID: " + _links[0].TargetId);
else
Console.WriteLine("There is no parent for ID: " + _id);
}
}
}
---------Screens
Query:
Debug:

How to set value in nested LINQ select to parent select result?

This is my LINQ:
var sdEnumTypes = from et in sdXmlEnums.Elements("Enum")
select new SdEnum
{
Name = et.Attribute("name").Value,
EnumGuid = et.Attribute("guid").Value,
Enumerators = (from en in et.Elements("Enumerator")
select new SdEnumerator
{
DisplayName = en.Attribute("displayName").Value,
Name = en.Attribute("name").Value
//Enum = I want this to point to parent SdEnum
}).ToList()
};
I want to set (commented part) Enum value to SdEnum that is being selected on level up. How to do it?
This is corresponding XML that is being parsed for you to visualize what I want to do:
<Enums>
<Enum name="Color" guid="{2C68F947-3103-4F3C-9855-60F289B3A039}">
<Enumerator name="Red" displayName="Red Color"/>
<Enumerator name="Green" displayName="Green Color" />
<Enumerator name="Blue" displayName="BlueColor"/>
</Enum>
</Enums>
P.S.
Is there any way to simplify this this query?
Here is a method using XML Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input =
"<Enums>" +
"<Enum name=\"Color\" guid=\"{2C68F947-3103-4F3C-9855-60F289B3A039}\">" +
"<Enumerator name=\"Red\" displayName=\"Red Color\"/>" +
"<Enumerator name=\"Green\" displayName=\"Green Color\" />" +
"<Enumerator name=\"Blue\" displayName=\"BlueColor\"/>" +
"</Enum>" +
"</Enums>";
XDocument doc = XDocument.Parse(input);
var results = doc.Descendants("Enum").Select(x => new {
name = x.Attribute("name").Value,
guid = x.Attribute("guid").Value,
enumerator = x.Elements("Enumerator").Select(y => new {
name = y.Attribute("name").Value,
displayName = y.Attribute("displayName").Value,
parent = x
}).ToList()
}).ToList();
}
}
}
​
The simplest way to do this is to use another projection:
var result = sdEnumTypes.Select(e =>
{
e.Enumerators.ForEach(enumerator => enumerator.Enum = e);
return e;
});

How to Merge a column from 2 sharepoint lists and display it in a ASP.NET GridView?

I have got 2 Sharepoint lists. I need to pick some random columns from both the lists and display it in an ASP.NET GRIDVIEW. I've done this code using Linq. but i'm getting an error stating that argument null exception. may i know the reason for such error .
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Linq;
using System.Linq;
using System.Text.RegularExpressions;
using System.Text;
using System.IO;
using System.Diagnostics;
namespace SharePointProject3.VisualWebPart1
{
public partial class VisualWebPart1UserControl : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
string sQuery = string.Empty;
string sWebUrl;
SPListItemCollection objProductListItems = null;
SPListItemCollection objOrderListItems = null;
string sViewFields = string.Empty;
sWebUrl = SPContext.Current.Site.Url;
sQuery = "<OrderBy><FieldRef Name='Modified' Ascending='FALSE' /></OrderBy>";
sViewFields = string.Concat("<FieldRef Name='ProductId'/>",
"<FieldRef name= 'ProductName' />",
"<FieldRef name= 'ProductDescription' />");
objProductListItems = GetListItems(sWebUrl, "Products", sQuery, sViewFields);
sViewFields = string.Concat("<FieldRef Name='OrderId'/>",
"<FieldRef name= 'Quantity' />",
"<FieldRef name= 'ProductName' />");
objOrderListItems = GetListItems(sWebUrl, "Orders", sQuery, sViewFields);
var Orders = (from itemProduct in objOrderListItems.Cast<SPListItem>()
join itemOrder in objOrderListItems.Cast<SPListItem>()
on Convert.ToString(itemProduct["ProductName"]) equals Convert.ToString(itemOrder["ProductName"])
select new
{
ProductName = Convert.ToString(itemProduct["ProductName"]),
ProductDescription = Convert.ToString(itemProduct["ProductDescription"]),
OrderQuantity = Convert.ToString(itemOrder["Quantity"]),
}).ToList();
if(Orders != null)
{
GridView1.DataSource = Orders;
GridView1.DataBind();
}
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
public static SPListItemCollection GetListItems(string sWebUrl, string sListName, string sQuery, string sviewFields)
{
SPListItemCollection objListItemCollection = null;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite objSite = new SPSite(sWebUrl))
{
using (SPWeb objWeb = objSite.OpenWeb())
{
SPList objList = objWeb.Lists.TryGetList(sListName);
if (objList != null)
{
SPQuery objSPQuery = new SPQuery();
objSPQuery.Query = sQuery;
objSPQuery.ViewFields = sviewFields;
objListItemCollection = objList.GetItems(objSPQuery);
}
}
}
});
return objListItemCollection;
}
}
}
Using Linq2SharePoint is not good idea. There are many issues with that. Including performance issues. Sometimes it generates strange errors and it's very hard to debug it. You use CAML in your code. CAML can do join as well. See here how to do it. It's handled by SharePoint itself and you will get single resultset.

Using Ebay SDK API: ExcludeShipToLocation.Add("CN") causes:“Object reference not set to an instance of an object”

I've been trying to figure out how to exclude some locations using Ebay API Csharp but so far I haven't solved this after so many code variations and deep-googling.
I need help in excluding "China".
item.ShippingDetails.ExcludeShipToLocation = new StringCollection();
But when the program hits this line of code, this error shows up:
"Object reference not set to an instance of an object"
If you would like to see the full code here it is:
using eBay.Service.Call;
using eBay.Service.Core.Sdk;
using eBay.Service.Core.Soap;
using eBay.Service.Util;
using Samples.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ebayapiex3
{
class Program
{
static void Main(string[] args)
{
ApiContext context = AppSettingHelper.GetApiContext();
context.ApiLogManager = new ApiLogManager();
context.ApiLogManager.ApiLoggerList.Add(new FileLogger("log.txt", true, true, true));
context.ApiLogManager.EnableLogging = true;
context.Site = SiteCodeType.US;
ReviseFixedPriceItemCall reviseFP = new ReviseFixedPriceItemCall(context);
ItemType item = new ItemType();
item.ItemID = "************";
item.Title = "TITLE HAS BEEN CHANGED";
item.Quantity = 99;
item.StartPrice = new AmountType();
item.StartPrice.Value = 795.76;
item.ShipToLocations = new StringCollection();
item.ShipToLocations.Add("US");
item.ShipToLocations.Add("AU");
item.ShippingDetails.ExcludeShipToLocation = new StringCollection();
item.ShippingDetails.ExcludeShipToLocation.Add("CN");
reviseFP.Item = item;
reviseFP.Execute();
Console.WriteLine(reviseFP.ApiResponse.Ack + " SKU " + reviseFP.SKU);
}
}
}
You need to create item.ShippingDetails before assiging to its members.
item.ShippingDetails = new ShippingDetailsType();
item.ShippingDetails.ExcludeShipToLocation = new StringCollection();
item.ShippingDetails.ExcludeShipToLocation.Add("CN");

how to use or format keyword in ebay FindingAPI search

I am using the following code to search items based on keywords:
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using ConsoleApplication1.EbayServiceReference;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TextWriter tw = new StreamWriter("1001.txt");
using (FindingServicePortTypeClient client = new FindingServicePortTypeClient())
{
MessageHeader header = MessageHeader.CreateHeader("My-CustomHeader", "http://www.mycustomheader.com", "Custom Header");
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageHeaders.Add(header);
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers.Add("X-EBAY-SOA-SECURITY-APPNAME", "myappid");
httpRequestProperty.Headers.Add("X-EBAY-SOA-OPERATION-NAME", "findItemsByKeywords");
httpRequestProperty.Headers.Add("X-EBAY-SOA-GLOBAL-ID", "EBAY-US");
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
FindItemsByKeywordsRequest request = new FindItemsByKeywordsRequest();
request.keywords = "gruen wristwatch parts -(sara,quartz,embassy,bob,robert,elephants,adidas)";
FindItemsByKeywordsResponse check = client.findItemsByKeywords(request);
int totalEntries = check.paginationOutput.totalEntries;
Console.WriteLine(totalEntries);
int totalPages = (int)Math.Ceiling((double)totalEntries / 100.00);
for (int curPage = 1; curPage <= totalPages; curPage++)
{
PaginationInput pagination = new PaginationInput();
pagination.entriesPerPageSpecified = true;
pagination.entriesPerPage = 100;
pagination.pageNumberSpecified = true;
pagination.pageNumber = curPage;
request.paginationInput = pagination;
FindItemsByKeywordsResponse response = client.findItemsByKeywords(request);
foreach (var item in response.searchResult.item)
{
Console.WriteLine(item.viewItemURL.ToString());
tw.WriteLine(item.viewItemURL.ToString());
}
}
}
}
tw.Close();
Console.WriteLine("end");
Console.ReadKey();
}
}
}
Here is the original keyword set:
gruen wristwatch parts -sara -quartz -embassy -bob -robert -elephants -adidas
If i use this keyword set it returns 3 items: The result is here
I have formatted it like this to use in FindingAPI according to this reference
gruen wristwatch parts -(sara,quartz,embassy,bob,robert,elephants,adidas)
and it returns 13 items. I think it should return 3 items too.
What is responsible for the discrepancy, and can I get the expected results using the alternate syntax?

Categories