views:

108

answers:

2

What I'm trying to do is rather basic, but I might have my facts mixed up. I have a details page that has a custom class as it's Model. The custom class uses 2 custom objects with yet another custom object a property of one of the 2. The details page outputs a fair amount of information, but allows the user to post a comment. When the user clicks the post button, the page gets posted to a Details action that looks something like this:

        [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Details(VideoDetailModel vidAndComment) { ....}

The only fields on the form that is posted are CommentText and VideoId. Here is what the VideoDetailModel looks like.

public class VideoDetailModel
{
    public VideoDetailModel()
    {
        Video = new VideoDTO();
        Comment = new CommentDTO();
    }

    public VideoDetailModel(VideoDTO vid)
    {
        Video = vid;
        Comment = new CommentDTO();
    }

    public VideoDTO Video { get; set; }
    public CommentDTO Comment { get; set; }
}

VideoDTO has a few properties, but the ones I need are VideoId. CommentDTO's pertinent properties include CommentText (which is posting correctly) and a UserDTO object that contains a userId property. Everything other than the CommentText value is not being posted. I also have the following line on the ascx page, but the model value never gets posted to the controller.

Html.Hidden("Model.Video.VideoId", Model.Video.VideoId);       

I'm really not sure what I'm missing here. I suppose if I added more form fields for the properties I need, they would get posted, but I only need 1 form entry field for the CommentText. If I could get the same Model objects value that were sent to the page to post with the page, that would help.

I'll be happy to make any clarifications needed here. I'm just at loss as to what's going on.

UPDATE

Okay, it looks like the solution is rather simple. I think using the RenderPartial in the middle of a form is problematic somehow to how the form gets written in html. I can't really put my finger on why things went bonkers, but if I do my RenderPartials before my form and then begin my form with the text entry field and the hidden VideoId, the default ModelBinder works just fine. I was beginning the form, writing the hidden VideoId, rendering several partial views, create my CommentText field, and then closed the form out. The CommentText field would get bound just fine. The hidden VideoId would not. Maybe I missed a rule somewhere about using RenderPartial.

For completeness, the partial view I was rendering took a Comment object and just wrote out it's CommentText data. Several of these objects would exist for a single Video object. All of this data was in a custom type and passed into the View (the main view) as it's Model. This partial view did not have a form and did not have any data entry fields.

A: 

Is there any Model Binding Security implemented in your mvc site? To explain what I mean, take a look at this page and read the section near the end titled "Model Binding Security". Note that this can be within your code OR in your global.asax file.

Jaxidian
A: 

I'd need to see more of your view page code to really give a thorough answer here but for the one snippet you posted:

Html.Hidden("Model.Video.VideoId", Model.Video.VideoId);

Should really be:

Html.Hidden("Video.VideoId", Model.Video.VideoId);

or

Html.Hidden("vidAndComment.Video.VideoId", Model.Video.VideoId);

Either way will work but I tend to prefer the first if your controller action only takes a single parameter. The default model binder will be (in your example) looking for a method parameter named "Model" or failing that will look for a property "Model" on your VideoDetailsModel class. Since neither of those exist, it can't bind "Model.Video.VideoId" to anything.

David Archer
I tried this and it did not work. It's very odd, really. When I check request.Form in debug mode, it seems as though the hidden value is not getting posted at all. It only see the Comment.CommentText field as being submitted. I haven't changed the parameter to a FormCollection just to see what would be returned. I'll try that later this evening.
Jason
Might seem obvious but is the Html.Hidden() call within the actual form? :) Do you see the hidden INPUT field in the generated HTML inside the form?
David Archer
This was part of the problem, but not all of it. I've chosen this response b/c it most closely answers my question.
Jason