tags:

views:

266

answers:

1

I'm working on a bit of MVC where I'm needing to dynamically route a form to a certain action and parameter combination. So far, I've got this:

PageViewModel
{
  public string Action {get;set;}
  public string Parameter {get;set;}
  /*... other properties for the form */
}

PageController
{
  public ViewResult MyAction(string myParamterName) {
    return View("CommonView", 
      new PageViewModel{Action="MyAction", Parameter="myParameterName"));
  }
  public ViewResult YourAction(string yourParamterName) {
    return View("CommonView", 
      new PageViewModel{Action="YourAction", Parameter="yourParameterName"));
  }
  /* ... and about 15 more of these */
}

CommonView.aspx:

<%-- ... --%>
<% using (Html.BeginForm(Model.Action,"PageController",FormMethod.Get)) {%>
    <%=Html.TextBox(Model.Parameter)%>
    <input id="submit" type="submit" value="Submit" />
<%}%>
<%-- ... --%>

This works, but it's got a lot of strings floating around to tell it where to go.

What I'd like to have is a type-safe way of defining the form parameters inside the view, but I'm a bit lost on how to accomplish this. Perhaps something that looks like this -

<% using (Html.BeginForm<PageController>(Model.??ExpressionToGetAction??)) {%>
    <%=Html.TextBox(Model.??ExpressionToGetParameter??)%>
    <input id="submit" type="submit" value="Submit" />
<%}%>

Or, is there a way to get the action and parameter used to generate this view, perhaps from route data?

Or should there be a custom routing scheme that can handle all of this automagically?

So, what I'm really wanting is the most elegant and type-safe way to accomplish this. Thanks!

EDIT

As Josh points out, the form will submit back to the action. This trims the code somewhat :

PageViewModel
{
  public string ParameterName {get;set;}
  /*... other properties for the form */
}

PageController
{
  public ViewResult MyAction(string myParamterName) {
    return View("CommonView", 
      new PageViewModel{ParameterName ="myParameterName"));
  }
  public ViewResult YourAction(string yourParamterName) {
    return View("CommonView", 
      new PageViewModel{ParameterName ="yourParameterName"));
  }
  /* ... and about 15 more of these */
}

CommonView.aspx:

<%-- ... --%>
<% using (Html.BeginForm(FormMethod.Get)) {%>
    <%=Html.TextBox(Model.ParameterName)%>
    <input id="submit" type="submit" value="Submit" />
<%}%>
<%-- ... --%>

It is still unclear how to have the textbox bind a parameter by name back to the action from which the view was created without explicitly specifying it.

A: 

Or, is there a way to get the action and parameter used to generate this view

If you leave the action and controller portion of the BeginForm arguments empty, it will to post back to where it came from. You can have two action with the same name, one decorated as HttpGet and the other HttpPost, as long as they have different parameters. Usually the get has one or none, and the post has several or a model bind.

Josh Pearce
Ah, good to know. Is there a way to get the action's parameter name as well, or some other way to bind the textbox to the parameter?
James Kolpack
What ever model you define in the action that returns the View will be THE Model, so I don't think it's necessary to do anything special.
Josh Pearce