Подтвердить что ты не робот

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.

4b9b3361

Ответ 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"})