ASP.NET MVC - модель передачи ошибок в Html.ActionLink routeValues
Мой вид выглядит следующим образом:
<%@ 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)
{
Параметр модели имеет значение NULL. Параметр sortBy заполняется. Я могу передать свойство String из модели в действие без проблем. Однако я хочу пройти во всей модели.
Любые идеи, что я делаю неправильно?
Ответы
Ответ 1
Еще одна опция - сохранить данные, которые вам нужны в TempData. Это передаст его следующему запросу, и вы сможете найти его там. Вы должны иметь возможность сохранить весь объект модели, если хотите.
Но проще (и лучше) просто вернуть его из базы данных, как предлагает Дарин.
Ответ 2
Вы не можете передавать сложные объекты:
new
{
model = Model,
sortBy = "EffectiveStartDate",
},
model = Model
не имеет смысла и не может быть отправлен с использованием GET. Возможно, вам понадобится использовать форму с шаблоном редактора и/или скрытыми полями для отправки всех свойств модели. Помните, что в строке запроса могут быть отправлены только скалярные значения (key1 = value1 & key2 = value2...). Другая альтернатива, которая приходит на ум, - отправить только ID:
new
{
modelId = Model.Id,
sortBy = "EffectiveStartDate",
},
и в действии вашего контроллера выберете модель с учетом этого идентификатора из вашего хранилища данных:
public ActionResult SortDetails(int modelId, String sortBy)
{
var model = repository.GetModel(modelId);
...
}
Конечно, это верно только в том случае, если пользователь не должен редактировать свойства модели в форме. Зависит от вашего сценария.
И ради полноты позвольте мне показать другой вариант: используйте Html.Serialize помощник из MVC Futures для сериализации всей модели в скрытое поле, которое может быть возвращено в действие контроллера и десериализовано там.
Ответ 3
Существует еще один способ передачи модельных или сложных объектов, особенно в ActionLink, как RouteValues.
-
МОДЕЛЬ: сделайте статические методы 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);
}
}
-
ПРОСМОТР: Теперь преобразуем ваш сложный объект в строку JSON, прежде чем передавать его в Action View
<%= Html.ActionLink(Model.x, "SomeAction", new { modelString = XYZ.Serialize(Model) })%>
-
CONTROLLER: получить объект как строку в методе действия и преобразовать его обратно в объект перед использованием
public ActionResult SomeAction(string modelString)
{
XYX xyz = XYX.Deserialize(modelString);
}
Thats All...
Примечание. Методы, обсуждаемые в других ответах, достаточно хороши в случае модели, но иногда вам нужно передать какой-то сложный объект (кроме модели базы данных) обратно на контроллер, поскольку у меня есть такие конкретный случай.
Надеюсь, это поможет некоторым...:)
Ответ 4
Вам придется сериализовать объект. URL-адрес станет уродливым и станет длинным.
Это похоже на то, что вы искали.
Я использую настраиваемые параметры, которые сохраняются только внутри контроллера.
Просто просты в обслуживании, и они сильные. Мне не нравится переменная в кавычках.
Если я использую их в форме submit, все это хорошо.
<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, похожи на ручку, которую вы несете в кармане, которая автоматически подписывает ваше имя, поэтому вам не нужно перемещать запястье. Если по какой-то причине перо в один прекрасный день не работает, просто возьмите обычное перо и переместите свое запястье, чтобы вы могли подписать свое имя и двигаться дальше.
Ответ 5
Джефф,
Возможно, вы могли бы создать класс View, который имеет свойства SearchDataTypeModel и sortby, и вы передадите его в представление. Когда вы нажимаете на actionlink, передайте его только Model.SearchDataTypeModel. НТН
Ответ 6
Может быть, уже слишком поздно. Получили какое-то решение. Что-то похожее на .
Вот мой пример.
Код генерации 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; }
}