views:

197

answers:

2

Hi

A default value of 0 is creeping into a Surveys app I am developing, for no reason that I can see. The problem is as follows:

I have a group of Html.RadioButtons that represent the possible values a user can choose to answer a survey question (1 == Not at all, 2 == A little, 3 == A lot). I have used a tinyint datatype, that does not allow null, to store the answer to each question.

The view code looks like this:

<ol class="SurveyQuestions">
    <% foreach (SurveyQuestion question in Model.Questions)
       {  

             string col = question.QuestionColumn;     
    %>

        <li><%=question.QuestionText%>
            <ul style="float:right;" class="MultiChoice">
                <li><%= Html.RadioButton(col, "1")%></li>
                <li><%= Html.RadioButton(col, "2")%></li>
                <li><%= Html.RadioButton(col, "3")%></li>
            </ul>
            <%= Html.ValidationMessage(col, "*") %>
        </li>
    <% } %>

</ol>

[Note on the above code:]

Each survey has about 70 questions, so I have put the questions text in one table, and store the results in a different table. I have put the Questions into my form view model (hence Model.Questions); the questions table has a field called QuestionColumn that allows me to link up the answer table column to the question, as shown above (<%= Html.RadioButton(col, "1")%>, etc)

[/Note]

However, when the user DOESN'T answer the question, the value 0 is getting inserted into the database column. I would expect Null if the user doesn't select any of the radiobuttons.

As a result, I don't get what I expect, ie, a validation error due to the null value (no user input).

In no place have I stipulated a default value of 0 for the fields in the answers table.

So what is happening? Any ideas?

A: 

As you have not set any of your buttons as default checked the browser may be supplying its own value - in this case 0.

According to w3.org authors should ensure that in each set of radio buttons that one is initially "on"

Nicholas Murray
Thanks, that does sound probable, but will hold on giving you the tick, as we have no certainty yet. Any suggestions on an alternative strategy? The questionnaire has to look like its printed version (ie, radio buttons). Curious: does the same apply to drop down lists? Some browsers (Chrome) leave it blank if no pre selection, others (IE), put in a 0. That would answer one issue I have seen!
awrigley
+1  A: 

I think I have cracked it:

As the SurveyAnswers table has a list of non nullable fields (representing user input), the class generated by Linq to Sql in the dbml file has fields with byte type.

As a result, when MVC creates a new SurveyAnswer object to add the Forms values to, the default value of the byte type fields is 0. If this value is not changed in the Form, then it stays as 0 and that is what is sent to the database. I was expecting null. Nicholas may also be right: the browser returns a value of 0 when none of the radio buttons is selected. Live and learn. I will check Nicholas' post as the answer.

To solve this, I am doing the following:

Writing a check constraint for each field in SurveyAnswers (there are over 70 of them...) that restricts input to (namefield > 0 AND nameField < 4). That way I guarantee that only valid data goes into the surveys.

As a result of these check constraints, the database update initiated in the Controller for the POST action will fail, and in the catch block, I can add a validation message to the ModelState and return to the input View.

awrigley
@awrigley - good workaround!
Nicholas Murray