Bonjour,

il y a quelques jours, j'ai posé une question concernant des tables génériques (cf. ici). Celles-ci fonctionnent bien comme il faut.

Ensuite, j'ai voulu pouvoir utiliser un template (DisplayFor())(Views/Shared/DisplayTemplates/xxx) afin de pouvoir créer des liens entre différentes pages sans me poser de questions.

Le compilateur de bronche pas à la compilation, mais lors du runtime, j'obtiens une exception :

Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

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: System.InvalidOperationException: Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
Stack trace :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[InvalidOperationException: Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.]
   System.Web.Mvc.ModelMetadata.FromLambdaExpression(Expression`1 expression, ViewDataDictionary`1 viewData) +561125
   System.Web.Mvc.Html.TemplateHelpers.TemplateFor(HtmlHelper`1 html, Expression`1 expression, String templateName, String htmlFieldName, DataBoundControlMode mode, Object additionalViewData, TemplateHelperDelegate templateHelper) +67
   System.Web.Mvc.Html.TemplateHelpers.TemplateFor(HtmlHelper`1 html, Expression`1 expression, String templateName, String htmlFieldName, DataBoundControlMode mode, Object additionalViewData) +100
   System.Web.Mvc.Html.DisplayExtensions.DisplayFor(HtmlHelper`1 html, Expression`1 expression) +56
   EORTC.TOOLS.EORTCPaginationHelper.EORTCTableContent(HtmlHelper`1 helper, EORTCPaginatedTable`1 table, Expression`1[] propertySelector) in C:\Projects\_Prisma\EORTC.TOOLS\Tables\EORTCPaginationHelper.cs:104
   EORTC.TOOLS.EORTCPaginationHelper.EORTCTable(HtmlHelper`1 helper, String action, String controller, EORTCPaginatedTable`1 table, Boolean menu, String method, String projectSpecificExportFunctionResult, Expression`1[] propertySelector) in C:\Projects\_Prisma\EORTC.TOOLS\Tables\EORTCPaginationHelper.cs:202
   ASP._Page_Views_Person__Index_cshtml.Execute() in c:\Projects\_Prisma\Prisma.Web\Views\Person\_Index.cshtml:4
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +272
   System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +81
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +187
   System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +220
   System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +115
   System.Web.Mvc.HtmlHelper.RenderPartialInternal(String partialViewName, ViewDataDictionary viewData, Object model, TextWriter writer, ViewEngineCollection viewEngineCollection) +279
   System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(HtmlHelper htmlHelper, String partialViewName, Object model) +72
   ASP._Page_Views_Person_Index_cshtml.Execute() in c:\Projects\_Prisma\Prisma.Web\Views\Person\Index.cshtml:10
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +272
   System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +81
   System.Web.WebPages.StartPage.RunPage() +58
   System.Web.WebPages.StartPage.ExecutePageHierarchy() +94
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +173
   System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +220
   System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +115
   System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +303
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
   System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +23
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +260
   System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b() +19
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +177
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
   System.Web.Mvc.Controller.ExecuteCore() +116
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8963149
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

Voici le code faisant appel au DisplayFor
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
private static string TableContent<T>(this HtmlHelper<PaginatedTable<T>> helper, PaginatedTable<T> table, params Expression<Func<T, object>>[] propertySelector) where T : IAuditedObject
        {
            StringBuilder sb = new StringBuilder();
            ICollection<string> properties = new List<string>();
            sb.AppendLine("<div class=\"EORTCTable-body\">");
            sb.AppendLine("<table>");
            sb.AppendLine("<thead>");
            sb.AppendLine("<tr>");
            Type type = typeof(T);
            foreach (var selector in propertySelector)
            {
                var expr = selector.Body;
                if (expr.NodeType == ExpressionType.Convert && expr.Type == typeof(object))
                    expr = ((UnaryExpression)expr).Operand;
                var memberExpr = expr as MemberExpression;
                if (memberExpr == null)
                    throw new ArgumentException("The body must be a member access expression");
                string propertyName = memberExpr.Member.Name;
                sb.AppendLine("<th>" + propertyName + "</th>");
                properties.Add(propertyName);
            }
            sb.AppendLine("</tr>");
            sb.AppendLine("</thead>");
            sb.AppendLine("<tbody>");
            foreach (var element in table.ShowedItems)
            {
                sb.AppendLine("<tr>");
                foreach (var prop in properties)
                {
                    switch (type.GetProperty(prop).PropertyType.ToString())
                    {
                        case "System.Nullable`1[System.DateTime]": sb.AppendLine("<td>" + helper.DisplayFor(elem => type.GetProperty(prop)) + "</td>"); break;
                        default: sb.AppendLine("<td>" + helper.DisplayFor(elem => type.GetProperty(prop)) + "</td>"); break;
                    }
                }
                sb.AppendLine("</tr>");
            }
            sb.AppendLine("</tbody>");
            sb.AppendLine("</table>");
            sb.AppendLine("</div>");
            return sb.ToString();
        }
Ma question est la suivante :
Est-il possible d'utiliser les templates tout en utilisant la reflection ?
Si oui, comment ?
Sinon, existe-t-il un système plus ou moins identique tout en utilisant la reflection ?

Merci !


EDIT :
Résolu !

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
sb.AppendLine("<td>" + helper.DisplayFor(elem => type.GetProperty(prop)) + "</td>");
Devient :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 
object value = (type.GetProperty(prop).GetValue(element, null));
                        sb.AppendLine(String.Format("<td>{0}</td>", helper.DisplayFor(elem => value)));