This question is not about POST method, redisplaying view with submited form or binding input values to controller method parameters. It's purely about rendering the View using html helper (HiddenFor or Hidden - both returns the same).
I created a simple hidden field using HiddenFor
helper
@Html.HiddenFor(m => m.ProductCode)
and my problem is that value for this hidden field is rendered as null:
<input id="productCode" name="productCode" type="hidden" value/>
Even if I set it when instantiating a model and of course it's confirmed with debugging (it always has a value).
So instead it should look like this:
<input id="productCode" name="productCode" type="hidden" value="8888888"/>
Because I know there are some questions like this one (actually all of them refer to changing form values during form POST) I included list of things I tried already. My code is right below this section which I belive to be essential.
HiddenFor
helper, but pure html instead. WORKS, but its just workaround, not an answer to the problem.@Html.HiddenFor(m => m.ProductCode)
@Html.HiddenFor(m => m.ProductCode)
PARTIALLY WORKS Produces first input as value/>
and second as value="8888888"/>
which indicates that there is probably something that hides initial property value. Anyway, I found nothing in ViewData at any point, nor in query string. Obviously I can't accept it this way, no explonation needed I guess.
@Html.Hidden
instead of @Html.HiddenFor
. NO EFFECT, with name set as ProductCode it renders the same way.One more thing I found interesting. Reading html with Display page source in Chrome [ctrl+U] shows that value is valid value="8888888"/>
, but in DevTools it's still value/>
and of course submitting the form passes null to Controller method.
public class Product
{
public string Description { get; set; }
public int Quantity { get; set; }
public string ProductCode { get; set; }
public string ImageUrl { get; set; }
public Product(string desc, string productCode, string imgUrl)
{
Description = desc;
ProductCode = productCode;
ImageUrl = imgUrl;
}
}
@model Product
@using (Html.BeginForm("UpdateCart", "Cart"))
{
<div class="row pad10">
<div class="col-sm-6 text-center">
<img src="@Model.ImageUrl" width="300" height="300" />
</div>
<div class="col-sm-6 text-justify">
<p>@Model.Description</p>
<div class="row padding-top-2">
<div class="col-sm-6">
<label>@CommonResources.Quantity: </label>
</div>
<div class="col-sm-4">
@Html.TextBoxFor(m => m.Quantity, new
{
@class = "form-control",
@data_val_required = CommonResources.FieldRequired,
@data_val_number = CommonResources.ValidationNumber
})
@Html.ValidationMessageFor(model => model.Quantity, "", new { @class = "text-danger" })
@Html.HiddenFor(m => m.ProductCode)
</div>
</div>
</div>
</div>
<div class="text-center col-xs-12 padTop20 padBottom20">
<input type="submit" value="Submit" class="whtBtn pad" />
</div>
}
The view is returned from controller with RedirectToAction as follows:
ValidateAndProceed -> ResolveNextStep (here redirection occurs) -> ShowProduct
public ActionResult ValidateAndProceed()
{
var order = Session.Current.Order;
var lang = LangService.GetSelectedLanguage();
var invoice = Session.Current.CurrentInvoice;
var localCurrency = Session.Current.LocalCurrencyInfo;
List<CheckoutValidationFieldError> errors = new List<CheckoutValidationFieldError>();
errors = ValidationService.ValidateAddress(order);
if (errors.Count > 0)
{
return RedirectToAction("InvalidAddress", "Address", new { serializedErrors = JsonConvert.SerializeObject(errors) });
}
return ResolveNextStep(order, invoice);
}
public ActionResult ResolveNextStep(IOrder order, IInvoice invoice)
{
if (OrderService.ShowProductView(order, invoice))
{
return RedirectToAction("ShowProduct");
}
return RedirectToAction("Summary");
}
public ActionResult ShowProduct()
{
Product model = ProductService.GetProduct(Session.Current.CurrentInvoice);
return View("~/Views/Product.cshtml", model );
}
Finally, what can cause such a weird behavior? I've already ran out of options. Maybe anyone had problem like mine before, would appreciate any clue on this case.
I debugged the whole process of rendering the view (got into .Net sources) checking every possible place that could make it fail and found nothing.
After @AndyMudrak and @Jeremy Lakeman comments I decided to try again to find JavaScript responsible for that behavior, but deeper than I did before. What I found was a really silly script where element Id is being concatenated from three strings what I didn't expect, cause it's really badly implemented. So finally - JavaScript is doing it and there is no bad behavior from framework etc.
Actually I am a bit disappointed (even if it's good to know this easy answer) cause it looked much more complicated than it really was and it took me hours to find out how simple it is :|
Thanks for comments, sorry for final simplicity.