ASP.NET MVC - модель передачи неисправностей в Html.ActionLink routeValues - PullRequest
12 голосов
/ 16 ноября 2010

Мой вид выглядит следующим образом:

<%@ 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)
    {

Параметр модели равен нулю.Параметр sortBy заполняется.Я могу передать свойство String из модели в действие без проблем.Я хочу передать всю модель, хотя.

Есть идеи, что я делаю не так?

Ответы [ 6 ]

16 голосов
/ 16 ноября 2010

Вы не можете передавать сложные объекты:

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

model = Model не имеет смысла и не может быть отправлено с помощью GET.Возможно, вам придется использовать форму с шаблоном редактора и / или скрытыми полями для отправки всех свойств модели.Помните, что в строке запроса могут быть отправлены только скалярные значения (key1 = value1 & key2 = value2 ...).Еще одна альтернатива, которая приходит на ум, это отправить только идентификатор:

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

и в вашем действии контроллера получить модель с данным идентификатором из вашего хранилища данных:

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

Конечно, этоИстинно, только если пользователь не должен редактировать свойства модели в форме.Зависит от вашего сценария.

И ради полноты позвольте мне предложить другой вариант: используйте помощник Html.Serialize из MVC Futures для сериализации всей модели в скрытое поле, которое можетпередается обратно в действие контроллера и там десериализуется.

13 голосов
/ 30 января 2013

Существует другой способ передачи модели или сложных объектов, в частности, в 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);
    }
    

Thats All ...

Примечание: Методы, обсуждаемые в других ответах, достаточно хороши вслучай модели, но иногда вам нужно передать какой-то сложный объект (кроме модели базы данных) обратно в контроллер, как у меня есть такой конкретный случай.

Надеюсь, это поможет некоторым ...:)

3 голосов
/ 16 ноября 2010

Еще один вариант - сохранить данные, которые вам нужны в TempData. Это передаст его следующему запросу, и вы сможете получить его там. Вы должны быть в состоянии сохранить весь объект модели, если хотите.

Но проще (и лучше практиковать) просто извлечь его снова из базы данных, как предлагает Дарин.

2 голосов
/ 09 февраля 2011

Вы должны сериализовать объект.URL станет уродливым и рискует стать длинным.

Это как бы близко к тому, что вы искали.Я использую пользовательские параметры, которые сохраняются только внутри контроллера.Просто в обслуживании и они строго набраны.Я не люблю переменную в кавычках.Если я использую их в форме отправки, тогда все хорошо.

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

Если я использую Html.ActionLink, тогда это не работает.По сути, URL должен выглядеть примерно так? Catid.Value = 31f1a21a-9546-4f2f-8c26-a0273d11b233

Обходной путь довольно прост, так как я до сих пор помню, как вручную написать HTML-тег A.

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

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

Не все, кроме некоторых Html-помощников, похожи на ручку, которую вы носите в кармане, которая автоматически подписывает ваше имя, поэтому вам не нужно сдвигать запястье.Если по какой-то причине ручка однажды не работает, просто возьмите обычную ручку и переместите свое запястье, чтобы вы могли подписать свое имя и двигаться дальше.

1 голос
/ 16 ноября 2010

Джефф,

Может быть, вы могли бы создать класс View, который имеет свойства SearchDataTypeModel и sortby, и передать его представлению.Когда вы нажимаете на ссылку действия, просто передайте ей Model.SearchDataTypeModel.НТН

0 голосов
/ 11 июля 2015

Может быть, уже слишком поздно. Есть какое-то решение. Нечто похожее на это . Вот мой пример.

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; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...