Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I've been developing a list with custom forms using Sharepoint 2010 using this excellent article: http://blog.karstein-consulting.com/2010/12/29/walkthrough-create-custom-sharepoint-2010-list-form-for-deployment-in-a-visual-studio-2010-project/; the author's post is easy to follow and rather clear, but I eventually hit a snag when I started complicating things. I'm seeing the light at the end of the tunnel, which is a good point to stop and post about it in order to get some feedback from the community, and possibly contribute to the general pool of knowledge. Any contributions are welcome!

A bit of background:

In a nutshell, the project I've been working on is a document management system for contracts. A contract can have several amendments. Certain types of contracts (known as Master Service Agreements), can also have work orders. Work orders can also be amended.

All of these contracts have a contract reference, which is a composite set of three numbers: a contract ref (int), an amendment ref (int), and a work order ref (int).

Here is an example of how referencing works: my initial Master Service Agreement with the ACME company would be referenced as 1.0.0. If, for instance, I've changed the terms of my agreement, this amended contract would be 1.0.1.

Under this MSA, I have a work order for shipping a crate of rocket shoes to my office by month end. This work order would be referenced as 1.1.0. If, in fact, I were to amend that work order to include two crates, the work order amendment would be 1.1.1. And so forth.

The design:

I have a single list to store my contracts, work orders and amendments. This list hosts four content types: Contract, Contract Amendment, Work Order, Work Order Amendment. Creation of an amendment or work order is contextual: you can't have an amendment without first having a contract. To ensure this, I have custom actions associated to the Contract content type, which point the user to the appropriate form to fill out the new amendment / work order relative to the contract. I set up my content types as hidden in the list to force the user to "come from" an existing contract.

The problem:

Here's where things get messy. Using this approach, I can create items that are related to my contracts - but these items, when saved, are saved as Contracts, and not as Amendments or Work Orders. This is -- annoying, to say the least.

The solution?

My solution uses an Item Event Receiver (ItemAdding) to set the content type as it is being added to the list. When an item is being added, I check for the presence of a hidden field that I have set. I could, for that matter, check the RawUrl of the request, which I obtain by grabbing the current HttpContext object in my Event Receiver's constructor. I went for the hidden field approach so that I could have multiple forms per content type without it affecting my Event Receiver.

Based on my hidden field's value, I set properties.AfterProperties["ContentType"] to be the appropriate content type.

Sample code:

In the .aspx form:

    <input type="hidden" id="ContractContentType" name="ContractContentType" value="Amendment"/>

In the event receiver:

    private readonly HttpContext _httpContext;

    public DetermineContentType()
    {
        _httpContext = HttpContext.Current;
    }

    /// <summary>
    /// An item is being added.
    /// </summary>
    public override void ItemAdding(SPItemEventProperties properties)
    {
        string contentType = _httpContext.Request.Params["ContractContentType"];

        switch (contentType)
        {
            case "Amendment":
                properties.AfterProperties["ContentType"] = "Contract Amendment";
                break;
        }
        base.ItemAdding(properties);
    }

In conclusion...

Would welcome your thoughts on this - à priori, this does not require inline code to be enabled via the PageParserPath directive in web.config. It's easy to set up, reasonably easy to maintain. Quite sure this wouldn't work if you're allowing Datasheet mode, but I suppose that it could be adapted (for instance, rather than look at a hidden field's value, choice of content type could be determined by a list's property).

share|improve this question
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.