简体   繁体   中英

ASP.NET MVC Alternatively Rendering EditorFor Based on User Role

I have a base viewmodel class that includes a current user property, and I need MVC to render a textbox or label according to the user's admin status.

Currently, I'm doing this way, But the code has to repeat itself a lot.

            @if (Model.CurrentUser.Admin)
            {
                @Html.EditorFor(m => m.Order.CustomerDiscount);
            }
            else
            {
                @Html.DisplayFor(m => m.Order.CustomerDiscount);
            }

Is it possible to create a custom editor extension?

            @Html.PrivilegedEditorFor(m=>m.Order.CustomerDiscount);

Edit:

Thanks to @Fals. A slightly different solution is here:

using System.Web.Mvc.Html;
public static class HtmlHelperExtensions
{
    public static MvcHtmlString PrivilegedEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool isAdmin)
    {
        if (isAdmin)
        {
            return htmlHelper.EditorFor(expression);
        } else {
            return htmlHelper.DisplayFor(expression);
        }
    }

}

You can create a custom HTML Helper for this, for exemple:

1) Add new Class to your project, this will contain the helper. Just make sure that the used model contains the CurrentUser.Admin .

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Helpers;
using System.Web.Mvc.Html;
using System.Linq.Expressions;

namespace MyAppName.Helpers
{
    public static class HtmlPrivilegedHelper
    {
        public static MvcHtmlString PrivilegedEditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
        {
            // You can access the Model passed to the strongly typed view this way
            if (html.ViewData.Model.CurrentUser.Admin)
            {
                return html.EditorFor(expression);
            }

            return html.DisplayFor(expression);
        }
    }
}

2) Add the namespace to the Web.config in the Views folder, then you don't have to include the namespace every time you want to use it:

<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Optimization"/>
    <add namespace="System.Web.Routing" />
    <add namespace="MyAppName.Helpers" /> //Here the helper reference
  </namespaces>
</pages>
</system.web.webPages.razor>

Hopes this help you!

Try to use extension methods. It is possible to create static class (cannot be non-static or nested) with methods you need, which one parameter is Html and it is marked using 'this' keyword. More information you can find here: http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx

You can create a HTML helper method. One way of doing this is by creating a new class with a static method that returns a string of html for rendering. Or you can extend the existing html helper class.

There is a great asp.net walkthrough on it here: http://www.asp.net/mvc/tutorials/older-versions/views/creating-custom-html-helpers-cs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM