2

I'm facing this weird problem ,unable to make sense of it,I have a form which accepts Person Id and then reads the data from an API and fills the UI for person Edit purposes.

enter image description here

Here is the markup of this form,I'm guessing its has something to do with Model binding as I have two Form tag and both having the same Model Id.

@using (Html.BeginForm("UpdatePerson", "Person", FormMethod.Get))
{
    <table>
        <tr>
            <td colspan="2">
                <h3>Read Person for Edit</h3>
            </td>
        </tr>
        <tr>
            <td>
                <label>@Html.LabelFor(m => m.Id)</label>
            </td>
            <td>
                @Html.TextBoxFor(m => m.Id)
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" name="btnReadPerson" value="Read Person" />
            </td>
        </tr>
    </table>
}
@using (Html.BeginForm("UpdatePerson", "Person", FormMethod.Post))
{
    <table>
        <tr>
            <td>
                <label>@Html.LabelFor(m => m.Id)</label>
            </td>
            <td>
                @Html.TextBoxFor(m => m.Id, new { @readonly = "readonly" })
            </td>
        </tr>
        <tr>
            <td>
                <label>@Html.LabelFor(m => m.Type)</label>
            </td>
            <td>
                @Html.TextBoxFor(m => m.Type)
            </td>
        </tr>
I have stripped the view,I tried to kept it brief.

Below is the Action which handles the Get

 [HttpGet]
 [ActionName("UpdatePerson")]
 public ActionResult UpdatePersonRead(PersonEditModel model)
    {
        if (model.Id.HasValue) 
        {
            var apiClient = new ApiClient (ApiVersions.v1);
            var segmentReplaceList = new Dictionary<string, string> { { "{id}", model.Id.Value.ToString() } };
            bool ApiHitStatus = false;
            var result = apiClient.MakeAPIRequest(out ApiHitStatus, ResourceUriKey.Person, segmentReplaceList, HttpVerbs.Get, string.Empty);

            model = new PersonEditModel();
            if (ApiHitStatus)
            {
                var personToBeUpdated = JsonConvert.DeserializeObject<RootChildPerson>(result);
                if (personToBeUpdated != null)//Assigning json obj to model
                {
                    model.NameFirst = personToBeUpdated.name_first;
                    model.NameLast = personToBeUpdated.name_last;
                    model.NameMiddle = personToBeUpdated.name_middle;
                    model.SocialSecurityNumber = personToBeUpdated.social_security_number;
                    model.SubType = PersonHelper.SubTypeValue(personToBeUpdated.sub_type);
                    model.Type = "person";
                    model.DateOfBirth = personToBeUpdated.date_of_birth;
                    model.Id = personToBeUpdated.id;
                }
            }
        }

        return View(model);
    }

Now since the Person Id 4 does not corresponds to any person ,so I receive Null json object which upon conversion to C# class results in an empty (not null because it has every property set to null or empty) personToBeUpdated object which is then assigned to the model,I have checked model.Id becomes null in the Controller and even in the View ,but somehow it assigns input value that is 4 (it was null) to both Person Id textboxes. Kindly let me know whats happening here.

DayTimeCoder
  • 4,294
  • 5
  • 38
  • 61
  • 1
    The values in `ModelState` take precedence over model values. You need to clear `ModelState` using `ModelState.Clear();` before trying to update model properties and returning the view. [Refer this answer](http://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111) for a more detailed explanation of the behavior. –  Dec 09 '14 at 12:11
  • @StephenMuecke It's quite helpful thanks – DayTimeCoder Dec 09 '14 at 12:28

1 Answers1

1

Well as commented by @StephenMuecke ,So I cleared model before updating it.

model = new PersonEditModel();
ModelState.Clear();

Its also interesting to note that view takes data from ModelState instead of current specified model,

HtmlHelpers controls (like .TextBoxFor() etc.) don't bind to model values on Postback, but rather get their value directly out of the POST buffer from ModelState.

Taken from ASP.NET MVC Postbacks and HtmlHelper Controls ignoring Model Changes

DayTimeCoder
  • 4,294
  • 5
  • 38
  • 61