Question

I've got an <input type='image'> in an ASP.NET MVC view, but I'm not sure how to retrieve the coordinates in the action that runs when the form is submitted. The requested URL looks like

/Map/View/?map.x=156&map.y=196

but I can't just do

public ActionResult View( int map.x, int map.y )
{
  ...
}

because they're obviously not valid names for C# method parameters. Is there any equivalent of the ActionName attribute to map query parameters to method parameters?

Was it helpful?

Solution

You have to use use Model binder and set the prefix property to "map":

First create the Model object:

public class ImageMap()
{
  public int x{get;set;}
  public int y{get;set;}
}

And in your action method:

public ActionResult About([Bind(Prefix="map")]ImageMap map)
{

   // do whatever you want here
    var xCord = map.x;

}

OTHER TIPS

To answer your question directly, you can change the field which is used on a parameter by using [Bind]:

public ActionResult View([Bind(Prefix="map.x")] int x, 
    [Bind(Prefix="map.y")] int y )

However, a custom ModelBinder that bound an image map to a System.Drawing.Point struct would be nicer.

Edit: Here is an ImageMapBinder that automatically maps to a System.Drawing.Point argument. You don't have to decorate each Point argument with an attribute as long as you add the following code to your Application_Start:

ModelBinders.Binders.Add(typeof(Point), new ImageMapBinder());

Though you can still rename the input using [Bind(Prefix="NotTheParameterName")] if you want to.

The code for ImageMapBinder is as follows:

public class ImageMapBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, 
        ModelBindingContext bindingContext)
    {
        int x, y;

        if (!(ParseValue(bindingContext, "x", out x) &&
            ParseValue(bindingContext, "y", out y)))
        {
            return Point.Empty;
        }

        return new Point(x, y);
    }

    private bool ParseValue(ModelBindingContext bindingContext, string value, 
        out int outValue)
    {
        string key = String.Concat(bindingContext.ModelName, ".", value);

        ValueProviderResult result = bindingContext.ValueProvider[key];

        if (result == null)
        {
            outValue = 0;
            return false;
        }

        return ParseResult(result, out outValue);
    }

    private bool ParseResult(ValueProviderResult result, out int outValue)
    {
        if (result.RawValue == null)
        {
            outValue = 0;
            return false;
        }

        string value = (result.RawValue is string[])
            ? ((string[])result.RawValue)[0]
            : result.AttemptedValue;

        return Int32.TryParse(value, out outValue);
    }
}

You could make a class like this:

public class ImageMap()
{
  public int x{get;set;}
  public int y{get;set;}
}

and then use that as a parameter for your action method

public ActionResult View(ImageMap map)
{
  ...
}

Try IModelBinders. See this, this and this question.

You can try an entirely different approach and build up your image map using the code provided in the following link.

http://www.avantprime.com/articles/view-article/9/asp.net-mvc-image-map-helper

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top