Custom module table is not created

Topics: Troubleshooting, Writing modules
Oct 16, 2012 at 1:21 PM
Edited Oct 24, 2012 at 6:15 AM

Hi, excuse my ignorance as this is my first Module and I am new to Orchard :), I also did some research and  I came up with my own code. I am trying to do a very basic Module that will display a form to the front-end user and once the user fill the form data will be stored in table. When I tested it the form is displayed properly and when I submit the form I get the message that is ok but - table Subscriber is not created in db.

********************************************************************************
[SubscriberViewModel.cs]
********************************************************************************

using System.ComponentModel.DataAnnotations;

namespace Subscriptions.ViewModels
{
    public class SubscriberViewModel {
        [Required]
        public string Name { get; set; }

        [Required]
        public string Email { get; set; }

        public string Newsletter { get; set; }
    }
}

********************************************************************************
[Subscriber.cs]
********************************************************************************

using Orchard.ContentManagement.Records;

namespace Subscriptions.Models
{
    public class Subscriber : ContentPartRecord {
        public virtual string Name { get; set; }
        public virtual string Email { get; set; }
        public virtual string Newsletter { get; set; }
    }
}

********************************************************************************
[SubscribersAreaController.cs]
********************************************************************************

using System.Web.Mvc;
using Subscriptions.Models;
using Subscriptions.ViewModels;
using Orchard.Themes;

namespace Subscriptions.Controllers
{
    [Themed]
    public class SubscribersAreaController : Controller
    {
        public ActionResult Subscribe()
        {
            return View("Subscribe");
        }

        [HttpPost]
        public ActionResult Subscribe(SubscriberViewModel subscriber) {
            //FormCollection formCollection
            var viewModel = new Subscriber
                             {
                                 Name = subscriber.Name,
                                 Email = subscriber.Email,
                                 Newsletter = subscriber.Newsletter
                             };

            if (!TryUpdateModel(viewModel))
            {
                ViewData["ErrorMessage"] = "Subscriber failed to be created!"; 
            } 
            else {
                ViewData["ErrorMessage"] = "Subscriber created successfully!";
            }
    
            return View("Subscribe");
        }
    }
}

********************************************************************************
[Subscribe.cshtml]
********************************************************************************

@model Subscriptions.ViewModels.SubscriberViewModel

<h1>Subscribe to News</h1>

@using (Html.BeginFormAntiForgeryPost()) {   
    @Html.ValidationSummary(true)
    <table >
        <tr>          
            <td colspan="2">
                <input type="text" name="Newsletter" value="company_news"/>
                <span style="font-weight: bold">Company News</span>
            </td>
        </tr>
        <tr>
            <td>Your name:</td>
            <td>
                @Html.EditorFor(model => Model.Name)
                @Html.ValidationMessageFor(model => Model.Name)
            </td>
        </tr>
        <tr>
            <td>Your Email:</td>
            <td>
                @Html.EditorFor(model => Model.Email)
                @Html.ValidationMessageFor(model => Model.Email)
            </td>
        </tr>
        <tr>          
            <td colspan="2" style="text-align: right">
                <input type="submit" name="submit" value="Subscribe"/>
            </td>
        </tr>
    </table>
}

********************************************************************************
[Migrations.cs]
********************************************************************************

using System.Data;
using Orchard.Data.Migration;

namespace Subscriptions {
    public class Migrations : DataMigrationImpl {

        public int Create() {

            // Creating table ProductPartRecord
            SchemaBuilder.CreateTable("Subscriber", table => table
                .ContentPartRecord()
                .Column("Name", DbType.String)
                .Column("Email", DbType.Single)
                .Column("Newsletter", DbType.Single)
            );

            return 1;
        }
    }
}

********************************************************************************
[SubscriberHandler.cs]
********************************************************************************

using Subscriptions.Models;
using Orchard.ContentManagement.Handlers;
using Orchard.Data;

namespace Subscriptions.Handlers
{
    public class SubscriberHandler : ContentHandler
    {
        public SubscriberHandler(IRepository<Subscriber> repository)
        {
            Filters.Add(StorageFilter.For(repository));
        }
    }

}

********************************************************************************
[Routes.cs]
********************************************************************************

using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Routing;
using Orchard.Mvc.Routes;

namespace Subscriptions {
    public class Routes : IRouteProvider {
        public void GetRoutes(ICollection<RouteDescriptor> routes) {
            foreach (var routeDescriptor in GetRoutes())
                routes.Add(routeDescriptor);
        }

        public IEnumerable<RouteDescriptor> GetRoutes() {
            return new[] {
                new RouteDescriptor {
                    Priority = 5,
                    Route = new Route(
                        "Subscribe",
                        new RouteValueDictionary {
                            {"area", "Subscriptions"},
                            {"controller", "SubscribersArea"},
                            {"action", "Subscribe"}
                        },
                        new RouteValueDictionary(),
                        new RouteValueDictionary {
                            {"area", "Subscriptions"}
                        },
                        new MvcRouteHandler())
                }
            };
        }
    }
}

Coordinator
Oct 16, 2012 at 4:22 PM

The table is not created? You don't mean the row? Did you verify that your migration was actually running?

Oct 16, 2012 at 4:41 PM

I checked and table has not been created, so Migrations.cs has not run. What do I need to do to make it run?

Coordinator
Oct 16, 2012 at 4:49 PM

If there isn't anything suspicious in app_data\logs, and if you can (if that doesn't contain data that you need to keep), the simplest is to delete app_data, restart the server, put a breakpoint in your migration, enable the feature and figure out what's failing. If you can't delete app_data, you can go into the database and roll back the migration number directly in the relevant table and then follow the same procedure. But my guess is that you already have the necessary info in logs.

Oct 16, 2012 at 5:07 PM

Not sure if this is your case, but if you have a module with more than one feature, I found out it's best to have more than one migration class and apply to it the attribute OrchardFeature. e.g:

[OrchardFeature("MyOrchardModule.FeatureName")]
public class FeatureNameMigrations : DataMigrationImpl
{
    ...
}

Oct 23, 2012 at 11:38 AM
Edited Oct 23, 2012 at 11:53 AM

// (removed)

Developer
Oct 23, 2012 at 3:58 PM
Edited Oct 27, 2012 at 10:42 PM

Do you have a Module.txt file with the feature in it? And can you see that feature in the Features list?

Also, you seem to have two namespace conventions

Is the folder your module in the same as the name of the Project? i.e. if the project is 'LqdMarkets.Subscriptions.csproj' is your module folder 'LqdMarkets.Subscriptions'

Some things to check off the top of my head.

Nick

Oct 24, 2012 at 6:21 AM

Oh my mistake, the issue was the namespace. thank you