ASP.NET MVC Проходящие модели ActionLink
Я хотел бы передать модель и int
контроллеру, щелкнув ActionLink
.
@Html.ActionLink("Next", "Lookup", "User", new { m = Model.UserLookupViewModel, page = Model.UserLookupViewModel.curPage }, null)
Не работает, вместо этого он передает пустой экземпляр модели, чего можно было бы ожидать при использовании new
.
@Html.ActionLink("Next", "Lookup", "User", Model.UserLookupViewModel, null)
Работает.
контроллер
[HttpGet]
public ActionResult Lookup(UserLookupViewModel m, int page = 0)
{
return this.DoLookup(m, page);
}
Просмотр модели
public class UserLookupViewModel
{
public int curPage { get; set; }
[Display(Name = "Forenames")]
public string Forenames { get; set; }
[Display(Name = "Surname")]
public string Surname { get; set; }
[Display(Name = "DOB")]
public DateTime? DoB { get; set; }
[Display(Name = "Post code")]
public string Postcode { get; set; }
}
Как я могу передать их вместе? Аргументы метода Lookup
соответствуют именованным свойствам в ActionLink.
Ответы
Ответ 1
Вы не можете использовать ActionLink для передачи свойств с помощью Link, но вы можете сделать следующее, чтобы получить такое же поведение.
<form action="/url/to/action" Method="GET">
<input type="hidden" name="Property" value="hello,world" />
<button type="submit">Go To User</button>
</form>
Если вы создадите помощник для создания этих форм GET, вы сможете их стилизовать, как обычные кнопки ссылок. Единственное, о чем я предупреждаю, это то, что формы ВСЕ на странице подвержены изменениям, поэтому я не доверяю данным. Я предпочел бы просто вытащить данные снова, когда вы доберетесь туда, куда идете.
Я использую этот метод выше при создании действий поиска и хочу сохранить историю поиска и поддерживать обратную кнопку.
Надеюсь, что это поможет,
Халид:)
P.S.
Причина, по которой это работает.
@Html.ActionLink("Next", "Lookup", "User", Model.UserLookupViewModel, null)
Это потому, что список параметров метода ActionLink обобщен для принятия объекта, поэтому ему потребуется что угодно. Что он будет делать с этим объектом, передайте его в RouteValueDictionary, а затем попытайтесь создать запрос, основанный на свойствах этого объекта.
Если вы говорите, что этот метод работает выше, вы можете просто попробовать добавить новое свойство в viewmodel с именем Id, и он будет работать так, как вы этого хотели.
Ответ 2
Вам придется сериализовать вашу модель как строку JSON и отправить ее на ваш контроллер, чтобы превратиться в объект.
Здесь ваш actionlink:
@Html.ActionLink("Next", "Lookup", "User", new { JSONModel = Json.Encode(Model.UserLookupViewModel), page = Model.UserLookupViewModel.curPage }, null)
В вашем контроллере вам понадобится метод превращения ваших данных JSON в MemoryStream:
private Stream GenerateStreamFromString(string s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
В вашем ActionResult вы превращаете строку JSON в объект:
public ActionResult YourAction(string JSONModel, int page)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Model.UserLookupViewModel));
var yourobject = (UserLookupViewModel)ser.ReadObject(GenerateStreamFromString(JSONModel));
}
Ответ 3
Хотя я настоятельно рекомендую вам использовать форму, чтобы выполнить то, что вы пытаетесь сделать здесь ради безопасности.
@Html.ActionLink("Next", "Lookup", "User", new
{ Forenames = Model.UserLookupViewModel.Forenames,
Surname = Model.UserLookupViewModel.Surname,
DOB = Model.UserLookupViewModel.DOB,
PostCode = Model.UserLookupViewModel.PostCode,
page = Model.UserLookupViewModel.curPage }, null)
MVC отобразит свойства, соответствующие этому; однако это будет использовать ваш url для передачи значений контроллеру. Это отобразит значения для всего мира.
Я настоятельно рекомендую использовать форму для безопасности, особенно при работе с конфиденциальными данными, такими как DOB.
Я лично сделал бы что-то вроде этого:
@using (Html.BeginForm("Lookup", "User")
{
@Html.HiddenFor(x => x.Forenames)
@Html.HiddenFor(x => x.Surname)
@Html.HiddenFor(x => x.DOB)
@Html.HiddenFor(x => x.PostCode)
@Html.HiddenFor(x => x.curPage)
<input type="submit" value="Next" />
}
При необходимости вы можете иметь несколько типов этих типов на странице.
Затем ваш контроллер принимает сообщение, но работает одинаково:
[HttpPost]
public ActionResult Lookup(UserLookupViewModel m, int page = 0)
{
return this.DoLookup(m, page);
}
Ответ 4
Пожалуйста, попробуйте это решение:
@{
var routeValueDictionary = new RouteValueDictionary("");
routeValueDictionary.Add("Forenames",Forenames);
routeValueDictionary.Add("Surname",Surname);
routeValueDictionary.Add("DoB ",DoB );
routeValueDictionary.Add("Postcode",Postcode );
routeValueDictionary.Add("Page",PageNum );
// Add any item you want!
}
@html.ActionLink("LinkName", "ActionName", "ControllerName",
routeValueDictionary , new{@class="form-control"})