Dev Team Assemble

Evil beware!
Add to Technorati Favorites

Archive

Tag: Development

One of the things I was working on today was trying to get an actual image from the library was that initially I was expecting to get a PublishingImage.  All the samples on MSDN and the ones strewn about the web refer to using the ImageFieldValue and getting it from a field in the SPListItem.  Like outlined on MSDN :

  // Retrieve the current value from an SPListItem with a
  // column of the ImageField type with the name imageFieldName
  ImageFieldValue currentFieldValue =
        listItemWithImageField[imageFieldName] as ImageFieldValue;

The problem is this only works for images that are in a list, like the PublishingRollupImage of a page that links to an image in the Site Collection Images library.  The actual images in the library are stored as documents (Referenced using SPFile) so in order utilize them I need to extract the information out and create an image tag for it...like so:

 
     ImageFieldValue imageValue = new ImageFieldValue(
          string.Format("<img src=\"{0}\" alt=\"{1}\" />",
          file.Url, file.Title == null ? string.Empty : file.Title));
 

Now that I had the ImageFieldValue it was easy to work with. I could manipulate many aspects of the image using this object and then save it for rendering using ToString(). Funny thing is for my purposes (ImageGallery xml generation) I didn't even end up needing this code after all...frustrating but a good learning experience.

Props to Phanat Chan as he did the initial development on this.

Technorati Tags: , ,

I came across this problem recently. Its a little strange and only happened once I changed my base webpart class to inherit from Microsoft.SharePoint.WebPartPages.WebPart. There seems to be two fixes for this problem that I implemented:

  • remove the XMlNamespace from class declaration
  • Use a .dwp file instead of a .webpart file in your feature folder

Technorati Tags: , ,

For the last little bit I have been working on learning how to package up all site infrastructure into a single feature.  All of this is pretty straight forward and I didn't really have any issues.....UNTIL  I tried to get lookup columns working.

Using CAML

I did some reading on the subject and apparently you can do all of this using CAML alone.  I came across a post from Josh Gaffery supporting this claim, but I simply could not get this working...so i gave up after spinning my wheels on it for longer than I wanted to.  Josh's approach is to use the list URL as opposed to the GUID that links the column to the source list and he has put up an update explaining it further.  Nonetheless....didn't work for me.

Using Feature Receiver

I knew that at this point I would have to take the feature reciever approach and modify the fields in place or create them.  I found two sources that both take different approachs to this problem.

  • Chris O'Brien has put together the a project on CodePlex that will create the lookup columns at activation time.  This actully sounds like a pretty good approach but unfortunately it didn't work for me.  I dont know if there is something wrong with my environment but I encountered a few errors doing this...things like the fields not rendering on the page layouts and getting the "The local device name is already in use. (Exception from HRESULT: 0x80070055)" error.
  • Waldek Mastykarz has a great post on creating the columns via code here.

Basically I took a hybrid approach to doing this by mixing the two approaches mentioned above.  I created a custom XML file that I deploy into the layouts directory and then use a feature reciever to read the xml content and create lookup columns based on this.  I also added a deactiving event to remove the fields when the feature is deactivated.  Heres the feature reciever code:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            using (SPSite site = properties.Feature.Parent as SPSite)
            {
                string contentTypes = null;
                string listName = null;
                string fieldName = null;
                string groupName = null;
                string staticName = null;
                string lookupFieldName = "Title";
                bool mult = false;
                bool required = false;
                string filePath = properties.Feature.Properties[
                   "ColumnDefinitionPath"].Value;
 
                XmlTextReader xReader = new XmlTextReader(
                  HttpContext.Current.Server.MapPath(@"~\_layouts\" + filePath));
                while (xReader.Read())
                {
                    if (xReader.LocalName == "Field")
                    {
                        #region Get values from attributes
                        if (xReader.MoveToAttribute("List"))
                        {
                            listName = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("Name"))
                        {
                            fieldName = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("StaticName"))
                        {
                            staticName = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("Group"))
                        {
                            groupName = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("LookUpField"))
                        {
                            lookupFieldName = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("ExistInContentTypes"))
                        {
                            contentTypes = xReader.Value;
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("Mult"))
                        {
                            bool.TryParse(xReader.Value, out mult);
                            xReader.MoveToElement();
                        }
                        if (xReader.MoveToAttribute("Required"))
                        {
                            bool.TryParse(xReader.Value, out required);
                            xReader.MoveToElement();
                        }
 
                        #endregion
 
                        SPFieldLookup lookup = CreateLookupField(
                          fieldName, groupName, required, mult, site.RootWeb,
                          site.RootWeb.Lists[listName], lookupFieldName, staticName);
                        if (contentTypes != null)
                            foreach (string s in contentTypes.Split(','))
                            {
                                LinkFieldToContentType(s.Trim(), (SPField)lookup);
                            }
                    }
                }
 
                xReader.Close();
 
            }
        }
 
        public static SPFieldLookup CreateLookupField(
          string fieldName, string group, bool required, bool allowMultipleValues,
          SPWeb w, SPList lookupList, string lookupField, string staticName)
        {
            w.Fields.AddLookup(fieldName, lookupList.ID,
               lookupList.ParentWeb.ID, required);
            SPFieldLookup lookup = (SPFieldLookup)w.Fields[fieldName];
            lookup.AllowMultipleValues = allowMultipleValues;
            lookup.LookupField = lookupField;
            lookup.StaticName = staticName;
            lookup.Group = group;
            lookup.Update(true);
            return lookup;
        }
 
        public static void LinkFieldToContentType(string contentType, SPField field)
        {
            using (SPSite site = SPContext.Current.Web.Site as SPSite)
            {
                SPContentType ct = site.RootWeb.ContentTypes[contentType];
                ct.FieldLinks.Add(new SPFieldLink(field));
                ct.Update(true); // will update children
            }
        }

As you can read from the above code the xml file would need to have a node like below for each lookup column:

 
<Field
         Type="Lookup"
         List="Access Type"
         Name="AccessTypeColumn"
         StaticName="Access_x0020_Type"
         Group="Infrastructure"
         ExistInContentTypes="THIS IS A COMMA DELIMITED LIST OF CONTENT NAMES"
         LookUpField="Title"
         Mult="TRUE"
         Required="FALSE"
        />
 

The Final Project

So here are all the pieces of my infrastructure project. Notice the placement of the lookupfields xml file...this is because the layouts directory is setup as a virtual directory for every sharepoint site and we can read files from there without a permissions problem.

12/TEMPLATES/FEATURES/myfeature/lists.xml this contains the source lists for the lookup fields
12/TEMPLATES/FEATURES/myfeature/contenttypes.xml this contains the content type definitions MINUS the lookup fields
12/TEMPLATES/FEATURES/myfeature/sitecolumns.xml this contains all the other fields included in the content types
12/TEMPLATES/FEATURES/myfeature/feature.xml the feature def
12/TEMPLATES/LAYOUTS/myfeature/lookupfields.xml this contains all the lookup fields that need to be provisioned

Hopefully this helps anyone who's been having problems getting this going. And a big thanks to Waldek, Chris and Josh for their posts.

Technorati Tags: , , , ,

Sometimes when I am working with SharePoint I really feel like I got it.  You now that feeling you get when you know exactly what you are doing and have no problems implementing it...then there are times when I really just want to smash something.  And it really doesn't matter what...it could be anything!  This is the feeling I got in the last couple of days working with custom field types in SharePoint.

It seems there are lots of blogs and articles out there talking about how to do it, but from what I could see (and to be fair I did not read them all so if you know of some good posts that would be great) it felt like most of the time I was only getting half the story.  I just finished putting together a very basic Custom Field Type that will display a multi line textbox in edit/new mode and simply display the value in a literal control in display mode.  In the grand scheme of things I am building a base XML Field Type to use for a series of additional Custom field types so essentially I want to store a string (yes I could use the XmlDocument)...but alas thats a story for another day.

So a bit of a primer, or rehash so I don't forget, when developing custom field types there are many pieces to it....not all of them required.  Here is a list of the items and what they do:

  • Field Type class - this class acts as the controller and hooks the rendering control, field type xml definition and the value class together.  It also provides validation at the field level via the GetValidatedString() method of the SPField object
  • Field Control class - this is the rendering engine and gives you the power to display your control in any manner you wish as well as perform validation on the data being saved via the UI.
  • Field Value class - allows for custom logic to be put around mutiple column fields and different data structures that will be storing data for your field type.
  • .ascx file in CONTROLTEMPLATES directory - this supplies rendering markup via a user control and hooks into the field control class
  • fldtypes_* - this file that gets installed into the 12/TEMPLATES/XML directory and contains the information that SharePoint requires in order to load your field type into the system.  Such as the assembly to use, the parent type and other information.  This is required if the type is going to be applied to content types and become a field on a list.

So for my requirements I only needed the field type, the field control and the fldtypes_xxx.xml file.  Lets look at the field type class I built

public class XmlFieldType : SPField
   {
        public XmlFieldType(SPFieldCollection fields, string fieldName) : base(fields, fieldName) { }
        public XmlFieldType(SPFieldCollection fields, string fieldName, string displayName) : base(fields, fieldName, displayName) { }
 
        public override BaseFieldControl FieldRenderingControl
        {
            get
            {
                BaseFieldControl fldControl = new XmlFieldControl();
                fldControl.FieldName = InternalName;
                return fldControl;
            }
        }
 
        public override object GetFieldValue(string value)
        {
            if (string.IsNullOrEmpty(value))
                return null;
            return value;
        }
 
        public override Type FieldValueType
        {
            get { return typeof(string); }
        }
 
        public override string DefaultValue
        {
            get
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(this.SchemaXml);
                XmlNode nodeInFieldSchema = doc.SelectSingleNode("Field/Default");
                if (nodeInFieldSchema != null)
                    return nodeInFieldSchema.InnerXml;
                return null;
            }
            set { base.DefaultValue = value; }
        }
 
        public override string GetValidatedString(object value)
        {
            base.GetValidatedString(value);
            if (value == null)
            {
                if (this.Required) throw new SPFieldValidationException("Invalid value for required field.");
                return string.Empty;
            }
            else
            {
                return value.ToString();
            }
        }
}

Lets review

  • The two constructors are required...don't even bother
  • FieldRenderingControl() method tells the field type which control to use
  • GetFieldValue() method returns the value of the field....if we were using a custom type you would cast that to the appropriate type here
  • FieldValueType() - get the type of the Value class
  • DefautValue() - this gets the default value from the field if one is defined
  • GetValidatedString() - perform field level validation

The Field Control Class is fairly simple as well:

public class XmlFieldControl : BaseFieldControl
{
        protected Literal _values;
        protected TextBox _editor;
 
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            EnsureChildControls();
        }
 
        protected override void CreateChildControls()
        {
 
            if (this.Field == null || this.ControlMode == SPControlMode.Invalid)
                return;
 
            Controls.Clear();
            base.CreateChildControls();
            _editor = new TextBox();
            _editor.TextMode = TextBoxMode.MultiLine;
            _editor.Height = new Unit(300);
            _editor.Width = new Unit(500);
            Controls.Add(_editor);
 
            if (ControlMode == SPControlMode.Display)
            {
                _values = new Literal();
                _values.Text = Convert.ToString(ItemFieldValue);
                Controls.Add(_values);
            }
        }
 
        protected override void Render(HtmlTextWriter output)
        {
 
            EnsureChildControls();
            if (ControlMode == SPControlMode.Display)
            {
                if (_values != null)
                    _values.RenderControl(output);
            }
            else
            {
                if (_editor != null)
                    _editor.RenderControl(output);
            }
        }
 
        public virtual string Text
        {
            get
            {
                this.EnsureChildControls();
                if (this._editor == null)
                {
                    return null;
                }
                return this._editor.Text;
            }
 
            set
            {
                this.EnsureChildControls();
                if (this._editor != null)
                {
                    this._editor.Text = value;
                }
            }
        }
 
        public override object Value
        {
            get
            { return this.Text; }
            set
            {
                if (base.Field != null)
                {
                    this.Text = base.Field.GetFieldValueForEdit(value);
                    base.Value = (string)value;
                    base.UpdateFieldValueInItem();
                }
            }
        }
    }

Lets take a look at what this class is doing:

  • OnInit() - come on, do I have to explain?
  • CreateChildControls() - initialize your controls and add to the Controls collection
  • Render() - writes the controls to the HtmlTextWriter
  • Text - This sets/gets the value in the controls
  • Value - this sets the value in the Text property and notice the base.UpdateFieldValueInItem(); statement...this oushes the value from Value to ItemFieldValue and allows you to access this value in display mode because Value returns null (which i did not find the documentation on M$ thank you very much).

So that leaves the last piece of the pie for my simple implementation the fldtypes file:

&lt;FieldTypes&gt;
&lt;FieldType&gt;
&lt;Field Name="TypeName"&gt;XmlFieldType&lt;/Field&gt;
&lt;Field Name="ParentType"&gt;&lt;/Field&gt;
&lt;Field Name="InternalType"&gt;Note&lt;/Field&gt;
&lt;Field Name="SQLType"&gt;ntext&lt;/Field&gt;
&lt;Field Name="TypeDisplayName"&gt;Xml Field&lt;/Field&gt;
&lt;Field Name="TypeShortDescription"&gt;Xml controls&lt;/Field&gt;
&lt;Field Name="UserCreatable"&gt;TRUE&lt;/Field&gt;
&lt;Field Name="ShowOnListCreate"&gt;TRUE&lt;/Field&gt;
&lt;Field Name="Sortable"&gt;FALSE&lt;/Field&gt;
&lt;Field Name="AllowBaseTypeRendering"&gt;FALSE&lt;/Field&gt;
&lt;Field Name="Filterable"&gt;FALSE&lt;/Field&gt;
&lt;Field Name="FieldTypeClass"&gt;Website.CustomFields.XmlFieldType, Website.CustomFields, Version=1.0.0.0, Culture=neutral, PublicKeyToken=346fcdd567259ee6&lt;/Field&gt;
&lt;RenderPattern Name="HeaderPattern"&gt;
&lt;Property Select="DisplayName" HTMLEncode="TRUE"/&gt;
&lt;/RenderPattern&gt;
&lt;RenderPattern Name="DisplayPattern"&gt;
&lt;Column/&gt;
&lt;/RenderPattern&gt;
&lt;/FieldType&gt;
&lt;/FieldTypes&gt;

So there you have it.  All I need to do in order to inherit from this is to remove the rendering (which i dont need anyway  as this is going to be a base type) and it should be good to go.  Those three pieces of code can be installed into your SharePoint environment and should help you get started to understanding custom field types.

Don't forget to add the SafeControl entry, Adjust your trust level and move the .dll into your bin folder as well.

Download the code here

Resources I found useful:

  • I did work through the example in Andrew Connell's book (Professional SP 2007 WCM development) and that worked fine and he actually does a great job of explaining most of whats going on here.
  • MSDN...where else
  • Charlie Holland has a pretty good article series on this stuff but unfortunately I couldn't get it working.  I also wanted a simple bare bones implementation.
Sometimes when I am working with SharePoint I really feel like I got it.  You now that feeling you get when you know exactly what you are doing and have no problems implementing it...then there are times when I really just want to smash something.  And it really doesn't matter what...it could be anything!  This is the feeling I got in the last couple of days working with custom field types in SharePoint.  It seems there are lots of blogs and articles out there talking about how to do it, but from what I could see (and to be fair I did not read them all so if you know of some good posts that would be great) it felt like most of the time I was only getting half the story.  I just finished putting together a very basic Custom Field Type that will display a multiline textbox in edit/new mode and simply display the value in a literal control in display mode.  In the grand scheme of things I am building a base XML Field Type to use for a series of additional Custom field types so essentially I want to store a string (yes I could use the XmlDocument)...but alas thats a story for another day.

So a bit of a primer, or rehash so I don't forget, when developing custom field types there are many pieces to it....not all of them required.  Here is a lit of the items and what they do:

* Field Type class - this class acts as the controller and hooks the rendering control, field type xml definition and the value class together.  It also provides validation at the field level via the GetValidatedString() method of the SPField object
* Field Control class - this is the rendering engine and gives you the power to display your control in any manner you wish as well as perform validation on the data being saved via the UI.
* Field Value class - allows for custom logic to be put around mutiple column fields and different data structures that will be storing data for your field type.
* .ascx file in CONTROLTEMPALTES directory - this supplies rendering markup via a usercontrol and hooks into the field control class
* fldtypes_* - this file that gets installed into the 12/TEMPLATES/XML directory and contrains the information that SharePoint requires in order to load your field type into the system.  Such as the assembly to use, the parent type and other information.  This is required if the type is going to be applied to content types and become a field on a list.

So for my requirements I only needed the field type, the field control and the fldtypes_xxx.xml file.  Lets look at the field type class I built

public class XmlFieldType : SPField
{
public XmlFieldType(SPFieldCollection fields, string fieldName) : base(fields, fieldName) { }
public XmlFieldType(SPFieldCollection fields, string fieldName, string displayName) : base(fields, fieldName, displayName) { }
 
public override BaseFieldControl FieldRenderingControl
{
get
{
BaseFieldControl fldControl = new XmlFieldControl();
fldControl.FieldName = InternalName;
return fldControl;
}
}
 
public override object GetFieldValue(string value)
{
if (string.IsNullOrEmpty(value))
return null;
return value;
}
 
public override Type FieldValueType
{
get { return typeof(string); }
}
 
public override string DefaultValue
{
get
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(this.SchemaXml);
XmlNode nodeInFieldSchema = doc.SelectSingleNode("Field/Default");
if (nodeInFieldSchema != null)
return nodeInFieldSchema.InnerXml;
return null;
}
set { base.DefaultValue = value; }
}
 
public override string GetValidatedString(object value)
{
base.GetValidatedString(value);
if (value == null)
{
if (this.Required) throw new SPFieldValidationException("Invalid value for required field.");
return string.Empty;
}
else
{
return value.ToString();
}
}
}

Lets review

* The two constructors are required
* FieldRenderingControl() method tells the field type which control to use
* GetFieldValue() method returns the value of the field....if we were using a custom type you would cast that to the appropriate type here
* FieldValueType() - get the type of the Value class
* DefautValue() - this gets the default value from the field if one is defined
* GetValidatedString() - perform field level validation

The Field Control Class is fairly simple as well:

public class XmlFieldControl : BaseFieldControl
{
protected Literal _values;
protected TextBox _editor;
 
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
EnsureChildControls();
}
 
protected override void CreateChildControls()
{
 
if (this.Field == null || this.ControlMode == SPControlMode.Invalid)
return;
 
Controls.Clear();
base.CreateChildControls();
_editor = new TextBox();
_editor.TextMode = TextBoxMode.MultiLine;
_editor.Height = new Unit(300);
_editor.Width = new Unit(500);
Controls.Add(_editor);
 
if (ControlMode == SPControlMode.Display)
{
_values = new Literal();
_values.Text = Convert.ToString(ItemFieldValue);
Controls.Add(_values);
}
}
 
protected override void Render(HtmlTextWriter output)
{
 
EnsureChildControls();
if (ControlMode == SPControlMode.Display)
{
if (_values != null)
_values.RenderControl(output);
}
else
{
if (_editor != null)
_editor.RenderControl(output);
}
}
 
public virtual string Text
{
get
{
this.EnsureChildControls();
if (this._editor == null)
{
return null;
}
return this._editor.Text;
}
 
set
{
this.EnsureChildControls();
if (this._editor != null)
{
this._editor.Text = value;
}
}
}
 
public override object Value
{
get
{ return this.Text; }
set
{
if (base.Field != null)
{
this.Text = base.Field.GetFieldValueForEdit(value);
base.Value = (string)value;
base.UpdateFieldValueInItem();
}
}
}
}

sdfsdf

    XmlFieldType
 
    Note
    ntext
    Xml Field
    Xml controls
    TRUE
    TRUE
    FALSE
    FALSE
    FALSE
    Website.CustomFields.XmlFieldType, Website.CustomFields, Version=1.0.0.0, Culture=neutral, PublicKeyToken=346fcdd567259ee6

I did work through the example in Andrew Connell's book (Professional SP 2007 WCM development) and that worked fine and he actually does a great job of explaining most of whats going on here.

http://msdn.microsoft.com/en-us/library/ms446361.aspx

Technorati Tags: , , , ,

Its seems that SharePoint has a knack for surprising me with seriously strange errors sometimes. Usually at the core of the error there is a sound explanation as to why this is happening but nonetheless I am not pleased with the obscurity of them sometimes. Case in point, while working on a Console application that would load FBA (Forms Based Authentication) users into a sharepoint sie collection and then create a site for each one (granting permissions and so on) I came across a very strange error - SPException: SharePoint cannot find the user.

This kind of surprised me at first and I was wondering if somehow my CustomMembershipProvider setup stopped working on my portal site, but that was fine. So after hammering away at it for a while I came across a great article written by Waldek Mastykarz on this exact problem.  After reading through his investigation it makes sense why it doesn't work in a console application but it works under the context of a SharePoint website. Essentially the web application has access to a context object and this has access to the providers node in your web.config file,  BUT the console application does not have this information available.  So when the SharePoint assemblies attempt to access this information they cannot because it does not exist.

The way around this is to create an HttpContext in your application before attempting to run SPWeb.EnsureUser("blah") like so:

if (HttpContext.Current == null) { HttpRequest request = new HttpRequest("", web.Url, ""); HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter())); HttpContext.Current.Items["HttpHandlerSPWeb"] = web; }

Then add the system.web/membership/providers node to your app.config file (which you may have to create in the project)..  Mine looks like so:

<system.web> <membership> <providers> <add name="CustomSqlProvider" applicationName="/Portal" connectionStringName="sqlData" type="CustomProviders.CustomSqlMembershipProvider, CustomProviders, Version=1.0.0.0, Culture=neutral, PublicKeyToken=91a4fcd60b73a0e8" /> </providers> </membership> </system.web> <connectionStrings> <add name="sqlData" connectionString="Data Source=sqlpd; Initial Catalog=PUsers; Integrated Security=True; MultipleActiveResultSets=True " providerName="System.Data.SqlClient" /> </connectionStrings>

After adding this information and running a few tests it started to work. In fact it worked really well on my dev box...the only problem was it was a little intermittent on my production machine. Which is funny because the provider on the site itself works just fine all the time but in order to get my console application working (the EnsureUser() portion) the site would require an IIS reset. This is the one MAJOR stumbling block that I have yet to overcome...the only saving grace I have is that I can import the users manually into the system first using the UI and then run my console application that will load the sites and grant permissions to sites based on an external configuration file.

Many thanks to Waldek Mastykarz for all his help on this one so far...I know I will be coming back to this one in the near future but my head hurts a little and I need a beer.

Canadian SharePint event anyone?

Technorati Tags: , , , ,

Inside the Microsoft.SharePoint namespace there is the SPBasePermissions enumeration. It specifies the built-in permissions available in Windows SharePoint Services / MOSS 2007.  This was taken from the MSDN site, but I am posting it here because sometimes they move content around and I can't find it...ha ha you can't fool me Microsoft!!!

Using the enumerations below you can wrap some markup on your page in an SPSecurityTrimmedControl like so:

<Sharepoint:SPSecurityTrimmedControl runat="server" PermissionsString="CreateGroups">

and only allow users with the defined permission to see the contents of the security trimming control.

Member name Description
AddAndCustomizePages Add, change, or delete HTML pages or Web Part Pages, and edit the Web site using a Windows SharePoint Services–compatible editor.
AddDelPrivateWebParts Add or remove personal Web Parts on a Web Part Page.
AddListItems Add items to lists, add documents to document libraries, and add Web discussion comments.
ApplyStyleSheets Apply a style sheet (.css file) to the Web site.
ApplyThemeAndBorder Apply a theme or borders to the entire Web site.
ApproveItems Approve a minor version of a list item or document.
BrowseDirectories Enumerate files and folders in a Web site using Microsoft Office SharePoint Designer 2007 and WebDAV interfaces.
BrowseUserInfo View information about users of the Web site.
CancelCheckout Discard or check in a document which is checked out to another user.
CreateAlerts Create e-mail alerts.
CreateGroups Create a group of users that can be used anywhere within the site collection.
CreateSSCSite Create a Web site using Self-Service Site Creation.
DeleteListItems Delete items from a list, documents from a document library, and Web discussion comments in documents.
DeleteVersions Delete past versions of a list item or document.
EditListItems Edit items in lists, edit documents in document libraries, edit Web discussion comments in documents, and customize Web Part Pages in document libraries.
EditMyUserInfo Allows a user to change his or her user information, such as adding a picture.
EmptyMask Has no permissions on the Web site. Not available through the user interface.
EnumeratePermissions Enumerate permissions on the Web site, list, folder, document, or list item.
FullMask Has all permissions on the Web site. Not available through the user interface.
ManageAlerts Manage alerts for all users of the Web site.
ManageLists Create and delete lists, add or remove columns in a list, and add or remove public views of a list.
ManagePermissions Create and change permission levels on the Web site and assign permissions to users and groups.
ManagePersonalViews Create, change, and delete personal views of lists.
ManageSubwebs Create subsites such as team sites, Meeting Workspace sites, and Document Workspace sites.
ManageWeb Grant the ability to perform all administration tasks for the Web site as well as manage content. Activate, deactivate, or edit properties of Web site scoped Features through the object model or through the user interface (UI). When granted on the root Web site of a site collection, activate, deactivate, or edit properties of site collection scoped Features through the object model. To browse to the Site Collection Features page and activate or deactivate site collection scoped Features through the UI, you must be a site collection administrator.
Open Allow users to open a Web site, list, or folder to access items inside that container.
OpenItems View the source of documents with server-side file handlers.
UpdatePersonalWebParts Update Web Parts to display personalized information.
UseClientIntegration Use features that launch client applications; otherwise, users must work on documents locally and upload changes.
UseRemoteAPIs Use SOAP, WebDAV, or Microsoft Office SharePoint Designer 2007 interfaces to access the Web site.
ViewFormPages View forms, views, and application pages, and enumerate lists.
ViewListItems View items in lists, documents in document libraries, and view Web discussion comments.
ViewPages View pages in a Web site.
ViewUsageData View reports on Web site usage.
ViewVersions View past versions of a list item or document.

Technorati Tags: , , ,

So I have been working on setting up a Linux box with PHP5 and mysql mostly just to fart around with but also because I like learning how to do these things. I was having a hell of a time getting PHP and mysql to install properly on my distro - ubuntu 8

I originally installed PHP using apt-get and then installed mysql doing the same but was having issues getting them to work...no big shocker considering I am still fairly new to Linux. Eventually I did the following to get everything working, well so far anyway :)

Here it is:

1. sudo tasksel install lamp-server - this installs the entire LAMP stack (Linux-Apache-MySQL-PHP) and does most of the work for you (i like this)

2. sudo apt-get install phpmyadmin - configure it for apache2 (installed above) this helped me get rid of the Fatal error: Call to undefined function: mysql_connect() I was getting...basically php was not configured to speak to mysql

3. I really cheated on this one because I was getting the following error Lost connection to MySQL server at ‘reading initial communication packet’, system error: 111 like any good linux noob I decided to google that up and came up with an article located here that worked like a charm. Here are the steps:

* sudo gedit /etc/mysql/my.conf - comment the line corresponding to ‘bind-address’
* sudo gedit config.inc.php - in the /etc/phpmyadmin folder
* add or edit a line $cfg['Servers'][$i]['host'] = ‘localhost’;
* restart mysql using sudo /etc/init.d/mysql restart

Anyway...HTH

Technorati Tags: , , , ,

If you are like me and have experienced this amazing error...here is how you can pinpoint the problem....change the SafeMode tag in the web.config file to enable the CallStack attribute

<safemode callstack="true" maxcontrols="200">

Then turn the customErrors mode to OFF. This should help you determine the problem.

Technorati Tags: , , ,

From November 2008:

Whew...its been a long week and its only Thursday. This years conference was much the same as last years with the exception of being held in various portions of the Mandalay Bay convention center as opposed to on one floor. This made for lots and lots and lots and lots of walking. But I'm still young (yes i am) so it makes for good excercise to walk off all the food they shovel in your mouth.

Most of the sessions I attended were really good with the exception of a couple. I wouldn't blame the speakers because these problems were mostly due to technical issues like the computers not working, the projectors broken or feedback in the presenters microphone sort of thing. All in all there were some great things presented this week.

Some of the sessions that really stuck out were:

Kimberly Tripp - Index Internals and Usage
This was a great session that talked about thins like SQL Server Statistics, Query Optimization, Types of indexes, diminishing returns on performance, etc. Of all the session I think this one stood out the most and because it is probably the most relevant for me right now being one of the "SQL Server DBA" for my company (Christie Digital). I say it that way because its a committee based DBA :)

Rick Strahl - Using WCF for JSON and REST Services with ASP.Net

Great session....last one of the conference for me so it really sticks out but essentially this covers the next gen replacement for ASMX or first gen webservices in the .NET Framework.

John Papa - Practical Strategies with the Entity Framework

For me this was an introduction to the Entity Framework that was released in VS 2008 SP1. John did a great job of quickly introducing the technology and getting on to the meat and potatoes of what we were there to discuss. There was a good discussion on how to use the IDE to build the data mappings and what happens after you make changes to the backend server, which coinceidently can be any data source...not just SQL as Linq to SQL supports.

Things I would change...(and only because its my blog and I can say whatever I want!!!)

...the time between sessions was ridiculous...one hour or in some cases and hour and a half is just way too long. They could have added an extra session or two to the day. I realize they want you in the expo hall but they could have extended the day to facilitate that or leave it open all day and then some people may skip a couple of sessions here and there to go and see what the vendors are offering. this was my gripe last year and its my gripe this year. Its probably going to be the thing that keeps me from going to this in the future.

...provide video or podcasts of the sessions so we can take in the whole conference...even the sessions we didn't get to go to. I see there point about this being intellectual property and the speakers are consultants and this is their livelyhood but I mean if they are willing to teach this at a conference...and we pay to see it...shouldn't we be entitled to review this information after the fact? Maybe they will supply it on their site (i heard they were recording the sessions this year).

...ease up on the food. Damn, there was too much...I ate too much...I felt stuffed the whole time...I guess this is really my fault! Okay dont change that :)

Technorati Tags: , , , , , ,

I have never in my life dealt with or had the "pleasure" of using a tool quite like Sharepoint Designer. First off I am a developer...so can they roll this thing into Visual Studio already? maybe then it will behave like my usual IDE...you know intellisense, fade away tool boxes and solution explorer. (Some of these issues are sharepoint itself but...this app is where i figured it out so i am adding it here)
So what makes me hate it?

...hmm did you know that you have to leave the ListFormWebPart on all the edit, insert and display forms for a list even if you want to customize them? Seems kind of odd to me and quite frankly where is this documented...shouldn't SPD at least say something to that effect...or dammit MS add it as a comment on the page somewhere.

...how about leaving my HTML code alone when i am done formatting it please!!!! Its like I am working in VS2002 again...no thanks

...the CustomListForm web part does not give you the ability to attach files...even though its right there on the toolbar it gives you the nice "You cannot attach a file because the form was customized". Thanks captain obvious...I think this is one of those sick jokes where every time you click on it a counter in Redmond increments by one and some sick developer is there laughing his ass off...heres to you buddy! Kudos to Marc Davis for his workaround posted here

...isn't it funny how the css file core.css is always the last css added to the list. Sure you can bypass it with the Alternate stylesheeet and/or using a hard coded link tag...but that just seems dumb to me.

...can I have an easier way to develop and debug code in sharepoint...sure I know I can build, deploy to the GAC and attach....but its a bit of a pain in the ass.

...Customized file and uncustomized files. Yes i get the gist of it and i believe this is a good thing....scenario - I have made numerous edits to a file - I choose to revert to the site definition - I don't get my original file back...I get some hybrid bastardized file that is completely useless to me...ummmm....again...not funny.

- I had a problem with one of my lists (pertaining to the ListFormWebPart not being there) and I was looking around on the internet...here is what I found this article here you can read it if you want but it basically says hey...just delete your list and recreate it....HA HA HA I love those simple "fixes".

...theres been other things but I cant remember them right now....too tired.

So these are my ramblings...I am kinda stuck with SharePoint now but if they could fix some of these very-time consuming problems it would make mine and judging from the problems people are having online a lot of other peoples jobs a lot easier. I mean isn't that what Microsoft has been promising all this time...

I'll stop now...happy SharePointing.

Technorati Tags: , , ,