MVC4:将HTML作为参数传递给Ajax.ActionLink

时间:2014-12-12 21:33:27

标签: asp.net-mvc-4 model-view-controller

有没有办法传递链接文本的HTML元素?例如,我希望文本是这样的引导图标:

@Ajax.ActionLink(
    "<i class='icon-trash'></i>",
    "_DeleteEstimateItem",
    "Projects",
    new {
        @estimateId = estimate.Estimate.Id,
        @inventoryItemId = inventoryItem.Id,
        @projectId = Model.Project.Id
    },
    new AjaxOptions() {
        HttpMethod = "Get"
    },
    new {
        @class = "btn btn-danger"
    }
)

非常感谢您的进步!

1 个答案:

答案 0 :(得分:0)

未经测试(以及为相对较低的回报做了很多工作),但这里有......

为了得到以下内容:

@Ajax.ActionLink(
    @<i class='icon-trash'></i>,
    "_DeleteEstimateItem",
    "Projects",
    new {
        @estimateId = estimate.Estimate.Id,
        @inventoryItemId = inventoryItem.Id,
        @projectId = Model.Project.Id
    },
    new AjaxOptions() {
        HttpMethod = "Get"
    },
    new {
        @class = "btn btn-danger"
    }
)

(注意.ActionLink如何接受HTML)您需要为Ajax.ActionLink创建一个新的重载。不幸的是,还有很多其他的绑定是internal方法,所以我们必须从原生MVC中检查它们(因此,重新实现它们)。这有点可怕,因为现在你不再共享代码库了,所以买家要小心!

除此之外,新的重载接受Func<Object, HelperResult>(这就是我们如何传递剃刀HTML字符串)。代码如下,但未经测试。请务必将名称空间更改为您自己的名称空间,并在您的剃刀文件中添加@using引用,或添加对~/Views/web.config的引用。

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Web.Routing;
using System.Web.WebPages;

namespace MyWebsite.Web.Mvc.Helpers
{
    public static class AjaxExtensions
    {
        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper,
            Func<Object, HelperResult> linkHtml,
            String actionName,
            String controllerName,
            Object routeValues,
            AjaxOptions ajaxOptions,
            Object htmlAttributes
        )
        {
            RouteValueDictionary routeDict = new RouteValueDictionary(routeValues);
            RouteValueDictionary htmlDict = new RouteValueDictionary(htmlAttributes);
            return ajaxHelper.ActionLink(linkHtml, actionName, controllerName, routeValues, ajaxOptions, htmlAttributes);
        }
        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper,
            Func<Object, HelperResult> linkHtml,
            String actionName,
            String controllerName,
            RouteValueDictionary routeValues,
            AjaxOptions ajaxOptions,
            IDictionary<String, Object> htmlAttributes
        )
        {
            String targetUrl = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true);
            return MvcHtmlString.Create(GenerateLink(ajaxHelper, linkHtml(null).ToHtmlString(), targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
        }

        private static String GenerateLink(AjaxHelper ajaxHelper, String linkHtml, String targetUrl, AjaxOptions ajaxOptions, IDictionary<String, Object> htmlAttributes)
        {
            TagBuilder builder = new TagBuilder("a")
            {
                InnerHtml = linkHtml // all this just to be able to access this one property without HttpUtility.HtmlEncode
            };
            builder.MergeAttributes<String, Object>(htmlAttributes);
            builder.MergeAttribute("href", targetUrl);
            if (ajaxHelper.ViewContext.UnobtrusiveJavaScriptEnabled)
            {
                builder.MergeAttributes<String, Object>(ajaxOptions.ToUnobtrusiveHtmlAttributes());
            }
            else
            {
                builder.MergeAttribute("onclick", GenerateAjaxScript(ajaxOptions, "Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), {0});"));
            }
            return builder.ToString(TagRenderMode.Normal);
        }

        private static AjaxOptions GetAjaxOptions(AjaxOptions ajaxOptions)
        {
            return ajaxOptions != null ? ajaxOptions : new AjaxOptions();
        }

        #region Internal Method Emulation

        private static String EventStringIfSpecified(String propertyName, String handler)
        {
            if (!String.IsNullOrEmpty(handler))
            {
                return String.Format(CultureInfo.InvariantCulture, " {0}: Function.createDelegate(this, {1}),", new Object[] { propertyName, handler.ToString() });
            }
            return String.Empty;
        }

        private static String GenerateAjaxScript(AjaxOptions ajaxOptions, String scriptFormat)
        {
            String str = ToJavascriptString(ajaxOptions);
            return String.Format(CultureInfo.InvariantCulture, scriptFormat, new Object[] { str });
        }

        private static String GetInsertionModeString(AjaxOptions ajaxOptions)
        {
            switch (ajaxOptions.InsertionMode)
            {
                case InsertionMode.Replace:
                    return "Sys.Mvc.InsertionMode.replace";

                case InsertionMode.InsertBefore:
                    return "Sys.Mvc.InsertionMode.insertBefore";

                case InsertionMode.InsertAfter:
                    return "Sys.Mvc.InsertionMode.insertAfter";
            }
            return ((Int32)ajaxOptions.InsertionMode).ToString(CultureInfo.InvariantCulture);
        }

        private static String PropertyStringIfSpecified(String propertyName, String propertyValue)
        {
            if (!String.IsNullOrEmpty(propertyValue))
            {
                String str = propertyValue.Replace("'", @"\'");
                return String.Format(CultureInfo.InvariantCulture, " {0}: '{1}',", new Object[] { propertyName, str });
            }
            return String.Empty;
        }

        private static String ToJavascriptString(AjaxOptions ajaxOptions)
        {
            StringBuilder builder = new StringBuilder("{");
            builder.Append(string.Format(CultureInfo.InvariantCulture, " insertionMode: {0},", new Object[] { GetInsertionModeString(ajaxOptions) }));
            builder.Append(PropertyStringIfSpecified("confirm", ajaxOptions.Confirm));
            builder.Append(PropertyStringIfSpecified("httpMethod", ajaxOptions.HttpMethod));
            builder.Append(PropertyStringIfSpecified("loadingElementId", ajaxOptions.LoadingElementId));
            builder.Append(PropertyStringIfSpecified("updateTargetId", ajaxOptions.UpdateTargetId));
            builder.Append(PropertyStringIfSpecified("url", ajaxOptions.Url));
            builder.Append(EventStringIfSpecified("onBegin", ajaxOptions.OnBegin));
            builder.Append(EventStringIfSpecified("onComplete", ajaxOptions.OnComplete));
            builder.Append(EventStringIfSpecified("onFailure", ajaxOptions.OnFailure));
            builder.Append(EventStringIfSpecified("onSuccess", ajaxOptions.OnSuccess));
            builder.Length--;
            builder.Append(" }");
            return builder.ToString();
        }

        #endregion
    }
}