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

我的视图如下所示:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> 

我的控制器动作:

  public ActionResult SortDetails(SearchDataTypeModel model, String sortBy) { 

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

我有什么想法我做错了吗?

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

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

您无法传递复杂对象:

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

model = Model没有意义,不能使用GET发送。 您可能需要使用带有编辑器模板和/或隐藏字段的表单来发送所有模型属性。 请记住,只能在查询字符串中发送标量值(key1 = value1&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助手将整个模型序列化为隐藏字段,该字段可以传递回控制器操作并在那里反序列化。

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

  1. MODEL:在类中创建静态Serialize和Deserialize方法

     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(data); } } 
  2. VIEW:现在将复杂对象转换为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); } 

就这样…

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

希望这会有所帮助… 🙂

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

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

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

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

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

 <%: cat.Name %> public ActionResult Index(Core.ControllerPersistence._Guid catid) { if (catid.Value.HasValue) { 

并非所有的Html助手都像一支笔,你可以放在口袋里自动签名,这样你就不必移动手腕了。 如果由于某种原因,笔有一天不工作只需抓住一支普通的笔并移动你的手腕,这样你就可以签名并继续前进。

杰夫,

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

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

url生成代码:

 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; } }