Ответ 1
Для короткого ответа вам нужно сделать три вещи:
- Удалите
new { Checked = "checked" }
со второго переключателя. Это жестко запрограммированное значение будет отменять все магические действия. - Когда вы возвращаете свой ViewResult из действия контроллера, дайте ему экземпляр вашего модельного класса, где TermsAndConditions является ложным. Это предоставит ложное значение по умолчанию, которое вам нужно для того, чтобы для вас была выбрана ложная радиокнига.
- Используйте
true
иfalse
как значения для ваших радиокнопок вместо"True"
и"False"
. Это связано с тем, что ваше свойство имеет типbool
. Строго говоря, вы случайно выбрали правильные строковые представления дляtrue
иfalse
, но параметр значения для метода RadioButtonFor имеет типobject
. Лучше всего передать фактический тип, который вы хотите сравнить, вместо того, чтобы преобразовывать его в строку самостоятельно. Подробнее об этом ниже.
Вот что происходит в глубине:
Рамка хочет сделать все это за вас автоматически, но вы сделали эти первые две вещи неправильно, что заставляет вас бороться с каркасом, чтобы получить нужное вам поведение.
Метод RadioButtonFor вызывает .ToString()
по значению указанного вами свойства и сравнивает его с .ToString()
значения, которое вы передали при создании переключателя. Если они равны, то он внутренне устанавливает isChecked = true
и заканчивает рендеринг checked="checked"
в HTML. Вот как он решает, какой переключатель выбрать. Он просто сравнивает значение переключателя со значением свойства и проверяет ту, которая соответствует.
Вы можете отображать переключатели для почти любого свойства таким образом, и это будет волшебным образом работать. Строки, ints и даже перечисления все работают! Любой объект, который имеет метод ToString
, который возвращает строку, которая однозначно представляет значение объекта, будет работать. Вам просто нужно убедиться, что вы настроили значение переключателя на значение, которое может иметь ваше свойство. Самый простой способ сделать это - просто передать значение, а не строковое представление значения. Пусть структура преобразует его в строку для вас.
(Так как вам удалось передать правильные строковые представления true
и false
, то эти значения будут работать до тех пор, пока вы исправите две свои фактические ошибки, но по-прежнему разумно передавать фактические значения, а не их строки.)
Ваша первая реальная ошибка заключалась в жестком кодировании Checked = "checked"
для переключателя "Нет". Это переопределит то, что система пытается сделать для вас, и результаты этого переключателя всегда проверяются.
Очевидно, что вы хотите, чтобы переключатель "Нет" был предварительно выбран, но вы должны сделать это так, чтобы он совместим со всем выше. Вам нужно предоставить представление экземпляра вашего модельного класса, где для параметра "Условия использования" установлено значение "ложь" и "привязать" его к переключателям. Обычно действие контроллера, которое отвечает на первоначальный запрос GET URL-адреса, вообще не отображает экземпляр класса модели. Как правило, вы просто return View();
. Однако, поскольку вы хотите, чтобы значение по умолчанию было выбрано, вы должны предоставить представление экземпляру вашей модели, для которого условия TermsAndConditions установлены на false.
Вот несколько исходных кодов, иллюстрирующих все это:
Какой-то класс учетной записи, который вы, вероятно, уже имеете. (Модель вашего вида):
public class Account
{
public bool TermsAndConditions { get; set; }
//other properties here.
}
Некоторые методы в вашем контроллере:
//This handles the initial GET request.
public ActionResult CreateAccount()
{
//this default instance will be used to pre-populate the form, making the "No" radio button checked.
var account = new Account
{
TermsAndConditions = false
};
return View( account );
}
//This handles the POST request.
[HttpPost]
public ActionResult CreateAccount( Account account )
{
if ( account.TermsAndConditions )
{
//TODO: Other validation, and create the account.
return RedirectToAction( "Welcome" );
}
else
{
ModelState.AddModelError( "TermsAndConditionsAgreement", "You must agree to the Terms and Conditions." );
return View( account );
}
}
//Something to redirect to.
public ActionResult Welcome()
{
return View();
}
Весь вид:
@model Account
@{
ViewBag.Title = "Create Account";
}
@using ( Html.BeginForm() )
{
<div>
<span>Do you agree to the Terms and Conditions?</span>
<br />
@Html.RadioButtonFor( model => model.TermsAndConditions, true, new { id = "TermsAndConditions_true" } )
<label for="TermsAndConditions_true">Yes</label>
<br />
@Html.RadioButtonFor( model => model.TermsAndConditions, false, new { id = "TermsAndConditions_false" } )
<label for="TermsAndConditions_false">No</label>
<br />
@Html.ValidationMessage( "TermsAndConditionsAgreement" )
</div>
<div>
<input id="CreateAccount" type="submit" name="submit" value="Create Account" />
</div>
}
БОНУС:. Вы заметите, что я добавил немного дополнительных функций к переключателям. Вместо того, чтобы просто использовать простой текст для ярлыков радиокнопки, я использовал элемент HTML label
с атрибутом for
, установленным на идентификаторы каждого переключателя. Это позволяет пользователям щелкнуть по метке, чтобы выбрать радиокнопку вместо того, чтобы щелкнуть по самой кнопке. Это стандартный HTML. Для этого я должен был установить ручные идентификаторы на переключателях, иначе они оба получат одинаковый идентификатор только "TermsAndConditions", который не будет работать.