tags:

views:

26

answers:

3

My url should look like this: localhost/Products/Details/1/asus-intel-core-2-duo.

As you can see, the slug is generated from existing fields: brand-processorBrand-ProcessorModel. My title will also look like this, without the dashes. I generate this slug in my Service layer. I have 2 questions:

  1. Where and how should I store this format so I can change it once and everything else changes? ie. {brand} {processorBrand} {ProcessorModel}

  2. How do I generate the string? I only know about: string.Format("{0} {1} {2}", Model.Brand, Model.ProcessorBrand, Model.ProcessorModel). Which doesn't seem like it could work in the case of storing the format elsewhere.


If I am going about this wrong, I have another method in mind. But this requires me to loop over every product in the service layer and call a method on the product class which generates a title and slug. For eg.

public class Product
{
    public void GenerateStuff();
    //Other properties here...

    public string Title {get; set;};
    public string Slug {get; set;};
}

I know there is a better way to do this, every method I have seems very messy.

A: 

No matter how you do it, it looks like it will involve reflection, which seems like it would be a performance bottleneck. Having to loop through each property on the model seems like a lot of work for something that will be done numerous times.

IMO, it is a big enough change, and one that should not be made too often, that I would not store this anywhere. I would have the code to generate this string in one place, and when it needs to change, change it, and re-build the app.

Martin
A: 

Generating the slug itself doesn't belong in the Product or any other domain class. That's tied up with issues relating to how to format the slug, safe URL encoding, allowable-characters and such like. [BTW, string.format alone clearly isn't enough to create a proper URL-encoded string from your domain object properties].

So, keep the slug generation method in your service layer but maybe change it to accept an enumeration of string values.

Your domain object classes could return the string values with a method like this

public IEnumerable<string> SlugValues {get {return new []{this.Brand, this.ProcessorModel} };

An alternative would be to add attribute to your class or to the properties within it to denote which ones to use in slug-generation. Now you can find which ones to use by using reflection.

Hightechrider
A: 

We also have a requirement for unique URL slugs.

We do it on the database-side, using triggers (yes i know triggers are evil, bare with me)

Our Product entities have a property called UniqueUri, which is nullable, and gets inserted with NULL when a product is first created.

We then have a INSERT/UPDATE Trigger on the Products table to generate the unique URI.

The trigger basically looks at all the existing Products, and (with some logic/magic), updates the unique URI.

This (IMO) is where this logic belongs, and is a good case for a trigger. When you add a Product via the UI, the UI should not have to wait for the URI to be created. This way, it's done asynchronously (in a sense, at least from the view of the request).

Plus looping over all the Products with SQL is much faster than doing it in .NET.

RPM1984