简体   繁体   中英

Passing values between View and Controller in MVC 2

I'm constantly confused about how to pass values between Views and Controllers in MVC. I know I can set ViewData in the Controller and use that in the View, but what about the other way around?

What I have found is I can use a hidden field and then access it through Request.Form["name"] like this:

<% using (Html.BeginForm("Upload", "Customers", FormMethod.Post, new { enctype = "multipart/form-data" }))
   {%>
<br />
<input id="currentDir" type="hidden" name="currentDir" value="" />
<input type="file" name="fileTextbox" id="fileTextbox" />
<br />
<br />
<input type="submit" value="Send" />
<% } %>

What complicates it even more is that the value originally comes from a jquery script, so that's why the input field was the only way I could think of. But it still feels wrong... Maybe it isn't but I'd basically like to know if there are other more "proper" established ways to pass values between the View and Controller (both ways). Should one use querystrings instead? If so, how would they look in the html.beginform htmlhelper?

Also, what I'm trying to do here is enable upload possibilities for my application. And I'm trying to make the whole application as "Ajaxy" as possible. But this form will make a complete post. Is there another way to do this and not have to reload the entire page for this upload?

Let's ignore the "AJAX-y" aspects for a moment (because that's a different issue) and just look at passing data between views and controllers. I would first recommend that you check out the NerdDinner Tutorial which provides some good insights into how MVC works and how you use some of the features of MVC.

To address your specific question of how data is passed from View to Controller and back, there are a few ways to do this. However, the one that tends to make sense to most people is the idea of using strongly-typed views.

Let's say you have a model called Person. For now, don't worry about how we store Person data - we just have a Person class in the Models folder inside your MVC project.

public class Person {

  public string FirstName;
  public string LastName;

  public Person() {
    FirstName = "John";
    LastName = "Doe";
  }
}

When we want to display data about Person in a View, we make a request to a specific controller. In this case (and for clarity) we'll call this controller the MainController. This will go in the Controllers folder and will be called MainController. Let's call the Action (an action is really just a specialized method) we want to get data from Index. Due to how ASP.NET MVC routing works, the path to our server will be: http://localhost/Main/Index . Notice the Controller (minus the "Controller" name), and the Action make up the path. (The first part is your server name, of course.)

Let's look at your controller - I'm going to keep it very simple for now:

public class MainController : Controller {

  public ActionResult Index() {
    Person person = new Person();
    return View(person);
  }
}

What we have going on inside the Index Action is that it is returning a View (which, by default, has the same name as the Action) and a model to correspond with that view. Now, we have to create our view.

The important part here is that you want to strongly-type the model that is being returned in the controller to your view. You do that with this line (which is first in your aspx file).

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewUserControl<Project.Namespace.Person>" %>

Notice the "Inherits" attribute and notice that your Person model makes up that attribute.

Now, just code the rest of your view as normal. Let's say we want to display the current Person name, and allow someone to change the name. The page would look like this (I'm not making this pretty):

<% using (Html.BeginForm()) { %>
  <%: Html.LabelFor(model => model.FirstName) %>
  <%: Html.TextBoxFor(model => model.FirstName) %>
  <%: Html.LabelFor(model => model.LastName) %>
  <%: Html.TextBoxFor(model => model.LastName) %>

  <input type="submit" value="Submit" name="submitButton" />
<% } %>

This is the important part about getting data back and forth between Controllers and Views. What we are doing here is that we are taking your strongly-typed view (which is typed with the Person class) and using helper methods (like LabelFor and TextBoxFor) to tie the model together with its data and, ultimately, together with the actions contained in the controller (which we have to finish developing here in one moment).

So, you can now see the data. But, if a user changes the name and clicks submit - we want the page to display the new name. This means we need to add one more action to MainController - the one that receives the data.

[HttpPost]
public ActionResult Index(Person person) {
  // Do whatever you want with the Person model. Update a database, or whatever.
  return View(person);
}

This action looks very similar to the other action we just developed. However, this one takes a person object (from the form that is being submitted) and it gives the controller an opportunity to do whatever needs to be done with that object. Once this is done, you can choose to redirect to a different page, redisplay the page (useful if there are errors), or do any number of other things.

Again, this is ALL covered (and much more) in the NerdDinner Tutorial . I highly recommend you read and follow through that.

As for the AJAX-y aspects you discussed, the premise is still the same (although there is a little bit of JavaScript/jQuery work that goes on in there). I won't go into it now, but the basics are also covered in the NerdDinner tutorial .

I hope this gets you started. I remember being a bit confused too when I first started working with web technologies, so I hope this helps you out!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM