views:

1450

answers:

4

Okay so, i am totally new to MVC and I'm trying to wrap my head around a few of the concepts. I've created a small application...

This application has a view for creating a new Individual record. The view is bound to a model ViewPage... And I have a associated IndividualController which has a New method...

The New method of the IndividualController looks like this...

public ActionResult New()
    {
        var i = new Individual();

        this.Title = "Create new individual...";
        i.Id = Guid.NewGuid();

        this.ViewData.Model = new Individual();


        return View();
    }

Now, the above all seems to be working. When the view loads I am able to retrieve the data from the Individual object. The issue comes into play when I try and save the data back through the controller...

In my IndividualController I also have a Save method which accepts an incoming parameter of type Individual. The method looks like...

   public ActionResult Save(IndividualService.Individual Individual)
    {
        return RedirectToAction("New");
    }

Now, on my view I wanted to use a standard html link/href to be used as the "Save" button so I defined an ActionLink like so...

 <%=Html.ActionLink("Save", "Save") %>

Also, defined in my view I have created a single textbox to hold the first name as a test like so...

 <% using (Html.BeginForm()) { %>
     <%=Html.TextBox("FirstName", ViewData.Model.FirstName)%>
 <% } %>

So, if I put a break point in the Save method and click the "Save" link in my view the break point is hit within my controller. The issue is that the input parameter of the Save method is null; even if I type a value into the first name textbox...

Obviously I am doing something completely wrong. Can someone set me straight...

Thanks in advance...

+1  A: 

Your New controller method doesn't need to create an individual, you probably just want it to set the title and return the view, although you may need to do some authorization processing. Here's an example from one of my projects:

    [AcceptVerbs( HttpVerbs.Get )]
    [Authorization( Roles = "SuperUser, EditEvent, EditMasterEvent")]
    public ActionResult New()
    {
        ViewData["Title"] = "New Event";
        if (this.IsMasterEditAllowed())
        {
            ViewData["ShowNewMaster"] = "true";
        }

        return View();
    }

Your Save action should take the inputs from the form and create a new model instance and persist it. My example is a little more complex than what I'd like to post here so I'll try and simplify it. Note that I'm using a FormCollection rather than using model binding, but you should be able to get that to work, too.

    [AcceptVerbs( HttpVerbs.Post )]
    [Authorization( Roles = "SuperUser, EditEvent, EditMasterEvent")]
    public ActionResult Save( FormCollection form )
    {
         using (DataContext context = ...)
         {
              Event evt = new Event();
              if (!TryUpdateModel( evt, new [] { "EventName", "CategoryID", ... }))
              {
                  this.ModelState.AddModelError( "Could not update model..." );
                  return View("New");  // back to display errors...
              }
              context.InsertOnSubmit( evt );
              context.SubmitChanges();
              return RedirectToAction( "Show", "Event", new { id = evt.EventID } );
         }
    }
tvanfosson
A: 

If I don't create a new Indvidual object in the New method then when my view tries to bind the textbox to the associated model I get a NullReferenceException on the below line in my view...

`<%=Html.TextBox("FirstName", ViewData.Model.FirstName)%>`

With regards to the Save method. From what I understand since my view is strongly typed shouldn't I be able to have a method signature like...

   `public ActionResult New(IndividualService.Individual ind)
    {
        return View();
    }`

I thought that was the purpose behind model binding..?

Jason
Jason, could you read the document on using markdown in SO. http://stackoverflow.com/editing-help, you are indenting code and delimiting it with `. Use ` for keywords embedded in normal paragraph text. For code samples you need only indent 4 spaces.
AnthonyWJones
Also note SO is not a forum or newsgroup. Most people read answers to questions in order of votes hence any use of answers to continue conversation is doomed. If want to comment on an answer use the add comments feature.
AnthonyWJones
A: 

Okay... I was able to get what I was trying to do to work with a standard Html submit button... But... I can't get the data back to the controller when I try using a ActionLink...

I assume this is because a ActionLink is simply a href and not causing a form submission...

Thoughts..? help..!

Jason
A: 

I would strongly recommend that you take a step back from what you are doing and run through some of the Tutorials/Videos here http://www.asp.net/learn/

If you have a strongly typed View it means that when the Controller picks that view to generate the output the view has better access to the Model.

However the View is not responsible for what comes back from the client subsequently such as when a form is posted or a URL is otherwise navigated to.

ASP.NET-MVC uses information in the URL to determine which Controller to hand the request off to. After that it's the controller's responsibility to resolve the various other elements in the request into instance(s) of Model classes.

The relationship between the incoming request and the controller is clouded by the significant assistance the ASP.NET-MVC routing gives the controller. For example a route can be defined to supply parameters to the controller method and thats all the controller needs and hence you don't see any code in the method relating to the http request. However it should be understood that the contoller method is simply processing a http request.

I hope you can see from the above that it would be too early in a requests life-cycle for an instance of a class from the model to passed to a public method on a controller. Its up to the controller to determine which model classes if any need instancing.

AnthonyWJones