I was creating some views where I used html for all my input fields instead of using the helper methods. I had some hidden fields that contained boolean values. I've done this often in MVC 3 and it was never a problem, but in MVC 4 Razor if the value of the boolen is true then it outputs the string "value" if the boolean is false then it completely removes the value attribute from the input.
I created a small test application using the basic webapplication template in VS2012,
ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace target45.ViewModels
{
public class IndexViewModel
{
public bool test1 { get; set; }
public bool test2 { get; set; }
public bool test3 { get; set; }
public bool test4 { get; set; }
}
}
Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using target45.ViewModels;
namespace target45.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
IndexViewModel model = new IndexViewModel()
{
test1 = true,
test2 = false,
test3 = true,
test4 = false
};
return View(model);
}
}
}
View:
@model target45.ViewModels.IndexViewModel
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
bool test = true;
}
<div>
<h2>test 1</h2>
<input type="hidden" value="@Model.test1" />
<input type="text" value="@Model.test2" />
<input type="password" value="@Model.test3" />
@Model.test4
@test
<input type="text" value="@test" />
<input type="text" value="@false" />
</div>
<div>
<!-- Shows that Razor acts correctly after invalid html -->
<h2>test 2</h2>
<" />
<input type="hidden" value="@Model.test1" />
<input type="text" value="@Model.test2" />
<input type="password" value="@Model.test3" />
@Model.test4
<input type="text" value="@test" />
<input type="text" value="@false" />
</div>
Outputted HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="/Content/site.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.5.3.js"></script>
</head>
<body>
<div>
<h2>test 1</h2>
<input type="hidden" value="value" />
<input type="text" />
<input type="password" value="value" />
False
True
<input type="text" value="value" />
<input type="text" />
</div>
<div>
<h2>test 2</h2>
<" />
<input type="hidden" value="True" />
<input type="text" value="False" />
<input type="password" value="True" />
False
<input type="text" value="True" />
<input type="text" value="False" />
</div>
<script src="/Scripts/jquery-1.7.1.js"></script>
</body>
</html>
I forgot to mention, in my second test I add an error to the html, after doing that Razor outputs the correct values.
I originally submitted this under the old project page: http://aspnet.codeplex.com/workitem/10320
but I realized it probably belongs here.
Comments: I knew I'd read this somewhere, and I recently rediscovered Andrew Nurses' blog post on this feature: http://vibrantcode.com/blog/2012/4/10/whats-new-in-razor-v2.html/ Seems that what Razor is doing is correct in that it's functioning as intended (i.e. if a boolean evaluates to true, the attribute name is rendered again as the attribute value). This makes perfect sense if you're rendering a checkbox and need to set it's checked value: ``` <input type=”checkbox” checked=”@isChecked”> ``` And I'm also aware that the Razor parser will ignore attributes that have the "data-" prefix, however, the rendering of the attributes name as it's value sill makes no sense for other attributes that might realistically need to contain the value of "true" or "false".
I created a small test application using the basic webapplication template in VS2012,
ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace target45.ViewModels
{
public class IndexViewModel
{
public bool test1 { get; set; }
public bool test2 { get; set; }
public bool test3 { get; set; }
public bool test4 { get; set; }
}
}
Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using target45.ViewModels;
namespace target45.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
IndexViewModel model = new IndexViewModel()
{
test1 = true,
test2 = false,
test3 = true,
test4 = false
};
return View(model);
}
}
}
View:
@model target45.ViewModels.IndexViewModel
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
bool test = true;
}
<div>
<h2>test 1</h2>
<input type="hidden" value="@Model.test1" />
<input type="text" value="@Model.test2" />
<input type="password" value="@Model.test3" />
@Model.test4
@test
<input type="text" value="@test" />
<input type="text" value="@false" />
</div>
<div>
<!-- Shows that Razor acts correctly after invalid html -->
<h2>test 2</h2>
<" />
<input type="hidden" value="@Model.test1" />
<input type="text" value="@Model.test2" />
<input type="password" value="@Model.test3" />
@Model.test4
<input type="text" value="@test" />
<input type="text" value="@false" />
</div>
Outputted HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="/Content/site.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.5.3.js"></script>
</head>
<body>
<div>
<h2>test 1</h2>
<input type="hidden" value="value" />
<input type="text" />
<input type="password" value="value" />
False
True
<input type="text" value="value" />
<input type="text" />
</div>
<div>
<h2>test 2</h2>
<" />
<input type="hidden" value="True" />
<input type="text" value="False" />
<input type="password" value="True" />
False
<input type="text" value="True" />
<input type="text" value="False" />
</div>
<script src="/Scripts/jquery-1.7.1.js"></script>
</body>
</html>
I forgot to mention, in my second test I add an error to the html, after doing that Razor outputs the correct values.
I originally submitted this under the old project page: http://aspnet.codeplex.com/workitem/10320
but I realized it probably belongs here.
Comments: I knew I'd read this somewhere, and I recently rediscovered Andrew Nurses' blog post on this feature: http://vibrantcode.com/blog/2012/4/10/whats-new-in-razor-v2.html/ Seems that what Razor is doing is correct in that it's functioning as intended (i.e. if a boolean evaluates to true, the attribute name is rendered again as the attribute value). This makes perfect sense if you're rendering a checkbox and need to set it's checked value: ``` <input type=”checkbox” checked=”@isChecked”> ``` And I'm also aware that the Razor parser will ignore attributes that have the "data-" prefix, however, the rendering of the attributes name as it's value sill makes no sense for other attributes that might realistically need to contain the value of "true" or "false".