I am working on an event receiver inside my sharepoint server 2013. now inside the event receiver i use the following html code to build a link to the current item which cause the event receiver to fire, and send this link by email. now the current item for the event receiver can be a custom list item or a discussion board item:-

"<a href='" + properties.Web.Url + "/" + properties.ListItem.Url + "'>" + properties.ListItem["Title"] + "</a>"

now in-case of a Discussion board item the generated link will have the following href, which will reference the item correctly :-


but in-case of a custom list item the href will have the following url that end with _.000:-


so now to fix this i have manually build the href for the custom list item as follow (which will reference the DispForm.aspx):-

"<a href='" + properties.Web.Url  + "/Lists/Projects/DispForm.aspx?ID="+properties.ListItem.ID + "'>" + properties.ListItem["Title"] + "</a>

but my question is why properties.ListItem.Url inside my original code did not work for the custom list item (the generated url will end with _.000), while it worked well for discussion board item ? is it a problem inside my code or it is a problem/issue inside how sharepoint reference the custom list items?


I never use the SPListItem.Url property, as list items don't really have a user browsable URL. They only have an ID, and the list that contains them has a display form (list forms may also change over time).
The URL of an item is used internally by SharePoint but is never shown/used by the users.
So, I always use code such as:

Uri webUri = new Uri(web.Url);
SPUrlUtility.CombineUrl(webUri.Scheme + "://" + webUri.Authority, list.DefaultDisplayFormUrl + "?ID=" + item.ID.ToString());

Note: don't use Web.Url + "/Lists..." since Web.Url may be ending by \ (when it is the root site of the root site collection).

EDIT: discussion boards special case
For a discussion board, things are a little different. The first item you post (when creating a new discussion) is actually a folder. That's why it's SPListItem.Url property is "correct" and directs you to the view you're expecting. No _.000 here because it' a folder, not a real item.
If you reply to a discussion, a real item is created inside the folder representing the discussion, i.e. the initial post for the discussion.

I think the view you want to embed in your email is the "general view" of the discussion, i.e. the view of the folder containing it.
To achieve this, you have to:

  1. Determinate if the item that triggered the ER is a new discussion or a reply to an existing discussion. This can be made by checking the content type of the item:

    a. If the CT Id starts with 0x0120 (well-known ID for folders CT, check here), it's a folder, i.e. a new discussion. Meaning the SPListItem.Url is the one you want.

    b. If not (if it starts with 0x0107, i.e. is from the message CT), it means it's a reply. So, to get the URL you want, you need to get the URL of the parent folder, i.e. properties.ListItem.GetParentFolder().Url where GetParentFolder() is the extension method defined below.

public static SPFolder GetParentFolder(this SPListItem item)
   if (item == null)
      return null;
   SPFile file = item.Web.GetFile(item.Url);
   if (file == null)
      return null;
   return file.ParentFolder;
  • 1
    Updated my answer with specific info for discussion boards. – Evariste Jan 26 '17 at 14:58
  • 1
    first thanks a lot for your edit it is really helpful.. so you mean for discussion board item i can use SPListItem.Url to build the url for the discussion item.. but for the issue tracking i need to use the appraoch you mentioned to build th item url SPUrlUtility.CombineUrl(webUri.Scheme + "://" + webUri.Authority, list.DefaultDisplayFormUrl + "?ID=" + item.ID.ToString()); .. is this correct ? – john Gu Jan 26 '17 at 15:08
  • 1
    For a custom list, yup SPUrlUtility.... For a discussion it depends: is it the first post in the discussion (is the new discussion being created) or a reply in a an existing discussion. – Evariste Jan 26 '17 at 15:11
  • 1
    currently i am ONLY sending emails when a new discussion is created ,, and for this i am checking if the item's content type == "Discussion" inside my event receiver.. – john Gu Jan 26 '17 at 15:15
  • 1
    Yup, discussion CT inherits from folder (starts with 0x0120). So it is a folder, so you go with SPListItem.Url. – Evariste Jan 26 '17 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.