开发者

Is there a bug with input type="image" in Internet Explorer

I'm using IE9 (rtm) at the moment and I am wondering if this is an issue of my own doing or a bug in Internet Explorer 9.

I'm using ASP.NET MVC the form controller is defined as:

[HttpPost()]  
[UrlRoute(Path = "Checkout/Cart")]  
public ActionResult Cart(ShoppingCartModel cart, string submitButton)

All browsers will cause this method to be hit on post back. The input type is detailed as:

<input type="image" src="/resources/images/removeselected.png" class="rightButton removeSelected" alt="Remove Selected" name="submitButton" value="<%= Html.Encode(Model.REMOVE_SELECTED) %>" />

And here is what is posted back with the form:

Chrome: CartId=241&submitButton.x=83&submitButton.y=12&submitButton=removeSelected&Items%5B0%5D.Selected=true&Items%5B0%5D.Selected=false&Items%5B0%5D.OrderItemId=76&Items%5B0%5D.Prod开发者_StackOverflowuct.ID=9611&Items%5B0%5D.Quantity=1

Internet Explorer 9: CartId=244&Items%5B0%5D.Selected=true&Items%5B0%5D.Selected=false&Items%5B0%5D.OrderItemId=77&Items%5B0%5D.Product.ID=10091&Items%5B0%5D.Quantity=1&submitButton.x=27&submitButton.y=8

As you can see, Chrome is putting in the submitButton=removeSelected and IE isn't. It works fine in Firefox, also.

If I change it to &lt;input type="submit"&gt; it works without an issue. However, I want to use an IMAGE type


According to the specification:

When a pointing device is used to click on the image, the form is submitted and the click coordinates passed to the server. The x value is measured in pixels from the left of the image, and the y value in pixels from the top of the image. The submitted data includes name.x=x-value and name.y=y-value where "name" is the value of the name attribute, and x-value and y-value are the x and y coordinate values, respectively.

You cannot expect more. IE doesn't send submitButton=removeSelected, yes, but there is nothing that obliges is to do so according to the spec. So you should not rely on this parameter. The fact that other browsers are sending it is probably just an implementation detail (on which of course you shouldn't rely).

As a workaround use a normal submit button and try styling it with CSS.


Here's how I got around this; hopefully someone else might find my solution helpful.

The message signature changes; the parameters are a list of all the various form button names. Chrome / FF will fill in these names so you won't need to parse it.

[HttpPost()]
[UrlRoute(Path = "Checkout/Cart")]
public ActionResult Cart(ShoppingCartModel cart, string removeSelected, string nextButton)
{
    if (removeSelected == ShoppingCartModel.REMOVE_SELECTED)
        removeOp = true;
    else if (nextButton == ShoppingCartModel.NEXT_BUTTON)
        nextOp = true;
    else
    {
        PostbackButtonParser parser = new PostbackButtonParser(HttpContext.Request.InputStream, new string[] { ShoppingCartModel.NEXT_BUTTON, ShoppingCartModel.REMOVE_SELECTED });

        if (parser.PostbackButtonName == ShoppingCartModel.NEXT_BUTTON)
            nextOp = true;
        else if (parser.PostbackButtonName == ShoppingCartModel.REMOVE_SELECTED)
            removeOp = true;
     }

    if(removeOp) { /* do something */ }
    else if (nextOp) { /* do something */ }
}

Then the code to the PostbackButtonParser is fairly straight forward:

/// <summary>
/// Implements a fallback rollover for Internet Explorer and other browsers which don't send the value with an INPUT TYPE="IMAGE" submit.
/// </summary>
/// <example>
/// PostbackButtonParser parser = new PostbackButtonParser(HttpContext.Request.InputStream, new string[] { "button1", "button2" });
/// if(parser.PostbackButtonName == "button1") {
///     // do something
/// }
/// else if (parser.PostbackButtonName == "button2" {
///     // do something else
/// }
/// </example>
/// <remarks>See http://stackoverflow.com/questions/5716260/is-there-a-bug-with-input-type-image-in-internet-explorer</remarks>
public class PostbackButtonParser
{
    /// <summary>
    /// Gets the name of the button which caused the postback.
    /// </summary>
    public string PostbackButtonName
    {
        get;
        private set;
    }

    /// <summary>
    /// Creates a new instance of the postback button parser
    /// </summary>
    /// <param name="requestStream">The stream to process</param>
    /// <param name="buttonNames">An array of button names to evaluate gainst</param>
    public PostbackButtonParser(Stream requestStream, string[] buttonNames)
    {
        byte[] stream = new byte[requestStream.Length];
        requestStream.Read(stream, 0, stream.Length);
        string contents = System.Text.Encoding.ASCII.GetString(stream);

        for (int i = 0; i < buttonNames.Length; i++)
        {
            // Set first match
            if (contents.Contains(buttonNames[i] + ".x") && contents.Contains(buttonNames[i] + ".y"))
            {
                PostbackButtonName = buttonNames[i];
                break;
            }
        }
    }
}

I really hope this helps someone; I spent a few hours on what really should have been trivial. What Darin said is very true, I could have styled a but I would rather have used the image type, just for semantics.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜