ASP.NET MVC - 在Html.ActionLink routeValues中传递模型的麻烦

时间:2010-11-16 18:48:40

标签: c# asp.net asp.net-mvc

我的观点如下:

<%@ Control Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<TMS.MVC.BusinessSystemsSupport.Models.SearchDataTypeModel>" %>


<table class="classQueryResultsTable">
   <!-- the header -->
  <tr class="headerRow">

      <td>
      <%= Html.ActionLink("Effective Startdate",
                  "SortDetails",
                  "DataQryUpdate",
                  new
                  {
                      model = Model,
                      sortBy = "EffectiveStartDate",
                  },
                  new { @class = "classLinkLogDetails" })%>
      </td>

  </tr>


</table>

我的控制器操作:

    public ActionResult SortDetails(SearchDataTypeModel model, String sortBy)
    {

model参数为null。 sortBy参数已填充。我可以将模型中的String属性传递给操作,没有任何问题。我想传递整个模型。

任何想法我做错了什么?

6 个答案:

答案 0 :(得分:16)

您无法传递复杂对象:

new
{
    model = Model,
    sortBy = "EffectiveStartDate",
},

model = Model毫无意义,无法使用GET发送。您可能需要使用带有编辑器模板和/或隐藏字段的表单来发送所有模型属性。请记住,只能在查询字符串中发送标量值(key1 = value1&amp; key2 = value2 ...)。想到的另一种选择是仅发送ID:

new
{
    modelId = Model.Id,
    sortBy = "EffectiveStartDate",
},

并在您的控制器操作中从数据存储中获取给定此ID的模型:

public ActionResult SortDetails(int modelId, String sortBy)
{
    var model = repository.GetModel(modelId);
    ...
}

当然,只有用户不应该在表单中编辑模型属性时才会出现这种情况。取决于你的情况。

为了完整起见,让我公开另一个选择:使用MVC Futures的Html.Serialize帮助程序将整个模型序列化为隐藏字段,该字段可以传递回控制器操作并在那里反序列化。

答案 1 :(得分:13)

还有另一种方法可以在ActionLink中专门传递模型或复杂对象作为RouteValues。

  1. MODEL:在类中创建静态序列化和反序列化方法,如

    public class XYZ
    { 
        // Some Fields
        public string X { get; set; }
        public string Y { get; set; }
        public string X { get; set; }
    
        // This will convert the passed XYZ object to JSON string
        public static string Serialize(XYZ xyz)
        {
            var serializer = new JavaScriptSerializer();
            return serializer.Serialize(xyz);
        }
    
        // This will convert the passed JSON string back to XYZ object
        public static XYZ Deserialize(string data)
        {
            var serializer = new JavaScriptSerializer();
            return serializer.Deserialize<XYZ>(data);
        }
    }
    
  2. 视图:现在将复杂对象转换为JSON字符串,然后在Action View

    中传递它
    <%= Html.ActionLink(Model.x, "SomeAction", new { modelString = XYZ.Serialize(Model) })%>
    
  3. CONTROLLER:在Action方法中将对象作为字符串获取,并在使用之前将其转换回对象

    public ActionResult SomeAction(string modelString)
    {
        XYX xyz = XYX.Deserialize(modelString);
    }
    
  4. 多数人......

    注意:在其他答案中讨论的技术在模型的情况下已经足够了,但有时你需要将一些复杂的对象(除了数据库模型)传递回控制器,因为我有这样的具体案例。

    希望这会有所帮助......:)

答案 2 :(得分:3)

另一个选择是在TempData中保留所需的数据。这将把它交给下一个请求,你可以在那里检索它。如果需要,您应该能够保留整个模型对象。

但正如达林建议的那样,从数据库中再次检索它会更容易(也更好)。

答案 3 :(得分:2)

您必须序列化该对象。网址会变得丑陋,并且可能会变得很长。

这有点接近你所寻找的。 我使用仅在控制器中保留的自定义参数。 只是易于维护,并且它们是强类型的。我不喜欢引号中的变量。 如果我在表单提交中使用这些,那么一切都很好。

<form><%=Html.TextBox("catid.Value") %></form> 

如果我使用Html.ActionLink,那么它没有用。 基本上,Url必须看起来像这样 ?catid.Value = 31f1a21a-9546-4f2f-8c26-a0273d11b233

解决方法非常简单,因为我还记得如何手动编写html A标记。<​​/ p>

<a href="?catid.Value=<%= cat.ID %>" ><%: cat.Name %></a>

 public ActionResult Index(Core.ControllerPersistence._Guid catid)
        {
            if (catid.Value.HasValue)
            {

除了一些Html助手之外,并不是所有的Hx助手都像是一个可以放在口袋里的笔,它会自动标记你的名字,因此你不必移动你的手腕。如果由于某种原因,笔有一天不工作只需抓住一支普通的笔并移动你的手腕,这样你就可以签名并继续前进。

答案 4 :(得分:1)

杰夫,

也许你可以创建一个具有SearchDataTypeModel和sortby属性的View类,然后将它传递给视图。单击actionlink时,只传递Model.SearchDataTypeModel。 HTH

答案 5 :(得分:0)

也许为时已晚。有一些解决方案。与this类似的东西。 这是我的例子。

生成代码的网址:

var rv = new RouteValueDictionary();
rv["sortBy"] = currentSortColumn;
rv["ascending"] = currentSortColumn == sortBy ? !ascending : true;
rv["filter.Id"] = // some value
rv["filter.Creator"] = // some value

var url = url.Action( // url is UrlHelper
    actionName,
    controllerName,
    rv);

// as result it will output something like this: 
// http://your_host/yourController/yourAction?sortBy=name&ascending=True&filter.Id=100&filter.Creator=test

控制器代码:

public ActionResult YourAction(string sortBy = "name", bool ascending = false, YourFilterModel filter = null)

过滤器对象类:

public class YourFilterModel 
{
    public string Id { get; set; }
    public string Creator { get; set; }
}