HiddenFor (x => x.Id) заселяется UrlParameter вместо ViewModel

public ActionResult SomeAction(int Id){
    //Id is set to 2

    var model = //get some thing from db using Id(2);
    //Now model.Id is set to 9;

    return View(model);
}

----------View----------
@Html.HiddenFor(x => x.Id)

Когда я просматриваю источник, это скрытое поле устанавливается равным 2, а не 9. Как мне его сопоставить с моделью вместо сопоставления с информацией о маршрутизации URL?

P.S. Я бы предпочел не переименовывать параметры, потому что тогда я теряю свой красивый URL-адрес, если не изменю информацию о маршрутизации. Я сделал это, и он работает, но не то, что я хочу.

Ответ 1

Когда вызов Action вызывается, фреймворк строит a ModelStateCollection на основе значений строки запроса, данных post-data, маршрутизации и т.д. И этот ModelStateCollection будет передан в View. Все входные помощники HTML пытаются получить значения из ModelStateCollection first, прежде чем пытаться получить значения из фактической модели.

Поскольку ваша модель ввода - это int id, но модель вывода - это какая-то новая модель, помощники будут использовать значения из ModelStateCollection (из строки запроса), потому что имена свойств Id соответствуют.

Чтобы сделать это, вы должны вручную очистить ModelStateCollection, прежде чем возвращать новую модель в представление:

public ActionResult SomeAction(int Id){
    //Id is set to 2

    ModelState.Clear();

    var model = //get some thing from db using Id(2);
    //Now model.Id is set to 9;

    return View(model);
}

Ответ 2

Вы можете попробовать это ниже

<input id="Id" type="hidden" value="@Model.Id" />

Возможно, это не то, что вы хотите, но по существу делает то же самое.

Ответ 3

Вы можете использовать TextBoxFor и скрывать его с помощью CSS как

@Html.TextBoxFor(x => x.Id, new { @style="visibility:hidden; width:4px;"})

Это сработало для меня.