OrchardCMS / OrchardDoc

Documentation for Orchard 1.x (not Orchard Core, for that see https://docs.orchardcore.net/).
http://docs.orchardproject.net
142 stars 241 forks source link

1-n documentation causes an exception to be thrown - review needed #211

Closed rtpHarry closed 8 years ago

rtpHarry commented 8 years ago

http://docs.orchardproject.net/Documentation/Creating-1-n-and-n-n-relations

Exception thrown

I accidentally introduced an error into the docs when I updated them all to use the infoset last year and it's gone largely unnoticed.

I was just running through the tutorial today, found it didn't work and actually found some discussion on CodePlex from back in May.

The error I introduced into the docs was when I tried to put an unsupported type into the infoset with this code:

public StateRecord State
{
    get { return Retrieve(r => r.State); }
    set { Store(r => r.State, value); }
}

It causes this exception:

System.NotSupportedException: Could not handle type StateRecord

The solution is to encode and decode it as you pass it to the InfoSet.

I've updated it to this:

// in the AddressPart class
public StateRecord State
{
    get
    {
        var rawStateRecord = Retrieve<string>("StateRecord");
        return StateRecord.DeserializeStateRecord(rawStateRecord);
    }
    set
    {
        var serializedStateRecord = StateRecord.SerializeStateRecord(value);
        Store("StateRecord", serializedStateRecord);
    }
}

// and in the StateRecord class
public static StateRecord DeserializeStateRecord(string rawStateRecord) {
    if (rawStateRecord == null) {
        return new StateRecord();
    }

    var stateRecordArray = rawStateRecord.Split(new[] { ',' });

    return new StateRecord() {
        Id = String.IsNullOrEmpty(stateRecordArray[0]) ? 0 : Int32.Parse(stateRecordArray[0]),
        Code = stateRecordArray[1],
        Name = stateRecordArray[2]
    };
}

public static string SerializeStateRecord(StateRecord stateRecord) {
    if(stateRecord == null) {
        return "";
    }

    return String.Join(",", stateRecord.Id, stateRecord.Code, stateRecord.Name);
}

Before I make a PR does anyone have any advice on a better way to do it?

It seems brittle because its encoding strings so they could potentially contain the join delimiter ,. I'd prefer to use IJsonConverter but seeing as it's need in a static method I don't know how to get at it?