Note that there are some explanatory texts on larger screens.

plurals
  1. POASP.NET MVC 5 Html.HiddenFor renders incorrect property value but Model.Property renders correct value
    primarykey
    data
    text
    <ul> <li>Visual Studio 2013 Professional</li> <li>C#</li> <li>.NET 4.5 Framework</li> <li>ASP.NET MVC 5</li> </ul> <p>In my view-model class, I have a property called <code>SerializedSelf</code> that is used to represent itself as a serialized string and also de-serialize, but only over any properties that aren't already initialized. I use this to simplify the round-tripping of my view-model by having a single hidden input with this value. Any other inputs related to the model will get populated in the model by the framework before getting passed to the controller method.</p> <p>The problem I'm having is that in my razor view code this isn't rendering properly:</p> <pre><code> @Html.HiddenFor(model =&gt; model.SerializedSelf) </code></pre> <p>I haven't determined if it's serializing a completely uninitialized <code>MyViewModel</code> object or if it's an instance from somewhere else.</p> <p>But this works properly:</p> <pre><code> &lt;input type="hidden" name="SerializedSelf" id="SerializedSelf" value="@Model.SerializedSelf" /&gt; </code></pre> <p>So I'm guessing it might have something to do with the lambda expression and enclosures??? When I step through in source code, the <code>SerializedSelf</code> has the proper value right before I call <code>return View("myView", model)</code>.</p> <p>Here is the view-model code:</p> <pre><code>using Newtonsoft.Json; using System; using System.Text; public class MyViewModel { [JsonIgnore] public string SerializedSelf { get { return JsonConvert.SerializeObject(this); } set { if (string.IsNullOrWhiteSpace(value)) return; string json = value; MyViewModel copy = JsonConvert.DeserializeObject&lt;MyViewModel&gt;(json); if (Message == null) Message = copy.Message; if (Phone == null) Phone = copy.Phone; // ... } } public string Message { get; set; } public string Phone { get; set; } // ... } </code></pre> <p>What would be the difference between:</p> <pre><code>@Html.HiddenFor(model =&gt; model.SerializedSelf) </code></pre> <p>and</p> <pre><code>@Model.SerializedSelf </code></pre> <p>and what would cause the former to be inaccurate?</p> <p><em>UPDATE 2013/12/5:</em> I removed the logic from <code>SerializedSelf</code> and explicitly serialize/deserialize to/from <code>SerializedSelf</code> at the appropriate times to test if this has any impact. It has no impact and the behavior is as I have described above.</p> <p><em>UPDATE 2013/12/5:</em> Removed HTML encoding and decoding. Was left over from previous attempt at problem solving.</p> <p><em>UPDATE 2013/12/5:</em> I don't have time to look into this today, but it occurred to me that perhaps the <code>[JsonIgnore]</code> attribute on the <code>SerializedSelf</code> property is the culprit and it's interfering with something in the MVC framework. Will look into as soon as I can and update.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COFirst problem your model contains logic. All logic should be in your controller. [Seperation of conerns](http://en.wikipedia.org/wiki/Separation_of_concerns). I reckon if you get this right your problem will go away.
      singulars
    2. CO@Liam, my model is specifically a view-model that is only used by the controller, and the logic is probably a gray area for separation of concerns. Regardless, it doesn't explain _why_ I am getting the behavior I am seeing. Property getters are simply specialized method calls and whether it's an auto-property, an explicitly field backed property, or a few lines of code with logic, it shouldn't be rendered differently in the two examples I gave. For completeness, I am converting SerializedSelf to an auto-property and doing the serialization/deserialization explicitly and see if this helps.
      singulars
    3. CO@Liam, removing the logic from `SerializedSelf` and converting it to an auto-property still results in the same behavior. If put in the `HiddenFor` I get the wrong result. If I explicitly code the hidden input and use `Model.SerializedSelf` I get the correct result. Literally no other changes in the code. It makes no sense. I am likely going to look into the MVC 5 source code and see what `HiddenFor` is doing.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload