2

I have the following abstract class:

public abstract class TemplateBase
{
    public abstract string TemplateName { get; }
    public string RuntimeTypeName { get { return GetType().FullName; } }
    public abstract List<AreaContainer> TemplateAreas { get; }
}

then these 2 inherited classes:

public class SingleColumnTemplate : TemplateBase
{
    public override string TemplateName { get { return "Single column"; } }

    public AreaContainer CenterColumn { get; private set; }

    public SingleColumnTemplate()
    {
        this.CenterColumn = new AreaContainer("Middle");
    }

    private List<AreaContainer> templateAreas;

    public override List<AreaContainer> TemplateAreas
    {
        get
        {
            if (this.templateAreas == null)
            {
                this.templateAreas = new List<AreaContainer>() { this.CenterColumn };
            }

            return this.templateAreas;
        }
    }
}

and

public class TwoColumnTemplate : TemplateBase
{
    public override string TemplateName { get { return "Two column"; } }
    public AreaContainer LeftColumn { get; private set; }
    public AreaContainer RightColumn { get; private set; }

    public TwoColumnTemplate()
    {
        LeftColumn = new AreaContainer("Left");
        RightColumn = new AreaContainer("Right");
    }

    private List<AreaContainer> templateAreas;

    public override List<AreaContainer> TemplateAreas
    {
        get
        {
            if (this.templateAreas == null)
            {
                this.templateAreas = new List<AreaContainer>() { this.LeftColumn, this.RightColumn };
            }
            return this.templateAreas;
        }
    }
}

I also have this class that is my model for editing:

public class ContentPage
{
    public virtual int ContentPageId { get; set; }

    public virtual string Title { get; set; }

    public TemplateBase Template { get; set; }
}

Question:

for my ActionResults I have the following:

[HttpGet]
public ActionResult Edit()
{
    var row = new ContentPage();
    var template = new TwoColumnTemplate();        

    // Areas
    HtmlArea html_left = new HtmlArea();
    html_left.HtmlContent = "left area html content";

    HtmlArea html_right = new HtmlArea();
    html_right.HtmlContent = "right area html content";

    template.LeftColumn.Areas.Add(html_left);
    template.RightColumn.Areas.Add(html_right);

    row.Template = template;
    return View(row);
}

[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(ContentPage row)
{
    // Here i could loop through List -TemplateAreas and save each template Area to Db. I guess that would work

    return this.View(row);
}

Question:

For HttpGet- how would I load row Template from the database? since it could be SingleColumnClass or TwoColumnClass.

how would my ViewModel look like to solve this?

thanks

3 Answers 3

2

You can write your own Model Binder that is responsible for binding TemplateBase. You will still need to have a way of knowing (in the model binder) which type you will be using a runtime, but you can always delegate that to a factory or service locator of some sort. I did a quick google search and here is a blog post I found that gives you some information for making a model binder for a similar scenario:

http://weblogs.asp.net/bhaskarghosh/archive/2009/07/08/7143564.aspx

EDIT: The blog leaves out how you tell MVC about your model binder. When the application starts, you can add your model binder to System.Web.Mvc.ModelBinders.Binders

HTH

Sign up to request clarification or add additional context in comments.

Comments

1

You need to know the template type in you controller, so you can pass a parameter from the view to the controller, indicating the type (SingleColumn or TwoColumn). You could do this witn a Enum:

public enum TemplateType
{
   SingleColumn,
   TwoColumn
}

[HttpGet]
public ActionResult Edit(TemplateType templateType)
{
    var row = new ContentPage();
    TemplateBase template; 

    if (templateType == TemplateType.SingleColumn)
    {
        template = new SingleColumnTemplate();
    }
    else
    {
        template = new TwoColumnTemplate();
    }

    ...

    return View(row);
}

When you create the action link from your view you can specify:

<%= Html.ActionLink("Edit",
                    "Edit",
                    "YouController",
                    new 
                    { 
                        // singlecolumn or twocolumn
                        // depending on your concrete view
                        TemplateType = TemplateType.xxx 
                    },
                    null); 

10 Comments

That's what i'm trying to avoid..the if else statements. I know what TemplateBase type is by:public string RuntimeTypeName { get { return GetType().FullName; } } what would my db object look like? and how would it load into ContentPage without having if/else stuff..maybe using GetType()? I found this:yoda.arachsys.com/csharp/plugin.html but i'm not sure how to implement it.
@Shane: Sorry can you explain better?
Ok, i'm thinking that in my ActionResult for HTTPPost I would have the following: [HttpPost] [ValidateInput(false)] public ActionResult Edit(ContentPage row) { // I can get a list here ; foreach(var item in TemplateAreas) { // Save each area...}; Save 'row' return this.View(row); } the problem is HTTPGET..how would I load ContentPage abstract class? without doing the if/else stuff. thanks
@Shane: Please, could you update your post with the content of HttpPost?
HttpGet...meaning. ContentPage row = getfromrepository..; how would i load it from db into ContentPage?
|
0

I wonder if you could do something like this?

[HttpGet]
public ActionResult Edit(TemplateType templateType)
{
    var row = new ContentPage();
    TemplateBase template = (TemplateBase)Activator.CreateInstance(templateType);

    ...

    return View(row);
}

templateType would have to be the exact name of your inherited classes (you can ignore case)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.