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

Jef*_*eff 12 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>
Run Code Online (Sandbox Code Playgroud)

我的控制器动作:

    public ActionResult SortDetails(SearchDataTypeModel model, String sortBy)
    {
Run Code Online (Sandbox Code Playgroud)

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

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

Dar*_*rov 16

您无法传递复杂对象:

new
{
    model = Model,
    sortBy = "EffectiveStartDate",
},
Run Code Online (Sandbox Code Playgroud)

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

new
{
    modelId = Model.Id,
    sortBy = "EffectiveStartDate",
},
Run Code Online (Sandbox Code Playgroud)

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

public ActionResult SortDetails(int modelId, String sortBy)
{
    var model = repository.GetModel(modelId);
    ...
}
Run Code Online (Sandbox Code Playgroud)

当然,只有在用户不应该在表单中编辑模型属性时才会这样.取决于您的方案.

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

  • Yeap,简单的字符串,就是HTTP协议的工作方式.另一种方法是仅发送ID,并在控制器操作中使用存储库从数据存储中的此ID中获取模型. (3认同)

uma*_*ali 13

还有另一种方法可以在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<XYZ>(data);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. VIEW:现在将复杂对象转换为JSON字符串,然后在Action View中传递它

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

    public ActionResult SomeAction(string modelString)
    {
        XYX xyz = XYX.Deserialize(modelString);
    }
    
    Run Code Online (Sandbox Code Playgroud)

就这样...

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

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


Rob*_*vey 3

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

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