Set the value of custom webpart property in c# - sharepoint-2010

How to set the value of custom webpart property Programatically in C#.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite SiteCollection = new SPSite(mySiteGuid))
{
SPWeb myWeb = SiteCollection.OpenWeb(myWebGuid);
myWeb .AllowUnsafeUpdates = true;
Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager mgr = null;
mgr = myWeb.GetLimitedWebPartManager ("default.aspx",System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
foreach (System.Web.UI.WebControls.WebParts.WebPart myWebPart in mgr.WebParts)
{
if (myWebPart.Title == "Other Webpart Name")
{
myWebPart.Visible = ! myWebPart.Visible;
myWeb.Update();
break;
}
}
}
});
I have a custom property in the webpart of type string to get the input from the user.
I wanted to updated the value of the property from c#.
Is there any way to set the value?
TIA

Try myWebPart.Update() instead of myWeb.Update().

Maybe it's a bit late for the answer, but here i let a piece of code i used for this.
var webCollection = new SPSite("http://mySharePointSite").AllWebs;
foreach (SPWeb web in webCollection)
{
var landingPageReference = #"/Pages/default.aspx";
var page = web.GetFile(landingPageReference);
if (!page.Exists)
continue;
page.CheckOut();
var spLimitedWebPartManager = web.GetLimitedWebPartManager(page.ServerRelativeUrl, PersonalizationScope.Shared);
foreach (WebPart webPartItem in spLimitedWebPartManager.WebParts)
{
if (webPartItem.Title.Equals("myWebPartTitle"))
{
// Specify Properties to change here
webPartItem.ChromeType = PartChromeType.Default;
webPartItem.Description = "AGAIN CHANGED";
// Save made changes
spLimitedWebPartManager.SaveChanges(webPartItem);
break;
}
}
page.CheckIn("Add Comment if desired");
page.Publish("Add Comment if desired");
web.Update();
web.Dispose();
}

Related

DataAnnotations attributes on custom control

I've used a custom control (HTML Helper) to build an Autocomplete controller.
it works great, the only thing is the validation problem.
on the client side, the validation works fine when jquery.validation.js is out of the picture, (for empty text box it gives an error message).
if the user selects something from the autocomplete, so im fine.
but when the user input is just junk, then the HttpPost needs to handle the junk & return an error message to the user.
HOW??
also, i've seen a DataAnnotation called Remote, which can manage the validation on the client side, is it better ? if so, how can i add DataAnnotaion on a custom control ??
Thank's :)
here is my code:
Index.cshtml
#using (Html.BeginForm("Index", "Create"))
{
#Html.AutocompleteFor(Url.Action("AutoCompleteServiceProviders", "Create"), true, "ex. Shower", c => c.service_id, a => a.name)
<input type="submit" id="search" value="" />
}
AutoComplete.cs
private static MvcHtmlString CreateAutocomplete<TModel>(this HtmlHelper<TModel> helper, string actionUrl, bool? isRequired, string placeholder, params Expression<Func<TModel, object>>[] expression)
{
var builder = new StringBuilder();
foreach (var item in expression)
{
var attributes = new Dictionary<string, object>
{
{ "data-autocomplete", true },
{ "data-action", actionUrl }
};
if (!string.IsNullOrWhiteSpace(placeholder))
{
attributes.Add("placeholder", placeholder);
}
if (isRequired.HasValue && isRequired.Value)
{
attributes.Add("required", "required");
}
Func<TModel, object> method = item.Compile();
var value = (Object)null;
if ((TModel)helper.ViewData.Model != null)
{
value = method((TModel)helper.ViewData.Model);
}
var baseProperty = (string)null;
var hidden = (MvcHtmlString)null;
if (item.Body is MemberExpression)
{
baseProperty = ((MemberExpression)item.Body).Member.Name;
hidden = helper.Hidden(baseProperty, value);
attributes.Add("data-value-name", baseProperty);
}
else
{
var op = ((UnaryExpression)item.Body).Operand;
baseProperty = ((MemberExpression)op).Member.Name;
hidden = helper.Hidden(baseProperty, value);
}
attributes.Add("data-value-id", "service_id");
var automcompleteName = baseProperty + "_autocomplete";
var textBox = (MvcHtmlString)null;
if (value != null)
{
textBox = helper.TextBox(automcompleteName, value, string.Empty, attributes);
}
else
{
textBox = helper.TextBox(automcompleteName, null, string.Empty, attributes);
}
builder.AppendLine(hidden.ToHtmlString());
if (baseProperty == "name")
{
builder.AppendLine(textBox.ToHtmlString());
}
}
return new MvcHtmlString(builder.ToString());
}
You can get your validation from here:
var validation = htmlHelper.ValidationMessageFor(expression, null, new Dictionary<string, object>());
UPDATE:
I use TagBuilder to create tags. What I do with tagbuilder is add that validation to a span or div tag and let the unobtrusive javascript hide/show it when needed. It returns an MVCHtmlString you can just append it to the element you want to display it in

The security validation for this page is invalid error trying to add sharepoint approval workflow to List in ListAdded eventreceiver

What I am trying to do is to attach the OOTB sharepoint workflow [Approval Sharepoint - 2010] to each and every document library that ever gets created. To accomplish this I created a List Added event reciever and put this code in it -
public override void ListAdded(SPListEventProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPUtility.ValidateFormDigest();
using (SPSite site = new SPSite(properties.SiteId))
{
using (SPWeb web = site.OpenWeb())
{
try
{
base.ListAdded(properties);
if (currentList is SPDocumentLibrary)
{
SPDocumentLibrary docLib = (SPDocumentLibrary)properties.List;
//workflows need a tasks and history list. Here we assume they exist
SPList taskList = web.Lists["Tasks"];
SPList historyList = web.Lists["Workflow History"];
//loop through the workfows in the web and grab the one we want by name
SPWorkflowTemplate wfTemp = null;
foreach (SPWorkflowTemplate wt in web.WorkflowTemplates)
{
if (wt.Name == "Approval - SharePoint 2010")
{
wfTemp = wt;
Common.AddToLog(web, "Found " + wt.Name + " in current web " +
web.Url, false);
break;
}
}
//Now add the workflow to the doc library
SPWorkflowAssociation workFlow = SPWorkflowAssociation.CreateListAssociation(wfTemp, wfTemp.Name, taskList, historyList);
workFlow.AllowManual = true;
workFlow.AutoStartChange = false;
workFlow.AutoStartCreate = true;
workFlow.AssociationData = null;
web.AllowUnsafeUpdates = true;
web.ValidateFormDigest();
docLib.WorkflowAssociations.Add(workFlow);
docLib.EnableModeration = true;
docLib.Update();
web.Update();
web.AllowUnsafeUpdates = false;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
web.AllowUnsafeUpdates = false;
}
}
}
});
}
I am getting this error-
The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.
at this line
docLib.WorkflowAssociations.Add(workFlow);
Any any have any suggestions please ? Thanks for your feedback.
Why do you need "SPUtility.ValidateFormDigest()" at all?
Your code was running in an event receiver, not on a form or aspx page, there is nothing to validate.
Could you remove this line and try again?
I believe updating this code block:
web.AllowUnsafeUpdates = true;
web.ValidateFormDigest();
docLib.WorkflowAssociations.Add(workFlow);
docLib.EnableModeration = true;
docLib.Update();
web.Update();
web.AllowUnsafeUpdates = false;
and replacing it with:
web.Site.WebApplication.FormDigestSettings.Enabled = false;
docLib.WorkflowAssociations.Add(workFlow);
docLib.EnableModeration = true;
docLib.Update();
web.Update();
web.Site.WebApplication.FormDigestSettings.Enabled = true;
Let me know if this works for you or if you still encounter the same error.

Sharepoint 2010 EventReceiver for SPFolder adding

I have a document library in which we have added a custom folder content type in order to keep the Folder Owner in a custom field.
Now I am asked to set the default value of the "Add new" form to the Parent Folder Owner. I have tried this code below but the event fires after saving the new Folder. Could anyone pls help me? How can I set this default value before opening the form?
public override void ItemAdding(SPItemEventProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
try
{
this.EventFiringEnabled = false;
base.ItemAdding(properties);
if (properties.List.RootFolder.Name == "Documents")
{
SPWeb web = properties.List.ParentWeb;
SPList List = properties.List;
SPField fld = List.Fields["Folder Owner"];
SPUser usr = web.CurrentUser;
SPFieldUserValue curUser = new SPFieldUserValue();
curUser.LookupId = usr.ID;
SPFolder parentFolder = web.GetFolder(properties.AfterUrl.Substring(0,properties.AfterUrl.LastIndexOf("/")));
if (parentFolder.Item["Folder Owner"] == null)
{
fld.DefaultValue = curUser.ToString();
}
else
{
fld.DefaultValue = parentFolder.Item["Folder Owner"].ToString();
}
fld.Update();
List.Update();
}
}
catch (Exception)
{
}
finally
{
this.EventFiringEnabled = true;
}
});
}

How to programmatically set the task outcome (task response) of a Nintex Flexi Task?

Is there any way of set a Nintex Flexi task completion through Sharepoint's web services? We have tried updating the "WorkflowOutcome", "ApproverComments" and "Status" fields without success (actually the comments and status are successfully updated, however I can find no way of updating the WorkflowOutcome system field).
I can't use the Nintex Web service (ProcessTaskResponse) because it needs the task's assigned user's credentials (login, password, domain).
The Asp.net page doesn't have that information, it has only the Sharepoint Administrator credentials.
One way is to delegate the task to the admin first, and then call ProcessTaskResponse, but it isn't efficient and is prone to errors.
In my tests so far, any update (UpdateListItems) to the WorkflowOutcome field automatically set the Status field to "Completed" and the PercentComplete field to "1" (100%), ending the task (and continuing the flow), but with the wrong answer: always "Reject", no matter what I try to set it to.
Did you try this code: (try-cacth block with redirection does the trick)
\\set to actual outcome id here, for ex. from OutComePanel control
taskItem[Nintex.Workflow.Common.NWSharePointObjects.FieldDecision] = 0;
taskItem[Nintex.Workflow.Common.NWSharePointObjects.FieldComments] = " Some Comments";
taskItem.Update();
try
{
Nintex.Workflow.Utility.RedirectOrCloseDialog(HttpContext.Current, Web.Url);
}
catch
{
}
?
Here are my code to change outcome of nintex flexi task. My problem is permission. I had passed admin token to site. It's solve the problem.
var siteUrl = "...";
using (var tempSite = new SPSite(siteUrl))
{
var sysToken = tempSite.SystemAccount.UserToken;
using (var site = new SPSite(siteUrl, sysToken))
{
var web = site.OpenWeb();
...
var cancelled = "Cancelled";
task.Web.AllowUnsafeUpdates = true;
Hashtable ht = new Hashtable();
ht[SPBuiltInFieldId.TaskStatus] = SPResource.GetString(new CultureInfo((int)task.Web.Language, false), Strings.WorkflowStatusCompleted, new object[0]);
ht["Completed"] = true;
ht["PercentComplete"] = 1;
ht["Status"] = "Completed";
ht["WorkflowOutcome"] = cancelled;
ht["Decision"] = CommonHelper.GetFlexiTaskOutcomeId(task, cancelled);
ht["ApproverComments"] = "cancelled";
CommonHelper.AlterTask((task as SPListItem), ht, true, 5, 100);
task.Web.AllowUnsafeUpdates = false;
}
}
}
}
}
}
public static string GetFlexiTaskOutcomeId(Microsoft.SharePoint.Workflow.SPWorkflowTask task, string outcome)
{
if (task["MultiOutcomeTaskInfo"] == null)
{
return string.Empty;
}
string xmlOutcome = HttpUtility.HtmlDecode(task["MultiOutcomeTaskInfo"].ToString());
if (string.IsNullOrEmpty(xmlOutcome))
{
return string.Empty;
}
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlOutcome);
var node = doc.SelectSingleNode(string.Format("/MultiOutcomeResponseInfo/AvailableOutcomes/ConfiguredOutcome[#Name='{0}']", outcome));
return node.Attributes["Id"].Value;
}
public static bool AlterTask(SPListItem task, Hashtable htData, bool fSynchronous, int attempts, int milisecondsTimeout)
{
if ((int)task[SPBuiltInFieldId.WorkflowVersion] != 1)
{
SPList parentList = task.ParentList.ParentWeb.Lists[new Guid(task[SPBuiltInFieldId.WorkflowListId].ToString())];
SPListItem parentItem = parentList.Items.GetItemById((int)task[SPBuiltInFieldId.WorkflowItemId]);
for (int i = 0; i < attempts; i++)
{
SPWorkflow workflow = parentItem.Workflows[new Guid(task[SPBuiltInFieldId.WorkflowInstanceID].ToString())];
if (!workflow.IsLocked)
{
task[SPBuiltInFieldId.WorkflowVersion] = 1;
task.SystemUpdate();
break;
}
if (i != attempts - 1)
{
Thread.Sleep(milisecondsTimeout);
}
}
}
var result = SPWorkflowTask.AlterTask(task, htData, fSynchronous);
return result;
}

Get custom templates programmatically sharepoint 2010

To get standard templates I do:
private void getTemplates()
{
string server = serverURL();
using (SPSite siteCollection = new SPSite(server))
{
SPWebTemplateCollection Templates = siteCollection.GetWebTemplates(1033);
foreach (SPWebTemplate template in Templates)
{
ddlSiteTemplate.Items.Add(new ListItem(template.Title, template.Name));
}
}
}
I thought I could do:
private void getTemplates()
{
string server = serverURL();
using (SPSite siteCollection = new SPSite(server))
{
SPWebTemplateCollection Templates = siteCollection.GetCustomWebTemplates(1033);
foreach (SPCustomWebTemplate template in Templates)
{
ddlSiteTemplate.Items.Add(new ListItem(template.Title, template.Name));
}
}
}
To get the custom templates but the dropdown is empty, what am I doing wrong here?
Thanks in advance.
Edit: the templates are activated in the solutions gallery.
I got it to work with
private void getTemplates()
{
string server = serverURL();
using (SPSite siteCollection = new SPSite(server))
{
SPWebTemplateCollection Templates = siteCollection.GetAvailableWebTemplates(1033);
foreach (SPCustomWebTemplate template in Templates)
{
//this gives me all templates, both standard and custom so I filter by name
if(template.name.ToUpper().StartsWith("CUSTOM"))
{
ddlSiteTemplate.Items.Add(new ListItem(template.Title, template.Name));
}
}
}
}
SPSite does not contain a GetAvailableWebTemplates method. For those who would like to use the code use the one below. So I have added this line of code:
using(SPWeb web = siteCollection.OpenWeb())
{
SPWebTemplateCollection Templates = web.GetAvailableWebTemplates(1033);
Full code:
private void getTemplates()
{
string server = serverURL();
using (SPSite siteCollection = new SPSite(server))
{
using(SPWeb web = siteCollection.OpenWeb())
{
SPWebTemplateCollection Templates = web.GetAvailableWebTemplates(1033);
foreach (SPCustomWebTemplate template in Templates)
{
//this gives me all templates, both standard and custom so I filter by name
if(template.name.ToUpper().StartsWith("CUSTOM"))
{
ddlSiteTemplate.Items.Add(new ListItem(template.Title, template.Name));
}
}
}
}
}