我的观点如下:
<%@ 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属性传递给操作,没有任何问题。我想传递整个模型。
任何想法我做错了什么?
答案 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。
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);
}
}
视图:现在将复杂对象转换为JSON字符串,然后在Action View
中传递它<%= Html.ActionLink(Model.x, "SomeAction", new { modelString = XYZ.Serialize(Model) })%>
CONTROLLER:在Action方法中将对象作为字符串获取,并在使用之前将其转换回对象
public ActionResult SomeAction(string modelString)
{
XYX xyz = XYX.Deserialize(modelString);
}
多数人......
注意:在其他答案中讨论的技术在模型的情况下已经足够了,但有时你需要将一些复杂的对象(除了数据库模型)传递回控制器,因为我有这样的具体案例。
希望这会有所帮助......:)
答案 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; }
}