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

2009-11-13

Headers in JavaScript: Firefox vs others

Problem with a JS-heavy web application. Administrators have some extra controls, which should be visible if server sends “seeall” header with a value “True” (don’t worry, the actual check about using those controls is on server-side, this is just for visibility). It works fine in Firefox, but fails completely in IE and Chrome.

Everything looks completely legit in other browsers. The header exists and has the value “True”… but the comparison still fails.

In the end I found the issue – it seems that Chrome and IE do not strip \r (carriage return) control symbol from the header value string. This can be illustrated with the following pseudocode:

if (data.getResponseHeader['seeall'] == 'True') alert("True in Firefox");

if (data.getResponseHeader['seeall'] == 'True\r') alert("True in non-Firefox");
 
The quick’n’dirty solution? Compare just first four symbols…

2009-05-05

Validation of viewstate MAC failed: yet another reason & fix

Rubriigid: Programmeerimine — dukelupus @ 11:42:36

I was idly coding an ASP.NET MVC application – it worked fine, I was actually starting to understand how MVC works. Then I added a GridView to a view. And suddenly, BOOM, an error when debugging:

[HttpException (0x80004005): Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey> configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster.]

I was not on a Web Farm – and this error was completely new to me. So I hit the Internets… and got a load of answers. Most were related to GridView, indeed – namely, if a large page with GridView loads slowly, viewstate may not be completely loaded when user re-submits the form (see Validation of viewstate MAC failed error) and so forth.

But my page was tiny. Two edit fields, a drop-down and an empty GridView, that’s it. Not to mention, the issue was supposedly fixed in .NET 3.5 SP1, which I was using.

I tried various recommended solutions. I generated <machineKey> using <machineKey> Generator, I removed the GridView, I disabled event validation (<system.web> <pages enableViewStateMac="false" /> </system.web>), rebooted just in case… but no use.

I was getting desperate. But then I saw a comment to some forum post – make sure you don’t have two forms in one page. I knew I didn’t have two forms, but I checked my view anyway – and… for my surprise, there were two forms – HTML <form>..</form> tags around <% using (Html.BeginForm()) { } . How did that happen? I removed <form></form> – and everything worked fine.

I figured out what had happened – when I dragged’n'dropped GridView to a view, Visual Studio designer didn’t “see” a form on the page. So it added form around all the form controls it could find – in effect creating a form inside a form. I tried to add GridView again – and indeed, it added form tags again.

So, if you get this error, make sure you don’t have extra form tags on your page.

2009-03-13

How to scroll DataGrid programmatically in .NET CE?

It is easy to scroll the DataGrid in full .NET Framework:

GridVScrolled(this, new ScrollEventArgs(ScrollEventType.LargeIncrement, rowNum));

– or even easier, just use DataGridView and DataGridView.FirstDisplayedScrollingRowIndex() property.

However, in .NET Compact Edition there is no DataGridView – and no GridVScrolled. So there is no easy method to scroll a certain row to the view – but that is exactly what I needed: if the DataGrid is resized, selected row must remain to be visible.

So I ended up using System.Reflection to scroll my grid – or to be more exact, I derived my own class from DataGrid and added a method ScrollToRow():

using System.Reflection;
...
class BaseGrid : DataGrid {
 
/// <summary>
/// Scrolls datagrid to the row.
/// </summary>
/// <param name="rowNum">The row num.</param>
public void ScrollToRow(int rowNum)
{
  FieldInfo fi = this.GetType().GetField("m_sbVert", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
  ((VScrollBar)fi.GetValue(this)).Value = rowNum;
}
 
}

And then simply call baseGrid.ScrolToRow(baseGrid.CurrentRowIndex);

Järgmine lehekülg »

Blog at WordPress.com.