tags:

views:

62

answers:

3

Hello everyone,

I am trying to figure out how to pass the model object from controller to view in a following scenario:

<% Html.Action("GetRequest", "The_Controller", new { requestId = 12 }); %>
<% Html.RenderPartial("Request", ViewData.Model); %>

The action should, and it does, call the controller's method which looks up the Request object in the DB repository and returns a Request object.

The partial view, named Request, should receive the request object and display it.

The problem is that the ViewData.Model is always null?!

I have tried to figure it out, but with no success :(

The reason for this behavior is that I need to display a partial view inside the jQuery's modal dialog based on the requestId value provided by the jQGrid. I have reached the point where I open the dialog but can't get that model object instance.

Any help is appreciated.

The solution - With the help of Nick Larsen and Darin Dimitrov

The controller:

    [AcceptVerbs(HttpVerbs.Post)]
    [Authorize]
    public PartialViewResult GetRequest(string requestId)
    {
        Request request = DatabaseContext.GetRequest(Convert.ToInt32(requestId)) as Request;
        return PartialView("Request", request);
    }

The view's Javascript:

function OpenRequest(requestId) {

        var methodName = '<%= Url.Content("~")%>' + 'Controller/GetRequest/';
        var dataType = "html";
        var postData = { requestId: requestId };
        var contentType = "application/x-www-form-urlencoded"; ;
        var request = ContactServer(methodName, postData, dataType, contentType);

        $("#dialog").html(request);
        $("#dialog").dialog({ html: request, title: 'Request details...', width: 800, height: 600, modal: true, zindex: 300000, show: 'scale', resizable: false });

    }
+1  A: 

It's better to set it up where your view does not call your controller. Load all of the data for the request in the action which calls this view and populate a view model with the needed data. Once you have that, render the fields from the model.

As for your actual problem. The action that calls this view in the first place populates the ViewData.Model for its context. When you call the action method, the framework is creating a new context with its own ViewData which you dont have access to without a handle to that newly created context.

NickLarsen
I see your point, however the initial view displays the jQGrid, hence I can't load all of the requests. The sample code used a hard coded value, i.e. requestId=12. In reality, the value is going to be passed via jQGrid's double click event, which will in turn open a modal dialog, which will in turn be injected with the <%RenderPartial...%> statement, which should display the desired data in a modal dialog. My problem revolves around how to pass an object from a controller to the partial view in a dynamic fashion :)
bignermo
Oh, I forgot, is there a way of accessing that newly created handle?
bignermo
There probably is but you probably shouldn't. If you're using jQGrid, load the data from the client on `jQuery().ready(...);`. Then you don't have to use this method at all. Here are a ton of examples: http://www.trirand.com/blog/jqgrid/jqgrid.html
NickLarsen
Thanks Nick, the examples at trirand.com do explain the master / detail with the jQGrid, however what I am trying to do is slightly different as I am not using the another gridview as a detail placeholder, but a partial view which I should display in a modal dialog. The jQuery solution with html injection could work but is not what I am after. I would like to preserve the MVC pattern.
bignermo
You still are preserving it. Just have your action return a partial view instead of a complete page reload. You have already written the partial view.
NickLarsen
A: 

It seems that you've got all the necessary information, up front, to create a 'Request' object in your initial controller action method.

Suggest that:

  • drop the <% Html.Action("GetRequest", "The_Controller", new { requestId = 12 }); %> altogether. We'll be prepopulating ViewData with all the data required to send to the Partial.

  • in your initial controller method, you create a new ViewData entry, perhaps ViewData["SomeRequest"]

  • prepopulate that as you need on the initial controller method, using requestId = 12 and email = "foo@bar", and all the other relevant pieces to create a 'Request' object, or whatever is needed in the Partial View named 'Request'.

    i.e. ViewData["SomeRequest"]= dbRepository.GetRequestById(intrequestId);

  • in your View, call Html.RenderPartial("Request", ViewData["SomeRequest"]);

p.campbell
Hi, I have changed the call to RenderPartial but the ViewData["SomeRequest"] is still null. However, the call <% Html.Action("GetRequest", "The_Controller", new { requestId = 12 }); %> does call the controller where I set the ViewData["SomeRequest"] = dbRepository.GetRequestById(intrequestId); The controller populates the ViewData but at that point where I need to call RenderPartial it is null :(
bignermo
Hi, your solution works but the answer is partially acceptable because the scenario is of a dynamic nature. Once I set the ViewData with the initial view, it is set to a request of a particular Id, which means it remains static. What I need is the way to retrieve the object in a dynamic way, i.e. when a user double clicks a jqGrid row, the requestId will change and that's when I was calling the Action method. The Id of 12 was just a demo value, that will be replaced with a variable.
bignermo
However one thing crosses my mind...I will try to have a jqGrid's doubleick event to call the controller and set the ViewData variable, which, I assume, should be available for passing to the partial view. I will be posting back the results tomorrow.
bignermo
+2  A: 

You could have the controller action return the partial view:

<%= Html.Action("GetRequest", "The_Controller", new { requestId = 12 }) %>

And in your controller action:

public ActionResult GetRequest(int requestId)
{
    var request = _repository.GetRequest(requestId);
    return PartialView("Request", request);
}

This way the GetRequest action will pass the request object to the strongly typed Request.ascx partial view and include it in the page at the place you called Html.Action helper.

Darin Dimitrov