Typically, if I have a field that is "read-only" but needs to be submitted back to the server, I will make the display disabled (or simply text), but then add a hidden field with the same name. You still need to make sure that the field is not actually modified on the server-side -- just don't update it from the model in your action -- but the model state will still be accurate if there are errors.
Can't you make the field readonly="readonly" instead of disabled="disabled"? A readonly field value will be submitted to the server while still being non-editable by the user. A SELECT tag is an exception though.
@ppumkin mentioned this on his comment on this answer but I wanted to highlight it as I was unable to find other resources on submitting data from a disabled <select>. I also believe it is relevant to the question as selects are not <input>s but they are "input"s.
Just include a Hidden field for the disabled select and its all sorted.
Example:
@Html.DropDownListFor(model => model.SelectedID, ... , new { disabled = "disabled"}) @* Won't be posted back *@
@Html.HiddenFor(model => model.SelectedID) @* Will be posted back *@
Caution: this will put two tags on the page with the same ID, which is not really valid HTML and could cause headaches with javascript. For me, I have javascript to set the value of the dropdown by its html id, and if you put the hidden field first, the javascript will find that instead of the select.
when we are dealing with disabled but checked checkboxes and we want to post the value, we need to ensure our hidden field appears before the @Html.CheckBoxFor hidden field.
I usually use this way for CheckBox or CheckBoxFor because making it disabled is causing the losing the value. Readonly doesn't work on checkbox neither.
Either make them readonly which allows submitting values to server
or if you're dealing with controls that are still usable with readonly attribute such as Select, add css style pointer-events: none; to make them non-interactive
Kind of a hack, but works! It also works when you are submitting form directly with submit button without using javascript. No extra work required!
Just put this script in @section scripts in your page.
this will enable inputs when you submit the page, and you should redirect user to another page after submit.