…meie igapäevast IT’d anna meile igapäev…

2011-06-27

ASP.NET MVC: Simple checkbox extension

Filed under: ASP.NET MVC — Sander @ 13:41:00
Tags: ,

As you may or may not have noticed, ASP.NET MVC checkbox implementation is just bad. In addition of regular <input type="checkbox".. it will render secondary hidden input, ” so that an unselected check box will return false”. This is supposed “make it easy to bind to view data or model data”. Considering how forums are full of people asking why their checkboxes misbehave, I’d say it is fairly safe to claim they failed.

I got tired of writing <input type=”checkbox” name=”mycheckbox” id=”mycheckbox” /> every time I needed a “normal”, checkbox, so I wrote a set SimpleTextbox extensions for InputExtensions (Html.SimpleTextbox()):

public static class SimpleCheckboxHelper
{
  public static MvcHtmlString SimpleCheckbox(this HtmlHelper helper, string name)
  {
    return SimpleCheckbox(helper, name, false, null);
  }

  public static MvcHtmlString SimpleCheckbox(this HtmlHelper helper, string name, bool @checked)
  {
    return SimpleCheckbox(helper, name, @checked, null);
  }

  public static MvcHtmlString SimpleCheckbox(this HtmlHelper helper, string name, bool @checked, object htmlAttributes)
  {
    return SimpleCheckbox(helper, name, @checked, new RouteValueDictionary(htmlAttributes));
  }

  public static MvcHtmlString SimpleCheckbox(this HtmlHelper helper, string name, bool @checked, IDictionary<String, Object> htmlAttributes)
  {
    string attributes = string.Empty;
    if (htmlAttributes != null && htmlAttributes.Count > 0)
      attributes = htmlAttributes.Aggregate(attributes, (current, htmlAttribute) => current + string.Format(" {0}=\"{1}\"", htmlAttribute.Key, htmlAttribute.Value));

    var s = string.Format("<input type=\"checkbox\" name=\"{0}\" id=\"{0}\"{1}{2}/>", name, @checked ? " checked=\"checked\"" : string.Empty, attributes);
    return new MvcHtmlString(s);
  }
}

(code formatted with http://quickhighlighter.com/code-syntax-highlighter.php, as I cannot currently use my normal utilities)

Using SimpleCheckbox is same as using normal ASP.NET MVC checkbox:

  • @Html.SimpleCheckbox(“Active”) – renders normal checkbox, not checked.
  • @Html.SimpleCheckbox(“Active”, Model.Active) – checked if Model.Active is true, unchecked if not.
  • @Html.SimpleCheckbox(“Active”, Model.Active, new { @class = “mycheckboxclass” }) – adds CSS class (or other attributes) to the checkbox.

2011-05-12

ASP.NET MVC: Enum binding helper

Filed under: ASP.NET MVC — Sander @ 12:32:01
Tags: ,

Binding enums in the modelbinder is a just bit different than other values, so I wrote another small method for enums into my BinderHelper:

public T GetEnum<T>(string keyName, T defaultValue) where T : struct
{
	if (string.IsNullOrEmpty(ValueCollection[keyName]))
		return defaultValue;  
	var value = ValueCollection[keyName];   
	Enum.TryParse(value, true, out defaultValue);
	return defaultValue;
}

ValueCollection is a NameValueCollection, like described in the BinderHelper post linked above.

Using it is simple:

myModel.EnumValue = _binder.GetEnum("EnumValue", MyEnum.DefaultValue);

2011-05-10

ASP.NET MVC: JSON string too long – a solution

Filed under: ASP.NET MVC — Sander @ 11:33:53
Tags: , ,

asp.net.mvc.logo

If you get the InvalidOperationException:

Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.

when trying to serialize data to JSON representation, then most likely you are doing something wrong. AJAX is not meant to move large amounts of data – rethink your application!

However, sometimes the limit is too low – in my case, a web service test application for the client, so they could test their own web services before claiming they are ready. One of the services gives quite a lot of data – and the test app needed to show the data as XML as well, so the actual JSON size was 26MB (as a sidenote, both Chrome and Firefox 4 crashed while parsing the data – surprisingly, IE9 was the only browser which didn’t).

I tried the Web.config approach described on various pages (1, 2), but that didn’t help. Then I realized – they are talking about “plain” ASP.NET, not ASP.NET MVC. So, I tried not returning Json(myBigData), but created my own serializer, setting the data size limit to int.MaxValue (var serializer = new JavaScriptSerializer {MaxJsonLength = Int32.MaxValue};) and then used it to serialize the return data: return new JsonResult { Data = serializer.Serialize(myBigData) };

But I still got the same exception. Apparently the JsonResult does checking of its own – so, the actual solution is not to return JsonResult, but ContentResult:

public ActionResult MyFancyMethod()
{
	var serializer = new JavaScriptSerializer { MaxJsonLength = Int32.MaxValue };
	var result = new ContentResult
	{
		Content = serializer.Serialize(myBigData),
		ContentType = "application/json"
	};
	return result;
}

And there, 26MB returned as JSON without any issues. An alternative approach would be to write the JSON directly to the output (Response.Clear(); Response.ContentType = “application/json”; Response.Write(serializer.Serialize(myBigData);).

Järgmine lehekülg »

Blog at WordPress.com.