asp.net-mvc Mvc Html.ActionButton

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/901372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:36:26  来源:igfitidea点击:

Mvc Html.ActionButton

asp.net-mvc

提问by Dan

Has anyone written one? I want it to behave like a link but look like a button. A form with a single button wont do it has I don't want any POST.

有人写过吗?我希望它表现得像一个链接,但看起来像一个按钮。带有单个按钮的表单不会这样做,我不想要任何 POST。

回答by Tomas Aschan

The easiest way to do it is to have a small formtag with method="get", in which you place a submit button:

最简单的方法是有一个带有 的小form标签method="get",在其中放置一个提交按钮:

<form method="get" action="/myController/myAction/">
    <input type="submit" value="button text goes here" />
</form>

You can of course write a very simple extension method that takes the button text and a RouteValueDictionary(or an anonymous type with the routevalues) and builds the form so you won't have to re-do it everywhere.

您当然可以编写一个非常简单的扩展方法,它接受按钮文本和 a RouteValueDictionary(或带有路由值的匿名类型)并构建表单,这样您就不必在任何地方重新执行它。

EDIT: In response to cdmckay's answer, here's an alternative code that uses the TagBuilderclass instead of a regular StringBuilderto build the form, mostly for clarity:

编辑:为了回应 cdmckay 的回答,这里有一个替代代码,它使用TagBuilder类而不是常规StringBuilder来构建表单,主要是为了清楚起见:

using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

namespace MvcApplication1
{
    public static class HtmlExtensions
    {
        public static string ActionButton(this HtmlHelper helper, string value, 
                              string action, string controller, object routeValues)
        {
            var a = (new UrlHelper(helper.ViewContext.RequestContext))
                        .Action(action, controller, routeValues);

            var form = new TagBuilder("form");
            form.Attributes.Add("method", "get");
            form.Attributes.Add("action", a);

            var input = new TagBuilder("input");
            input.Attributes.Add("type", "submit");
            input.Attributes.Add("value", value);

            form.InnerHtml = input.ToString(TagRenderMode.SelfClosing);

            return form.ToString(TagRenderMode.Normal);
        }
    }
}

Also, as opposed to cdmckay's code, this one will actually compile ;) I am aware that there might be quite a lot of overhead in this code, but I am expecting that you won't need to run it a lot of times on each page. In case you do, there is probably a bunch of optimizations that you could do.

此外,与 cdmckay 的代码相反,这个代码实际上可以编译 ;) 我知道这段代码中可能有很多开销,但我希望你不需要在每个代码上运行它很多次页。如果你这样做了,你可能会做很多优化。

回答by Brett Allred

If you want it to behave like a link but "look" like a button just use the ActionLink with a CSS Class.

如果您希望它表现得像一个链接但“看起来”像一个按钮,只需使用带有 CSS 类的 ActionLink。

<%: Html.ActionLink("Back", "Index", null, new { @class = "link-button" })%>

Here is the CSS for a Button that I am using.

这是我正在使用的按钮的 CSS。

.link-button {
    -moz-border-radius:0.333em 0.333em 0.333em 0.333em;
    -moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.4);
    background:-moz-linear-gradient(center top , white, #306AB5 4%, #274976) repeat scroll 0 0 transparent;
    border-color:#306AB5 #2B5892 #274771;
    border-style:solid;
    border-width:1px;
    color:white;
    cursor:pointer;
    display:inline-block;
    font-size:1.167em;
    font-weight:bold;
    line-height:1.429em;
    padding:0.286em 1em 0.357em;
    text-shadow:0 1px 2px rgba(0, 0, 0, 0.4);
}


.link-button {
    color: white;
    border-color: #a1a7ae #909498 #6b7076;
    background: #9fa7b0 url(../images/old-browsers-bg/button-element-grey-bg.png) repeat-x top;
    background: -moz-linear-gradient(
        top,
        white,
        #c5cbce 5%,
        #9fa7b0
    );
    background: -webkit-gradient(
        linear,
        left top, left bottom,
        from(white),
        to(#9fa7b0),
        color-stop(0.05, #c5cbce)
    );
    -moz-text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
    -webkit-text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
    -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
    -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
    }
    .link-button:hover {
        border-color: #a1a7b0 #939798 #6e7275;
        background: #b1b5ba url(../images/old-browsers-bg/button-element-grey-hover-bg.png) repeat-x top;
        background: -moz-linear-gradient(
            top,
            white,
            #d6dadc 4%,
            #b1b5ba
        );
        background: -webkit-gradient(
            linear,
            left top, left bottom,
            from(white),
            to(#b1b5ba),
            color-stop(0.03, #d6dadc)
        );
    }
    .link-button:active {
        border-color: #666666 #ffffff #ffffff #979898;
        background: #dddddd url(../images/old-browsers-bg/button-element-grey-active-bg.png) repeat-x top;
        background: -moz-linear-gradient(
            top,
            #f1f1f1,
            #dddddd
        );
        background: -webkit-gradient(
            linear,
            left top, left bottom,
            from(#f1f1f1),
            to(#dddddd)
        );
    }

回答by Valamas

Two versions to make an extension for...

两个版本来扩展...

<button 
    onclick="javascript:window.location=('@Url.Action("Review", "Order", null)')"
    >Review Order</button>

Unobtrusive version:

不显眼的版本:

<button data-action="@Url.Action("Review", "Order", null)">Review Order</button>

$(document).on('click', "[data-action]", 
    function(e) { window.location = $(this).attr('data-action'); }
);

If you have users which do not have javascript turned on, then form tag is the way to go. Although, this make the situation difficult if your link is already within a form. However, you could change the action and method to GET.

如果您的用户没有打开 javascript,那么表单标签就是您要走的路。虽然,如果您的链接已经在表单中,这会使情况变得困难。但是,您可以将操作和方法更改为 GET。

回答by cdmckay

Code for Tomas' answer:

托马斯的回答代码:

public static class HtmlExtensions
{
  public static string ActionButton(this HtmlHelper helper, string value, 
      string action, string controller, object routeValues)
  {
    UrlHelper urlHelper = new UrlHelper(helper.ViewContext);
    var action = urlHelper.Action(action, controller, routeValues);

    var html = new StringBuilder();
    html.AppendFormat("<form method='get' action'{0}'>", action).AppendLine()
        .AppendFormat("    <input type='submit' value='{0}' />", value).AppendLine()
        .AppendFormat("</form>").AppendLine();

    return html.ToString();
  }
}

回答by T.J.Kjaer

I modified Tomas Lyckens code to return a MvcHtmlString instead of just a string. This makes sure the output is HTML, not escaped as text. I also xml-documented it nicely. Thanks to Tomas who did all the real work.

我修改了 Tomas Lyckens 代码以返回一个 MvcHtmlString 而不仅仅是一个字符串。这确保输出是 HTML,而不是作为文本转义。我也很好地对其进行了 xml 文档化。感谢 Tomas,他做了所有真正的工作。

    /// <summary>
    /// Returns an HTML submit button (enclosed in its own form) that contains the virtual path of the specified action.
    /// </summary>
    /// <param name="helper">The HTML helper instance that this method extends.</param>
    /// <param name="buttonText">The visible text of the button.</param>
    /// <param name="action">The name of the action.</param>
    /// <param name="controller">The name of the controller.</param>
    /// <param name="routeValues">An object that contains the parameters for a route. The parameters are retrieved through reflection by examining the properties of the object. The object is typically created by using object initializer syntax.</param>
    /// <returns></returns>
    public static MvcHtmlString ActionButton(this HtmlHelper helper, string buttonText, string action, string controller, object routeValues)
    {
        string a = (new UrlHelper(helper.ViewContext.RequestContext)).Action(action, controller, routeValues);

        var form = new TagBuilder("form");
        form.Attributes.Add("method", "get");
        form.Attributes.Add("action", a);

        var input = new TagBuilder("input");
        input.Attributes.Add("type", "submit");
        input.Attributes.Add("value", buttonText);

        form.InnerHtml = input.ToString(TagRenderMode.SelfClosing);

        return MvcHtmlString.Create(form.ToString(TagRenderMode.Normal));
    } 

回答by Tony Wall

Here is a VB.NET version with one extra thing, the controller and routes parameters are optional so it can be used without repeating the controller name if it's the same as the current/default controller for the page.

这是一个 VB.NET 版本,有一个额外的东西,控制器和路由参数是可选的,因此如果它与页面的当前/默认控制器相同,则可以在不重复控制器名称的情况下使用它。

Public Module MvcExtensions

    ''' <summary> 
    ''' Returns an HTML submit button (enclosed in its own form) that contains the virtual path of the specified action. 
    ''' </summary> 
    ''' <param name="helper">The HTML helper instance that this method extends.</param> 
    ''' <param name="text">Text displayed in the button.</param> 
    ''' <param name="action">Action name.</param> 
    ''' <param name="controller">Optional controller name, using current when null.</param> 
    ''' <param name="routeValues">
    ''' An object that contains the parameters for a route. The parameters are retrieved
    ''' through reflection by examining the properties of the object.
    ''' The object is typically created by using object initializer syntax.
    ''' </param> 
    ''' <returns>
    ''' HTML output.
    ''' </returns> 
    <Extension()> _
    Public Function ActionButton(helper As HtmlHelper, text As String, action As String,
                                 Optional controller As String = Nothing, Optional routeValues As Object = Nothing) As MvcHtmlString

        ' Validate parameters
        If String.IsNullOrEmpty(text) Then Throw New ArgumentNullException("text")

        ' Get post back URL for action
        Dim actionUrl As String = New UrlHelper(helper.ViewContext.RequestContext).Action(action, controller, routeValues)

        ' Build form tag with action URL
        Dim form = New TagBuilder("form")
        form.Attributes.Add("method", "get")
        form.Attributes.Add("action", actionUrl)

        ' Add button
        Dim input = New TagBuilder("input")
        input.Attributes.Add("type", "submit")
        input.Attributes.Add("value", text)
        form.InnerHtml = input.ToString(TagRenderMode.SelfClosing)

        ' Return result as HTML
        Return MvcHtmlString.Create(form.ToString(TagRenderMode.Normal))

    End Function

End Module

Then it can be invoked like the other other MVC controls, with minimum code on the page.

然后它可以像其他 MVC 控件一样被调用,页面上的代码最少。

This should really have gone into the core MVC framework from the start; it seems such an obvious requirement. I think buttons are much more intuitive for the user when performing actions which create or change things, rather than links. Links should just navigate to related information (not change anything). If i had a grid I would use ActionLink for any data navigation (e.g. click a product name to goto product page) but only ActionButton for real "actions" like edit and delete.

这真的应该从一开始就进入核心 MVC 框架;这似乎是一个明显的要求。我认为在执行创建或更改事物的操作时,按钮对用户来说更加直观,而不是链接。链接应该只导航到相关信息(不更改任何内容)。如果我有一个网格,我会使用 ActionLink 进行任何数据导航(例如,单击产品名称转到产品页面),但只有 ActionButton 用于真正的“操作”,例如编辑和删除。

回答by numaroth

If you want a button that functions like a link this should work:

如果您想要一个功能类似于链接的按钮,这应该可以工作:

<input type="button" value="Button Text"
  onclick="@("location.href='http://stackoverflow.com/q/901372/2460971'")" />

If you want the button to use a controller action only a minor change is needed:

如果您希望按钮使用控制器操作,则只需稍作更改:

<input type="button" value="Button Text"
  onclick="@("location.href='" + Url.Action("ActionName", "ControllerName") + "'")" />