AWG Blogs

Showing posts with label SharePoint. Show all posts
Showing posts with label SharePoint. Show all posts

Sunday, January 13, 2013

Dev on Alternate Machine

This is for when you want to work on a different SharePoint 2007 dev machine but not have to change host name configuration entries in your Silverlight code.

- edit the Windows hosts file adding
127.0.0.1 yourPrimaryServerName

- add yourPrimaryServerName as a public url for the intranet zone of your web app in the alternate access mappings

- add a host header value of "yourPrimaryServerName" to the site's IIS 6 configuration

- set DisableLoopbackCheck see http://support.microsoft.com/kb/896861
- add the following files to c:\inetpub\wwwroot (or a subdir, check IIS for the actual root dir the 80 site)

clientaccesspolicy.xml

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>

<grant-to>
<resource include-subpaths="true" path="/"></resource>
</grant-to>
</policy>
</cross-domain-access>

</access-policy>

crossdomain.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- The file must be configured to allow access to the service from any other domain,
or it is not recognized by Silverlight 4.
Save the crossdomain.xml file to the root of the domain where the service is hosted.
If, for example, the service is hosted in http://fabrikam.com,
then the file must be located at http://fabrikam.com/crossdomain.xml.
-->
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>

</cross-domain-policy>
ref

Thursday, December 13, 2012

Testing Email in SharePoint Dev Environment

Tried this. Installing local dummy SMTP not possible. Finally just configured the local SMTP Virtual Server in IIS 6.0 Manager, setting the FQDN of the local server in Advanced Delivery, leaving Smart host empty. Then in used the local server for Outbound SMTP server in CA Outgoing E-Mail Settings.

Try adding a user to a group and leaving send email checked, and, bingo, email appears in c:\inetpub\mailroot\Queue.

Thursday, November 1, 2012

GetListItemChangesSinceTokenAsync and Paging

It's possible to page with GetListItemChangesSinceTokenAsync. For instance, if the result returns a ListItemCollectionPositionNext value, you know there are more results.

When make the call to retrive those results however, you must set changeToken to null. When I inserted the changeToken in a query for more paged results, I got zero results, which may seem counterintuitive, but actually makes sense because adding a changeToken that implicitely pointed to the next result set would be redundant as ListItemCollectionPositionNext already indicates this.

Monday, September 17, 2012

Debugging Silverlight to SSL'd SharePoint .asmx from VS

As explained here, there are a few steps you need to take to enable this scenario, i.e. to get around:

An error occurred while trying to make a request to URI 'https://machinename/_vti_bin/Lists.asmx'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.

Copy the following files to C:\inetpub\wwwroot\wss\VirtualDirectories\443: crossdomain.xml:
<?xml version="1.0" encoding="utf-8"?>
<!-- The file must be configured to allow access to the service from any other domain, 
or it is not recognized by Silverlight 4.
Save the crossdomain.xml file to the root of the domain where the service is hosted. 
If, for example, the service is hosted in http://fabrikam.com, 
then the file must be located at http://fabrikam.com/crossdomain.xml.
-->
<!DOCTYPE cross-domain-policy SYSTEM 
"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type"/>
  
</cross-domain-policy>
clientaccesspolicy.xml:
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
              <domain uri="http://*"/>
              <domain uri="https://*"/>
            </allow-from>

      <grant-to>
        <resource include-subpaths="true" path="/"></resource>
      </grant-to>
    </policy>
  </cross-domain-access>
  
</access-policy>
Note the subpaths="true"! Then open https://machinename/clientaccesspolicy.xml in browser (BTW verify its wellformed xml), accept the security warning, then click Certificate Error, View Certificate, then Install Certificate..., Next, then "Place all certificates in the following store", select "Trusted Root Certification Authorities", OK. After that, you should be able to F5 your Visual Studio 2010 Silverlight 5 app, and load your data from the SSL enabled Sharepoint 2007 web service. Ref1, ref2

Tuesday, April 24, 2012

SharePointMVC Note

When following the Deployment.docx, the instructions say to put the DLLs in the SharePoint website _app_bin. Well, I had to also put the web app DLL in the SharePoint website bin folder to get it working; otherwise I'd get the error: Could not load type 'SampleWebApplication.xxxxxx'.   at System.Web.UI.TemplateParser.GetType(String typeName, Boolean ignoreCase, Boolean throwOnError)
   at System.Web.UI.TemplateParser.ProcessInheritsAttribute(String baseTypeName, String codeFileBaseTypeName, String src, Assembly assembly)
   at System.Web.UI.TemplateParser.PostProcessMainDirectiveAttributes(IDictionary parseData)

Sunday, January 29, 2012

Sharepoint PowerShell Shortcuts

Command to output sorted site columns:
PS C:\WINDOWS\system32\WindowsPowerShell\v1.0> [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
PS C:\WINDOWS\system32\WindowsPowerShell\v1.0> set-variable -option constant -name url -value "http://servername/sites/teamsite/"
PS C:\WINDOWS\system32\WindowsPowerShell\v1.0> $site = new-object Microsoft.SharePoint.SPSite($url)
PS C:\WINDOWS\system32\WindowsPowerShell\v1.0> $site.rootweb.Fields | foreach { $fieldValues = @{ "Display Name" = $_.Title; "Internal Name" = $_.InternalName; "Value" = $site.rootweb.AvailableFields.GetFieldByInternalName($_.InternalName) }; New-Object PSObject -Property $fieldValues | Select @("Display Name","Internal Name","Value") } | Sort-Object -Property "Internal Name" | Out-GridView

refs:
http://get-spscripts.com/2010/09/get-all-column-values-from-sharepoint.html

see also: http://blogs.flexnetconsult.co.uk/colinbyrne/2008/02/26/PowerShellSharePointAddAListItem.aspx

Wednesday, January 18, 2012

Adapting the schema.xml

I wanted to add a new field to the base item content type -- i.e. content type ID 0x01. I also wanted to change the display name of title. This is what worked for my schema.xml.

Copy the Schema.xml from FEATURES\CustomList\CustList to my Feature folder named after the Name attribute of the ListTemplate element.

Comment out both ContentTypeRef elements.

Create a ContentType element that likes like:
<ContentType
ID="0x0100DECA7022CD234bb1BE7E9BCFF593552F"
Name="Item"
Group="List Content Types"
Description="Create a new list item.">
<FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"
Name="Title"
Required="TRUE"
DisplayName="My Title"
/>
<FieldRef ID="{AA242460-9794-4d45-A726-938D1B8B7D72}"
Name="My Added field"
Required="FALSE"
/>

</FieldRefs>


</ContentType>

NOTE the ContentType ID structure: follows the GUID method from MSDN http://msdn.microsoft.com/en-us/library/ie/aa543822.aspx, MAKE sure to remove any hyphens!!!

Add all modified fields to the Fields element, including Title, LinkFilenameNoMenu, and LinkTitle. You can get samples from a schema.xml that you copy from a list in SharePoint Manager.

Adjust View BaseViewID="1" as needed.

Wednesday, January 11, 2012

SharePoint Workflows on 64bit server

This is a quick start on how to get a functioning workflow compiled, installed, and running to completion. It will simply log a message to the workflow history; that's it.

Assumes Visual Studio 2008 is installed on Windows Server 2003 64bit with WSPBuilder.

File, New Project, WSPBuilder Project with Workflow

Right-click project in Solution Explorer and choose Workflow, Sequential Workflow (code) - note: I tried using Sequential Workflow with definition expressed as Xaml and user code in a separate code file, but I got errors such as "RunWorkflow: System.Workflow.Activities.EventDeliveryFailedException: Event "OnWorkflowActivated" on interface type "Microsoft.SharePoint.Workflow.ISharePointService" for instance id "405ff0ae-d08d-41b8-ab69-be69ae4ccde1" cannot be delivered. ---> System.Workflow.Runtime.QueueException: Event Queue operation failed with MessageQueueErrorCode QueueNotFound for queue 'Message Properties Interface Type:Microsoft.SharePoint.Workflow.ISharePointService Method Name:OnWorkflowActivated CorrelationValues: '. "

Drag a onWorkflowActivated control onto the designer
Set its CorrelationToken property to anything, e.g. "mytoken"; then expand CorrelationToken and for OwnerActivityName, choose Workflow1 (e.g.)

Drag a logToHistoryListActivity onto the canvas under the onWorkflowActivated1 control.
Double click its MethodInvoking property, and enter the following code into the body of the method: var workflowProperties = new Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties();

this.logToHistoryListActivity1.HistoryOutcome = "Here is a comment " + workflowProperties.InitiationData;


Build Solution

Right click property and choose WSPBuilder, Copy to GAC

Create a folder called MyLoggingWorkflowFeature under C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES\

Create two xml files in this folder:
Feature.xml:
<?xml version="1.0" encoding="utf-8"?>

<Feature Id="genkey id here"
Title="Workflow to create a log something to history"
Description="Logs something to history"
Version="12.0.0.0"
Scope="Site"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="workflow.xml" />
</ElementManifests>
</Feature>

workflow.xml:

<?xml version="1.0" encoding="utf-8"?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Workflow
Name="New Task Workflow"
Description="Creates a new task"
Id="yourId here from genkey tool"
CodeBesideClass="NewTaskWorkflow.Workflow3"
CodeBesideAssembly="NewTaskWorkflow, Version=1.0.0.1, Culture=neutral, PublicKeyToken=yourkeytokenhere"
></Workflow>

</Elements>

Sunday, December 25, 2011

Copying Discussion Items to Document Libary

The Requirement is to copy discussion items to another document library.

Code ideas borrowed from: http://stackoverflow.com/questions/468469/how-do-you-upload-a-file-to-a-document-library-in-sharepoint, http://sharepoint.stackexchange.com/questions/20216/iterate-through-discussion-list, http://www.sharepoint-tips.com/2011/11/event-handler-to-archive-items-when.html

Sample code containing the general idea:
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace WebPart3
{
[Guid("26d38752-d4ce-456e-88f6-496d213627d4")]
public class WebPart3 : System.Web.UI.WebControls.WebParts.WebPart
{
string msg1;
Button saveTitle;
TextBox newTitle;
Label label;

public WebPart3()
{
SPSite site1 = SPContext.Current.Site;

msg1 = "(1.03)" ;

}

public void saveTitle_click(object sender, EventArgs e)
{
//this.Title = newTitle.Text;
string tempprint = "";
SPWeb myweb = SPContext.Current.Web;
SPListCollection lists = myweb.Lists;
SPList mylist;
SPListItem sli;
string labeltext = "";
SPList targetList;

try
{

// SPList targetList = lists["Discussion Archive"];
// SPListItem newItem = targetList.Items.Add();

mylist = lists[newTitle.Text];
targetList = lists["Discussion Archive"];
// targetList = lists["DiscussionDocs"];

// SPQuery query = new SPQuery();
//query.RowLimit = 10;
// SPListItemCollection posts = mylist.GetItems(query);

//this. .SaveProperties = true;
try
{
labeltext += " entering foreach";
foreach (SPListItem item in mylist.Folders)
{
SPListItem newItem = targetList.Items.Add();
//copy the list item to the target
foreach (SPField f in item.Fields)
{
if (!f.ReadOnlyField && newItem.Fields.ContainsField(f.InternalName))
newItem[newItem.Fields.GetFieldByInternalName(f.InternalName).Id] = item[f.Id];
}
//copy "special" read only fields that can be written to
newItem["Created By"] = item["Created By"];
newItem["Modified By"] = item["Modified By"];
newItem["Modified"] = item["Modified"];
newItem["Created"] = item["Created"];
newItem.SystemUpdate(false);
CopyAttachments(item, newItem);


labeltext += item["Body"] + ",";
sli = item;
tempprint = (string)sli["Created By"];
}
labeltext += " existing foreach";
try
{
this.Title = "yo" + mylist.ItemCount + " by: " + tempprint;

}
catch (Exception ex)
{
this.Title = "Error3: " + ex.Message;
label.Text = ex.StackTrace;

}
}
catch (Exception ex)
{

this.Title = "Error2: " + ex.Message;
label.Text = ex.StackTrace;
}
}
catch (Exception ex)
{
this.Title = "Error: " + ex.Message;
label.Text = ex.StackTrace;
}
label.Text += labeltext + "the end";
// this.SetPersonalizationDirty();
}

private void CopyAttachments(SPListItem sourceItem, SPListItem targetItem)
{
SPWeb web = SPContext.Current.Web;

SPFolder myLibrary = web.Folders["DiscussionDocs"];
Boolean replaceExistingFiles = true;

try
{
//get the folder with the attachments for the source item
SPFolder sourceItemAttachmentsFolder = sourceItem.Web.Folders["Lists"].SubFolders[sourceItem.ParentList.Title]
.SubFolders["Attachments"].SubFolders[sourceItem.ID.ToString()];
foreach (SPFile file in sourceItemAttachmentsFolder.Files)
{
byte[] binFile = file.OpenBinary();
targetItem.Attachments.AddNow(file.Name, binFile);
this.label.Text += file.Name + " attached to target ";
SPFile spfile = myLibrary.Files.Add(file.Name, binFile, replaceExistingFiles);
SPListItem newfileitem = spfile.Item;
newfileitem["Created"] = sourceItem["Created"];
newfileitem["Modified By"] = sourceItem["Modified By"];
newfileitem["Modified"] = sourceItem["Modified"];
newfileitem["Created By"] = sourceItem["Created By"];
newfileitem["Title"] = sourceItem["Title"];
//newfileitem.SystemUpdate(false);
newfileitem.Update();

myLibrary.Update();
}
}
catch (Exception ex)
{
this.Title = "Error: " + ex.Message;
}
}

protected override void CreateChildControls()
{
base.CreateChildControls();

// TODO: add custom rendering code here.
label = new Label();
label.Text = "Hello World" + msg1;
this.Controls.Add(label);

//Create text box
newTitle = new TextBox();
newTitle.Text = "myxmdiscuss";
this.Controls.Add(newTitle);

//Create Button
saveTitle = new Button();
saveTitle.Text = "Set Web Partt Title";
saveTitle.Click += new EventHandler(this.saveTitle_click);
Controls.Add(saveTitle);
}
}
}


And here's the Powershell:


$error.clear()

[System.reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

$site = new-object Microsoft.SharePoint.SPSite("https://site")
$web = $site.OpenWeb()

$lists = $web.Lists;

$lista = $lists['Team Discussion']
$listb = $web.Folders['MyDocLib']

foreach ($item in $lista.Folders)
{
Try
{
$sourceItemAttachmentsFolder = $item.Web.Folders["Lists"].SubFolders[$item.ParentList.Title].SubFolders["Attachments"].SubFolders[$item.ID.ToString()];
foreach ($file in $sourceItemAttachmentsFolder.Files)
{
$binfile = $file.OpenBinary()
"Attached to target " + $item["Title"]
$spfile = $listb.Files.Add($file.Name, $binfile, 1)
$newfileitem = $spfile.Item
foreach ($f in $item.Fields)
{
if (!$f.ReadOnlyField -and $newfileitem.Fields.ContainsField($f.InternalName))
{
$newfileitem[$newfileitem.Fields.GetFieldByInternalName($f.InternalName).Id] = $item[$f.Id];
}

$newfileitem["Created By"] = $item["Created By"];

$newfileitem["Created"] = $item["Created"];

$newfileitem["Modified By"] = $item["Modified By"];

$newfileitem["Modified"] = $item["Modified"];

$newfileitem.Update();

}
}

}
Catch
{

"caught a system exception"
}

$error

}

Note: Minimum permissions to execute the ps1 is local server administrator + Site owner.