I need to add custom handling to a lists' adding event. However, the event does not appear to be firing. I would like my custom handler defined in EventReceivers to fire anytime a new item of the custom type is added to the list.
I would appreciate any suggestions.
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
namespace MyTestGroupListFeature
{
class MyTestGroupListFeature : SPFeatureReceiver
{
private const string LISTNAME = "Acquisition Groups";
private const string CONTENTTYPE_LISTNAME = "Contenttype List";
private const string FOO = "FOO";
private const string SITE_TEMPLATE_EXTENSION = ".stp";
public override void FeatureInstalled
(SPFeatureReceiverProperties properties)
{
}
public override void FeatureUninstalling
(SPFeatureReceiverProperties properties)
{
FeatureDeactivating(properties);
}
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
SPWeb web = properties.Feature.Parent as SPWeb;
SPList list = GetList(web, LISTNAME);
SPSite site = web.Site;
site.AllowUnsafeUpdates = true;
SPContentType newCType = CreateSourceSystemContentType(web);
SPList listct = web.Lists[CONTENTTYPE_LISTNAME];
AddEventReceiverToList(listct);
AddContentTypeToList(web, listct, newCType);
}
catch { }
}
/// <summary>
/// Creates a content type for Source System
/// </summary>
private SPContentType CreateSourceSystemContentType(SPWeb site)
{
//Create site columns
string acronymFieldName = site.Fields.Add("Acronym", SPFieldType.Text, true);
SPFieldText acronymField = (SPFieldText)site.Fields.GetFieldByInternalName(acronymFieldName);
acronymField.Group = "AQSIDM Columns";
acronymField.Update();
string nameFieldName = site.Fields.Add("Name", SPFieldType.Text, true);
SPFieldText nameField = (SPFieldText)site.Fields.GetFieldByInternalName(nameFieldName);
acronymField.Group = "AQSIDM Columns";
acronymField.Update();
string descriptionFieldName = site.Fields.Add("Description", SPFieldType.Text, true);
SPFieldText descriptionField = (SPFieldText)site.Fields.GetFieldByInternalName(descriptionFieldName);
descriptionField.Group = "AQSIDM Columns";
descriptionField.Update();
// Get the parent content type.
SPContentTypeId itemCTID = new SPContentTypeId("0x01");
SPContentType itemCT = site.AvailableContentTypes[itemCTID];
//Create SourceSystem content type:
SPContentType sourceSystemCT = new SPContentType(itemCT, site.ContentTypes, "Source System");
sourceSystemCT.Group = "Source System Content Types";
//Add columns to content type
sourceSystemCT = site.ContentTypes[sourceSystemCT.Id];
SPFieldLink acronymLink = new SPFieldLink(acronymField);
sourceSystemCT.FieldLinks.Add(acronymLink);
//
SPFieldLink nameLink = new SPFieldLink(nameField);
sourceSystemCT.FieldLinks.Add(nameLink);
//
SPFieldLink descriptionLink = new SPFieldLink(descriptionField);
sourceSystemCT.FieldLinks.Add(descriptionLink);
//
//sourceSystemCT.Update();
string assemblyName = System.Reflection.Assembly.GetEntryAssembly().FullName;
string ctReceiverName = "MyTestGroupListFeature.EventReceivers";
sourceSystemCT.EventReceivers.Add(SPEventReceiverType.ItemAdding, assemblyName, ctReceiverName);
sourceSystemCT.Update(true);
site.ContentTypes.Add(sourceSystemCT);
return sourceSystemCT;
}
/// <summary>
/// Adds a custom content type to site's list
/// </summary>
private void AddContentTypeToList(SPWeb web, SPList list, SPContentType ct)
{
list.ContentTypesEnabled = true;
list.ContentTypes.Add(ct);
list.Update();
// Add the item:
SPListItem newItem = list.Items.Add();
newItem["Acronym"] = "Acronym Field Added";
newItem.Update();
}
/// <summary>
/// Programmatically add new event receivers
/// </summary>
private void AddEventReceiverToList(SPList list)
{
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
SPEventReceiverDefinition eventReceiver = list.EventReceivers.Add();
eventReceiver.Name = "On Updating";
eventReceiver.Type = SPEventReceiverType.ItemAdding;
eventReceiver.SequenceNumber = 200;
eventReceiver.Assembly = assembly.FullName;
eventReceiver.Class = "MyTestGroupListFeature.EventReceivers";
eventReceiver.Update();
}
}
class EventReceivers : SPItemEventReceiver
{
/// <summary>
/// Test behavior when adding an item
/// </summary>
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
SourceSystem ss = new SourceSystem();
ss.Name = "sharepointss";
ss.Acronym = "sharepoint acronym";
ss.Description = "desc";
ss.EndPoint = new Uri(#"\testURI");
ss.Update("foo");
ss.Create(String.Format("SourceSystem_Create_SP_{0:o}", DateTime.Now));
}
}
}
After you activated the feature, did you verify whether or not the event receiver was attached to the list? This can be done programatically or using tools such as SharePoint Manager.
Related
I need to create a tree view in asp.net mvc5 framework for the recursive outputs.
This is my model class
public class ProcSearchModel
{
/// <summary>
///
/// </summary>
public string TableName { get; set; }
/// <summary>
///
/// </summary>
public string DirectoryPath { get; set; }
/// <summary>
///
/// </summary>
public List<string> ProceduresName { get; set; }
// public List<ProcSearchModel> =
}
That stores the list of result in ProceduresName list.
Now for each Procedure name in the list there is another list of names in it. Which I need to populate as tree view..
Presently this is my controller function:
public ActionResult SearchProcedure(ProcSearchModel procSearchModel)
{
List<string> lstString = new List<string>();
//if (procSearchModel != null)
//{
try
{
var txtFiles = Directory.EnumerateFiles(procSearchModel.DirectoryPath, "*.sql", SearchOption.AllDirectories);
// pattern to capture the Stored procedue name
// string cpattern = #"(CREATE PROCEDURE|ALTER PROCEDURE)\s*(?<proc_name>(\w|_|\[|\]|\.)*)(.|\n)*" + procSearchModel.TableName;
string cPattern = #"(CREATE PROCEDURE|ALTER PROCEDURE)\s*(?<proc_name>(\w|_|\[|\]|\.)*)";
string tPattern = procSearchModel.TableName;
foreach (string currentFile in txtFiles)
{
string content = System.IO.File.ReadAllText(currentFile);
if(Regex.IsMatch(content,tPattern,RegexOptions.IgnoreCase) && Regex.IsMatch(content,cPattern,RegexOptions.IgnoreCase))
{
Match match = Regex.Match(content, cPattern, RegexOptions.IgnoreCase);
lstString.Add(match.Groups["proc_name"].Value);
}
}
procSearchModel.ProceduresName = lstString;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
//}
return View(procSearchModel);
}
Now plz help me how to populate the tree view by usnig nested list with jstree plugin
Create a recursive node structure of the nodes (or objects) as you need in the hierarchy and link them as in a tree. Then pass that object in a tree
class dummyObject{
int num;
String data;
List<dummyObject> d = new List<dummyObject>();
}
Use this type of class object to create hierarchy structure and then pass them into jstree (http://www.jstree.com/) plugin call..... Rest will be done the plugin.
I have a class like this,
public class Item
{
private string _itemCode=string.empty;
private string _itemName = string.empty;
//Dynamic variable to keep custom properties
private dynamic _customProperties = new ExpandoObject();
public string ItemCode
{
get{return _itemCode;}
set{_itemCode=value;}
}
public string ItemName
{
get{return _itemName;}
set{_itemName=value;}
}
private ExpandoObject CustomProperties
{ get { return _customProperties; } }
//Method to load objects
publc static List<Item> Load()
{
List<Item> itemList = new List<Item>();
//Create Item objects
Item itm1 = new Item();
{
_itemCode="Code1";
_itemName="Name1";
}
//Create custom properties
itm1._customProperties.Test1 = "t1";
itemList.Add(itm1);
//Add more items as above with the several custom properties
return itemList;
}
}
In my windows form I'm getting a Item list and assigning it to the datasource of the datagridview.
List<Item> lstItems= Item.Load();
//Add item list to the data grid view
BindingSource bindingSource = new BindingSource();
bindingSource.DataSource = lstItems;
this.dataGridView1.DataSource = bindingSource;
this.dataGridView1.Refresh();
When form runs, grid doesn't show the custom properties I have added to the Item.CustomProperties. How can I change my code to overcome this.
Try this
Set
bindingSource.DataMember = "Your value"; //
http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.aspx
this is like an interview question given to me by someone, can you tell me whats wrong with it or if there is a better way of doing this. this will be run in a large enterprise. NOTE : Demo.Tasks.Task is a custom object whose deninition is not shown in this code.
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.WebControls;
using System.Collections;
namespace Demo.WebParts
{
/// <summary>
/// Description for MyTasks.
/// </summary>
[DefaultProperty("Text"),
ToolboxData("<{0}:WebPart1 runat=server></{0}:WebPart1>"),
XmlRoot(Namespace="Demo.Tasks")]
public class MyTasks : Microsoft.SharePoint.WebPartPages.WebPart
{
private const string defaultListName = "";
private string listName = defaultListName;
private ArrayList alTasks;
[Browsable(true),
Category("Miscellaneous"),
DefaultValue(defaultListName),
WebPartStorage(Storage.None),
FriendlyName("List Name Filter"),
Description("The name of sps lists to gather tasks from")]
public string ListName
{
get
{
return listName;
}
set
{
listName = value;
}
}
protected override void CreateChildControls()
{
alTasks = new ArrayList();
try
{
SPWeb myWeb = SPControl.GetContextWeb(this.Context);
foreach(SPList list in myWeb.Lists)
{
if(list.BaseTemplate == SPListTemplateType.Tasks)
{
if(list.Title == listName)
{
getTasksFromList(list);
}
}
}
foreach(SPWeb subWeb in myWeb.Webs)
foreach(SPList list in subWeb.Lists)
if(list.BaseTemplate == SPListTemplateType.Tasks)
getTasksFromList(list);
}
catch
{}
}
private void getTasksFromList(SPList list)
{
for(int i=0;i<list.ItemCount;i++)
{
if(list.Items[i]["AssignedTo"].ToString() == this.Context.User.Identity.Name)
{
Demo.Tasks.Task tsk = Tasks.Task.CreateTask();
tsk.Title = list.Items[i]["Title"].ToString();
tsk.DueDate = (DateTime)list.Items[i]["DueDate"];
tsk.Description = list.Items[i]["Description"].ToString();
tsk.Priority = (int)list.Items[i]["Priority"];
alTasks.Add(tsk);
//now update the item
list.Items[i]["LastViewed"] = DateTime.Now;
}
}
}
/// <summary>
/// Render this Web Part to the output parameter specified.
/// </summary>
/// <param name="output"> The HTML writer to write out to </param>
protected override void RenderWebPart(HtmlTextWriter output)
{
try
{
string strHTML = "";
for(int i=0;i<alTasks.Count;i++)
{
Demo.Tasks.Task tsk = (Demo.Tasks.Task)alTasks[i];
strHTML = strHTML + "The task " + tsk.Title + " is due on " + tsk.DueDate + "<BR>" + tsk.Description + "<BR><BR>";
}
output.Write(strHTML);
}
catch
{}
}
}
}
It would be better if you'll give us more info (what doesn't work, etc.).
But in my opinion you should use 'using' when you're working with SPWeb or SPSite. Not doing this sometimes causes strange errors:
using (SPWeb myWeb = SPControl.GetContextWeb(this.Context))
{
foreach (SPList list in myWeb.Lists)
{
if (list.BaseTemplate == SPListTemplateType.Tasks)
{
if (list.Title == listName)
getTasksFromList(list);
}
}
}
using (SPSite site = new SPSite(SiteUrl))
{
foreach (SPWeb subWeb in site.AllWebs)
{
try //should be 1st statement after foreach
{
foreach (SPList list in subWeb.Lists)
{
if (list.BaseTemplate == SPListTemplateType.Tasks)
getTasksFromList(list);
}
}
finally
{
if (subWeb != null)
subWeb.Dispose();
}
}
}
Here you can read about this:
http://blogs.msdn.com/b/rogerla/archive/2009/01/14/try-finally-using-sharepoint-dispose.aspx
I am trying to enable View toolbar on my list views. But it seems not to be working. How can I get the code right?
/// <summary>
/// Handles the Click event of the btnEnable control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void btnEnable_Click(object sender, EventArgs e)
{
using (SPWeb spWeb = new SPSite(tbSiteUrl.Text).OpenWeb())
{
SPList spList = spWeb.Lists[lbLists.SelectedItem.ToString()];
foreach (SPView spView in spList.Views)
{
EnableToolbar(spView.Title, spList.Title, spWeb.Url);
}
}
}
/// <summary>
/// Enables the toolbar.
/// </summary>
/// <param name="viewName">Name of the view.</param>
/// <param name="listName">Name of the list.</param>
/// <param name="webUrl">The web URL.</param>
private void EnableToolbar(string viewName, string listName, string webUrl)
{
SPSecurity.RunWithElevatedPrivileges(() =>
{
using (var spSite = new SPSite(webUrl))
{
using (SPWeb web = spSite.OpenWeb())
{
spSite.AllowUnsafeUpdates = true;
SPList spList = web.Lists[listName];
SPView spView = spList.Views[viewName];
XDocument xDocument =
XDocument.Parse(spView.GetViewXml());
XElement xElement =
xDocument.Element("View").Element("Toolbar");
xElement.RemoveAttributes();
xElement.SetAttributeValue("Type", "Standard");
xElement.SetAttributeValue("ShowAlways", "TRUE");
spView.SetViewXml(xDocument.ToString());
spView.Update();
spSite.AllowUnsafeUpdates = false;
}
}
});
}
UPDATE:
using (var spSite = new SPSite(webUrl))
{
using (SPWeb web = spSite.OpenWeb())
{
spSite.AllowUnsafeUpdates = true;
SPList spList = web.Lists[listName];
SPView spView = spList.Views[viewName];
spView.Toolbar =
#"<Toolbar Type=""Standard"" ShowAlways=""TRUE""/>";
spView.Update();
spSite.AllowUnsafeUpdates = false;
}
}
Closer, but still not good.
This time, it did modified the view. I know it because, the second time I run the debugger, I did noticed the value of the SPView.Toolbar property changed.
But when I open the same page in the SharePoint designer, I do not see <Toolbar Type="Standard" ShowAlways="TRUE"/> but I see the default value as: <Toolbar Type="Standard"/>.
In addition to that, I do not see the toolbar on the list view page when I open the list view in the browser.
This is what I had to do to make it work.
/// <summary>
/// Enables the toolbar.
/// </summary>
/// <param name="viewName">Name of the view.</param>
/// <param name="listName">Name of the list.</param>
/// <param name="webUrl">The web URL.</param>
private void EnableToolbar(string viewName, string listName, string webUrl)
{
using (var spSite = new SPSite(webUrl))
{
using (SPWeb web = spSite.OpenWeb())
{
spSite.AllowUnsafeUpdates = true;
SPList spList = web.Lists[listName];
SPView spView = spList.Views[viewName];
SPLimitedWebPartManager spLimitedWebPartManager =
web.GetLimitedWebPartManager(spView.Url, PersonalizationScope.Shared);
foreach (WebPart webPart in spLimitedWebPartManager.WebParts)
{
if (webPart.GetType().Name.Equals("XsltListViewWebPart"))
{
try
{
MethodInfo ensureViewMethod = webPart.GetType().GetMethod("EnsureView",
BindingFlags.Instance |
BindingFlags.NonPublic);
object[] ensureViewParams = {};
ensureViewMethod.Invoke(webPart, ensureViewParams);
FieldInfo viewFieldInfo = webPart.GetType().GetField("view",
BindingFlags.NonPublic |
BindingFlags.Instance);
var view = viewFieldInfo.GetValue(webPart) as SPView;
Type[] toolbarMethodParamTypes = {Type.GetType("System.String")};
MethodInfo setToolbarTypeMethod = view.GetType().GetMethod("SetToolbarType",
BindingFlags.Instance |
BindingFlags.NonPublic, null,
toolbarMethodParamTypes, null);
object[] setToolbarParam = {"ShowToolbar"};
setToolbarTypeMethod.Invoke(view, setToolbarParam);
view.Update();
}
catch { }
}
}
spSite.AllowUnsafeUpdates = false;
}
}
}
Use the SPView.Toolbar property instead. The property expects the <Toolbar/> CAML element and replaces the particular XML node in the underlying CAML fragment.
I am having trouble implementing ASPNetIdentity on my MVC project
I am getting this error in the var line (The entity type IdentityRole is not part of the model for the current context.):
using System;
using System.Linq;
using System.Web.Mvc;
using EZ.Models;
using Microsoft.AspNet.Identity.EntityFramework;
namespace EZ.Controllers
{
public class RoleController : Controller
{
ApplicationDbContext context;
public RoleController()
{
context = new ApplicationDbContext();
}
/// <summary>
/// Get All Roles
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
var roles = context.Roles.ToList();
return View(roles);
}
/// <summary>
/// Create a New role
/// </summary>
/// <returns></returns>
// GET: /Roles/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Roles/Create
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole()
{
Name = collection["RoleName"]
});
context.SaveChanges();
ViewBag.ResultMessage = "Role created successfully !";
return RedirectToAction("Index");
}
catch
{
return View();
}
}
/// <summary>
/// Set Role for Users
/// </summary>
/// <returns></returns>
public ActionResult SetRoleToUser()
{
var list = context.Roles.OrderBy(role => role.Name).ToList().Select(role => new SelectListItem { Value = role.Name.ToString(), Text = role.Name }).ToList();
ViewBag.Roles = list;
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UserAddToRole(string uname, string rolename)
{
ApplicationUser user = context.Users.Where(usr => usr.UserName.Equals(uname, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
// Display All Roles in DropDown
var list = context.Roles.OrderBy(role => role.Name).ToList().Select(role => new SelectListItem { Value = role.Name.ToString(), Text = role.Name }).ToList();
ViewBag.Roles = list;
if (user != null)
{
var account = new AccountController();
account.UserManager.AddToRoleAsync(user.Id, rolename);
ViewBag.ResultMessage = "Role created successfully !";
return View("SetRoleToUser");
}
else
{
ViewBag.ErrorMessage = "Sorry user is not available";
return View("SetRoleToUser");
}
}
}
}
I have scripted the tables in my DB.
This is the exact same code as in the role-security-mvc5-master project from CodeProject.com. The only difference is that I moved the tables in my DB ana dI changed the connection string. What is the piece I am missing?
in my IdentityModel.cs I have:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
If you need more code, please let me know and I will post.
When the project was created, identity, a database at locadb. when I moved the tables in my DB I overwrote the entire Default connection string with the one I created for E. The big probelm here was that the default connection needs providerName="System.Data.SqlClient" /> and NOT providerName="System.Data.EntityClient". Be careful there. Credit needs to go to this excellent article from Daniel Eagle: http://danieleagle.com/blog/2014/05/setting-up-asp-net-identity-framework-2-0-with-database-first-vs2013-update-2-spa-template/. Tons of detail on how to use Identity with DB first.