Creating my own widget doesn't work.

Topics: Customizing Orchard, Troubleshooting, Writing modules
Jun 16, 2011 at 3:37 PM

Hi,

 

I've tried many times to create my own little widget based on the tutorial named "Create content part" but without any success. I really don't know what's wrong and I keep having this error:

 

Compilation Error

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS1963: An expression tree may not contain a dynamic operation

Source Error:

 
Line 8:    </div>
Line 9:    <div class="editor-field">
Line 10:     @Html.TextBoxFor(model => model.fileName)
Line 11:     @Html.ValidationMessageFor(model => model.fileName)
Line 12:   </div>


Source File: c:\Users\jeansimon\Documents\My Web Sites\Orchard CMS1\Modules\FileFichier\Views\EditorTemplates\Parts\FichierPermission.cshtml Line: 10

 

Here's my code:

FichierPermission.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Records;
namespace FileFichier.Models
{
    public class FichierPermissionRecord : ContentPartRecord
    {
        public virtual string fileName { get; set; }
        public virtual string permission { get; set; }
    }


    public class FichierPermissionPart : ContentPart<FichierPermissionRecord>
    {
        [Required]
        public string fileName
        {
            get { return Record.fileName; }
            set { Record.fileName = value; }
        }

        [Required]
        public string permission
        {
            get { return Record.permission; }
            set { Record.permission = value; }
        }
    }

}

FichierPermissionDriver.cs

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using FileFichier.Models;
namespace FileFichier.Drivers
{
    public class FichierPermissionDriver : ContentPartDriver<FichierPermissionPart>
    {
        protected override DriverResult Display(
            FichierPermissionPart part, string displayType, dynamic shapeHelper)
        {

            return ContentShape("Parts_FichierPermission", () => shapeHelper.Parts_FichierPermission(
                FileName: part.fileName,
                Permission: part.permission));
        }

        //GET
        protected override DriverResult Editor(
            FichierPermissionPart part, dynamic shapeHelper)
        {

            return ContentShape("Parts_FichierPermission_Edit",
                () => shapeHelper.EditorTemplate(
                    TemplateName: "Parts/FichierPermission",
                    Model: part,
                    Prefix: Prefix));
        }
        //POST
        protected override DriverResult Editor(
            FichierPermissionPart part, IUpdateModel updater, dynamic shapeHelper)
        {

            updater.TryUpdateModel(part, Prefix, null, null);
            return Editor(part, shapeHelper);
        }

    }
}

FichierPermissionHandlers.cs

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FileFichier.Models;
using Orchard.ContentManagement.Handlers;
using Orchard.Data;

namespace FileFichier.Handlers
{
    public class FichierPermissionHandlers : ContentHandler
    {
        public FichierPermissionHandlers(IRepository<FichierPermissionRecord> repository)
        {
            Filters.Add(StorageFilter.For(repository));
        }

    }
}

 

Migration.cs

using FileFichier.Models;
using System;
using System.Collections.Generic;
using System.Data;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Builders;
using Orchard.Core.Contents.Extensions;
using Orchard.Data.Migration;
namespace FileFichier.DataMigrations
{
    public class Migrations : DataMigrationImpl {

        public int Create() {

            SchemaBuilder.CreateTable("FileFichier", table => table
                .ContentPartRecord()
                .Column("fileName", DbType.String)
                .Column("permission", DbType.String)
            );
            ContentDefinitionManager.AlterPartDefinition(
                typeof(FichierPermissionPart).Name, cfg => cfg.Attachable());
            return 1;
        }

        public int UpdateFrom1()
        {
            // Create a new widget content type with our map
            ContentDefinitionManager.AlterTypeDefinition("FichierPermissionWidget", cfg => cfg
                .WithPart("FichierPermissionPart")
                .WithPart("WidgetPart")
                .WithPart("CommonPart")
                .WithSetting("Stereotype", "Widget"));
            return 2;
        }
    }
}

.csprj File

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E4C88D1B-5E9F-42BB-966C-DB26DFA43B7F}</ProjectGuid>
    <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>FileFichier</RootNamespace>
    <AssemblyName>FileFichier</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <MvcBuildViews>false</MvcBuildViews>
    <FileUpgradeFlags>
    </FileUpgradeFlags>
    <OldToolsVersion>3.5</OldToolsVersion>
    <UpgradeBackupLocation />
    <TargetFrameworkProfile />
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.ComponentModel.DataAnnotations">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Web.DynamicData" />
    <Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
    </Reference>
    <Reference Include="System.Web" />
    <Reference Include="System.Web.Abstractions" />
    <Reference Include="System.Web.Routing" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Configuration" />
    <Reference Include="System.Xml.Linq" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="Web.config" />
    <Content Include="Views\Web.config" />
    <Content Include="Scripts\Web.config" />
    <Content Include="Styles\Web.config" />
    <Content Include="Views\EditorTemplates\Parts\FichierPermission.cshtml" />
    <Content Include="Views\Parts\FichierPermission.cshtml" />
    <Content Include="Properties\AssemblyInfo.cs" />
    <Content Include="Module.txt" />
    <Compile Include="Models\FichierPermission.cs" />
    <Compile Include="Drivers\FichierPermissionDriver.cs" />
    <Compile Include="Handlers\FichierPermissionHandlers.cs" />
    <Folder Include="Properties" />
    <Folder Include="Controllers" />
    <Folder Include="Views" />
    <Folder Include="Models" />
    <Folder Include="Scripts" />
    <Folder Include="Styles" />
  </ItemGroup>
  <ItemGroup>
    <Reference Include="Orchard.Core">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\bin\Orchard.Core.dll</HintPath>
    </Reference>
    <Reference Include="Orchard.Framework">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\bin\Orchard.Framework.dll</HintPath>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Migrations.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target> -->
  <Target Name="AfterBuild" DependsOnTargets="AfterBuildCompiler">
    <PropertyGroup>
      <AreasManifestDir>$(ProjectDir)\..\Manifests</AreasManifestDir>
    </PropertyGroup>
    <!-- If this is an area child project, uncomment the following line:
    <CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Child" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
    -->
    <!-- If this is an area parent project, uncomment the following lines:
    <CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Parent" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
    <CopyAreaManifests ManifestPath="$(AreasManifestDir)" CrossCopy="false" RenameViews="true" />
    -->
  </Target>
  <Target Name="AfterBuildCompiler" Condition="'$(MvcBuildViews)'=='true'">
    <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
  </Target>
  <ProjectExtensions>
    <VisualStudio>
      <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
        <WebProjectProperties>
          <UseIIS>False</UseIIS>
          <AutoAssignPort>True</AutoAssignPort>
          <DevelopmentServerPort>45979</DevelopmentServerPort>
          <DevelopmentServerVPath>/</DevelopmentServerVPath>
          <IISUrl>
          </IISUrl>
          <NTLMAuthentication>False</NTLMAuthentication>
          <UseCustomServer>True</UseCustomServer>
          <CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
          <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
        </WebProjectProperties>
      </FlavorProperties>
    </VisualStudio>
  </ProjectExtensions>
</Project>

FichierPermission.cshtml (editor file)

@Model FileFichier.Models.FilePermission;  
          
<fieldset>
  <legend>Map Fields</legend>
           
  <div class="editor-label">
    @Html.LabelFor(model => model.fileName)
  </div>
  <div class="editor-field">
    @Html.TextBoxFor(model => model.fileName)
    @Html.ValidationMessageFor(model => model.fileName)
  </div>

   <div class="editor-label">
    @Html.LabelFor(model => model.permission)
  </div>
  <div class="editor-field">
    @Html.TextBoxFor(model => model.permission)
    @Html.ValidationMessageFor(model => model.permission)
  </div>
</fieldset>

Jun 16, 2011 at 4:31 PM
Edited Jun 16, 2011 at 4:32 PM

- In your migration you're creating "FileFichier" table, not "FichierPermissionRecord" which is what your table should be.

- You're passing "FichierPermissionPart" into your view, but your view has the model "FileFichier.Models.FilePermission"

Jun 16, 2011 at 4:59 PM

For the view, which object should I keep ? FichierPermissionPart or FichierPermission ?

Jun 16, 2011 at 6:30 PM

You shouldn't have FichierPermission. You should have FichierPermissionPart and FichierPermissionPartRecord. Usually you'd pass FichierPermissionPart into the view, or you can create any ViewModel that you like if there's any extra data you want to pass in. So long as the model that the view declares is the same type as the one you're passing in!

Jun 16, 2011 at 6:48 PM

I have made the modifications you told me. I don't get the error I had but when I try to safe my widget (through Orchard's editor widget) I got this error:

null id in Orchard.Indexing.Models.IndexingTaskRecord entry (don't flush the Session after an exception occurs)

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: NHibernate.AssertionFailure: null id in Orchard.Indexing.Models.IndexingTaskRecord entry (don't flush the Session after an exception occurs)

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.


Stack Trace:

[AssertionFailure: null id in Orchard.Indexing.Models.IndexingTaskRecord entry (don't flush the Session after an exception occurs)]
   NHibernate.Event.Default.DefaultFlushEntityEventListener.CheckId(Object obj, IEntityPersister persister, Object id, EntityMode entityMode) +193
   NHibernate.Event.Default.DefaultFlushEntityEventListener.GetValues(Object entity, EntityEntry entry, EntityMode entityMode, Boolean mightBeDirty, ISessionImplementor session) +80
   NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent event) +96
   NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent event) +294
   NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event) +170
   NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) +44
   NHibernate.Impl.SessionImpl.Flush() +292
   NHibernate.Transaction.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment) +395

[TransactionAbortedException: The transaction has aborted.]
   System.Transactions.TransactionStateAborted.EndCommit(InternalTransaction tx) +11
   System.Transactions.CommittableTransaction.Commit() +239
   System.Transactions.TransactionScope.InternalDispose() +402
   System.Transactions.TransactionScope.Dispose() +1450
   Orchard.Data.TransactionManager.System.IDisposable.Dispose() in d:\TeamCity\Projects\Orchard-Default\src\Orchard\Data\TransactionManager.cs:47
   Autofac.Core.Disposer.Dispose(Boolean disposing) +79
   Autofac.Util.Disposable.Dispose() +46
   Autofac.Core.Lifetime.LifetimeScope.Dispose(Boolean disposing) +21
   Autofac.Util.Disposable.Dispose() +46
   Orchard.Environment.<>c__DisplayClass2.<.ctor>b__0() in d:\TeamCity\Projects\Orchard-Default\src\Orchard\Environment\WorkContextAccessor.cs:75
   Orchard.Environment.HttpContextScopeImplementation.System.IDisposable.Dispose() in d:\TeamCity\Projects\Orchard-Default\src\Orchard\Environment\WorkContextAccessor.cs:80
   Orchard.Mvc.Routes.HttpAsyncHandler.EndProcessRequest(IAsyncResult result) in d:\TeamCity\Projects\Orchard-Default\src\Orchard\Mvc\Routes\ShellRoute.cs:151
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8841105
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

 

 

Jun 16, 2011 at 6:56 PM

Sometimes that indicates an error going on elsewhere in the content management pipeline. Can you check your Logs folder to see if there are any other errors?

Jun 16, 2011 at 7:08 PM

Okay I got it working. I changed the database table name without reinstalling the module. Now it's working. I am testing it.

Jun 16, 2011 at 7:41 PM

Now the editor part works very well but I can't make it display the model's property in my website. Here's the code of my FichierPermission.cshtml in folder View/Parts:

 

FichierPermission.cshtml 

<p>Voici les permissions du fichier: </p>
@Model.permission

 

 

When I display the page. It doesn't display anything.

 

Coordinator
Jun 16, 2011 at 7:43 PM

What do you see under Model in Shape Tracing?

Jun 16, 2011 at 7:46 PM

I am not sure what you're talking about. Is it where I create the shape in my driver ?

Coordinator
Jun 16, 2011 at 8:11 PM

Oh boy :)

http://orchardproject.net/gallery/List/Modules/Orchard.Module.Orchard.DesignerTools

http://orchardproject.net/docs/Customizing-Orchard-using-Designer-Helper-Tools.ashx

Jun 16, 2011 at 8:19 PM

I have never used that tool before. Is it normal that when I install it, the following error is thrown:

 

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS1061: 'ClaySharp.IClayBehavior' does not contain a definition for 'GetMembers' and no extension method 'GetMembers' accepting a first argument of type 'ClaySharp.IClayBehavior' could be found (are you missing a using directive or an assembly reference?)

Source Error:

 
Line 169:        private void DumpShape(IShape shape) {
Line 170:            var members = new Dictionary<string, object>();
Line 171:            ((IClayBehaviorProvider) (dynamic) shape).Behavior.GetMembers(() => null, shape, members);
Line 172:
Line 173:            foreach (var key in members.Keys.Where(key => !key.StartsWith("_"))) {


Source File: c:\Users\jeansimon\Documents\My Web Sites\Orchard CMS1\Modules\Orchard.DesignerTools\Services\ObjectDumper.cs Line: 171

Coordinator
Jun 16, 2011 at 8:24 PM

No. You probably downloaded the 1.2 version on top of Orchard 1.1.

Jun 16, 2011 at 8:57 PM

Have you added an entry in Placement.info? That's the one thing I usually forget to do, your part won't appear without it.

Jun 16, 2011 at 8:57 PM

I am not able to upgrade my Orchard. Do I really need to install that module ? I only want the model's values to be displayed.

Coordinator
Jun 16, 2011 at 8:58 PM

Earlier versions are still available. You don't *need* to install that module, but you want to. Very much. You'll thank me ;)

Jun 16, 2011 at 9:14 PM

Okay If you say so I'll install it. How do I upgrade Orchard ? I enabled the Recipes module but nothing seems to have been upgraded.

Coordinator
Jun 16, 2011 at 9:28 PM

http://orchardproject.net/docs/Upgrading-a-site-to-a-new-version-of-Orchard.ashx

Jun 17, 2011 at 2:59 PM

Okay I've get my Orchard upgraded and the Designer Tool module installed.

Jun 17, 2011 at 3:03 PM

What information did you need again ? Because I still go the problem that no model's values are being displayed.

Jun 17, 2011 at 3:37 PM

Okay I found a way. I didn't know I had to use @Display. Thanks a lof for all your help.

Jun 17, 2011 at 3:42 PM

You shouldn't have to use @Display to show a widget - did you see my previous comment: "Have you added an entry in Placement.info? That's the one thing I usually forget to do, your part won't appear without it."

Jun 17, 2011 at 3:46 PM

My widget was being displayed but not his value. I do have a file placement.info:

<Placement>
    <Place Parts_FichierPermission="Content:10"/>
    <Place Parts_FichierPermission_Edit="Content:7.5"/>
</Placement>

Jun 17, 2011 at 3:49 PM

Ok; you didn't post your display template so I can't see what was happening. What were you passing into @Display? It should normally only be needed for displaying additional shapes.

Jun 17, 2011 at 4:53 PM

Here's the code of my template:

<p>Voici les permissions du fichier: </p>
@Display(Model.FileName)

@if (Model.FileName == "arrow.gif")
{
    <p>Le fichier est cool</p>
}

Jun 17, 2011 at 6:21 PM

This should just work:

@Model.FileName

Jun 17, 2011 at 6:41 PM

Haaarg. I think my mistake was that I didn't put the case on the property at first : @Model.fileName

Jun 17, 2011 at 7:40 PM

One good reason to always UpperCase your model properties, so from the view you'll always know what case they need to be :)