繁体   English   中英

表MVC中的ActionLink

[英]ActionLink in Table MVC

编辑:我已经阅读并实现了本文介绍的方法,但是这种方法不起作用。

我有正确填充的下表。

<table class="table">
   <tr>
       <th>Product</th>
       <th>File Name</th>
       <th>Release Date</th>
       <th>Size</th>
       <th></th>
   </tr>
   @{
       if (Model != null)
       {
           foreach (var item in Model.Uploads)
           {
               <tr>
                   <td>@Html.DisplayFor(modelItem => item.Product)</td>
                   <td>@Html.DisplayFor(modelItem => item.DisplayName)</td>
                   <td>@Html.DisplayFor(modelItem => item.ReleaseDate)</td>
                   <td>@Html.DisplayFor(modelItem => item.Size)</td>
                   <td>@Html.ActionLink("Delete File", "Upload", "Tools", new { id = item.DisplayName }, null)</td>
               </tr>
           }
       }
   }
</table>

我也有一个动作控制器

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteUser(
    AdministratorViewModel model, string userName)
{
    // Do amazing stuff...
    return Index();
}

我想将选择删除的用户名传递给此操作。 我以为可以通过上述@Html.ActionLink达到此目的,但这不是要走的路。

如何将所选的用户名传递给我的操作方法?

谢谢你的时间。


编辑:将Ajax代码更改为以下代码(使用Index作为被调用方法)

@Ajax.ActionLink(
    "Remove",
    "Index", 
    "Tools",
    new
    {
        model = item,
        userName = item.UserName
    },
    new AjaxOptions
    {
        InsertionMode = InsertionMode.Replace,
        HttpMethod = "POST"
    })

并将DeleteUser(AdministratorViewModel model, string userName)方法的名称更改为Index(AdministratorViewModel model, string userName) 现在,这将在ToolsController触发Index方法。 但是调用的方法是NON-POST属性方法(!?),所以我现在有两个问题:

  1. 如何调用未标记[HttpPost]属性的方法?
  2. 为什么我可以使用下面的Ben Griffiths的答案调用DeleteUser方法?
  3. 如何在工具控制器中调用我的DeleteUser方法,并传入模型和要删除的用户名?

谢谢你的时间。

调用时使用的ActionLink扩展方法的重载的第四个参数

Html.ActionLink("Delete File", "Upload", "Tools", new { id = item.DisplayName }, null)

用于route values参数,可用于将数据传递回控制器。

当前,在上述调用中, Tools控制器上的Upload操作方法将接收id参数。 如果要将显示名称传递回DeleteUser操作方法,则可以使用

Html.ActionLink("Delete User", "DeleteUser", "[ControllerName]", new { userName = item.DisplayName }, null)

但是, DeleteUser方法使用HttpPost属性修饰,这意味着该操作将仅接受使用post方法的请求。 这意味着您有三个选择:

(1)从action方法中删除[HttpPost]属性-可能不是一个好主意,因为我想您不想出于充分理由公开此操作以获取请求。

(2)使用包含提交输入和隐藏的DisplayName输入而不是链接的表单。

(3)使用AjaxHelper.ActionLink扩展方法对您的控制器进行异步回发。 例如:

Ajax.ActionLink("Delete User", "DeleteUser", "[ControllerName]", new { userName = item.DisplayName }, new AjaxOptions{ HttpMethod = "Post" })

更新:第三个选项的更完整示例

这是第三个选项的工作示例(尽管非常简单)。 我不确定100%的最终目标是什么,因此,我没有尝试提供一个现实的示例,而是尝试创建一个简单但清晰的示例。 请注意,为了简化起见,我省略了防伪令牌的处理,但是我坚持使用async操作方法,以免与现实生活相差太大。

控制器:

public class HomeController : Controller {

    private async Task<string> Delete(string displayName) {
        Thread.Sleep(1000);
        return string.Format("{0} has been deleted", displayName);
    }

    [HttpPost]
    [AllowAnonymous]
    public async Task<JsonResult> DeleteItem(string displayName, int product) {

        Task<string> deleteTask = Delete(displayName);

        return new JsonResult() {
            Data = new { 
                product = product,
                result = await deleteTask }
        };
    }



    public ActionResult Index() {

        AdministratorViewModel model = new AdministratorViewModel() {
            Uploads = new List<ItemModel>() {
                new ItemModel() {
                    DisplayName = "First one",
                    Product = 1,
                    ReleaseDate = DateTime.Now,
                    Size = 11
                },
                new ItemModel() {
                    DisplayName = "Second one",
                    Product = 2,
                    ReleaseDate = DateTime.Now.AddDays(1),
                    Size = 12
                }
            }
        };


        return View(model);
    }

}

模型:

public class AdministratorViewModel {
    public IEnumerable<ItemModel> Uploads { get; set; }
}

布局:

<!DOCTYPE html>
<html>
    <head>
        <title>Demo</title>
    </head>
    <body>
        @RenderBody()
        <script src="~/Scripts/jquery-1.10.2.js"></script>
        <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
        @RenderSection("scripts", false)
    </body>
</html>

主页/索引视图:

 @model AdministratorViewModel

 <table class="table">
    <tr>
        <th>Product</th>
        <th>File Name</th>
        <th>Release Date</th>
        <th>Size</th>
        <th></th>
    </tr>
    @{
        if (Model != null) {
            foreach (var item in Model.Uploads) {
                <tr>
                    <td>@Html.DisplayFor(modelItem => item.Product)</td>
                    <td>@Html.DisplayFor(modelItem => item.DisplayName)</td>
                    <td>@Html.DisplayFor(modelItem => item.ReleaseDate)</td>
                    <td>@Html.DisplayFor(modelItem => item.Size)</td>
                    <td>@Ajax.ActionLink("Remove", "DeleteItem", "Home", new { displayName = item.DisplayName, product = item.Product }, new AjaxOptions { HttpMethod = "POST", OnComplete = "itemDeleted" }, new { id = item.Product })</td>
                </tr>
            }
        }
    }
</table>

@section scripts {
    <script>
        var itemDeleted = function (data) {
            var $link = $('#' + data.responseJSON.product);
            $link.parents('tr')
                 .children()
                 .css('text-decoration', 'line-through');

            $link.remove();

            alert(data.responseJSON.result);
        };
    </script>
}

我认为首先您必须通过添加路由来处理url

routes.MapRoute(
                name: "Default",
                url: "{User}/{DeleteUser}/{username}",
                defaults: new { controller = "Home", action = "Index", username = UrlParameter.Optional }
            );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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