简体   繁体   中英

Issue sending data to PartialView C# MVC

I'm trying to build an inbox that is very similar to facebooks message inbox, where you have a list of conversations(I only want a list of a message title) and when you click the conversation or message title in my situation, I want the whole message to be rendered next to it in a partial view.

Here's my Inbox view:

@model BlocketProject.Models.ViewModels.ProfilePageViewModel
@{
ViewBag.Title = "Inbox";
}

<h2>Dina meddelanden:</h2><br />

<div class="left">
    <table id="messageTable">
        @foreach (var message in Model.UserMessages)
        {
            <tr>
                <td>
                    <button type="submit" class="messageButton">
                        @if (message.Unread == true)
                        {
                            <h4 style="font-weight:bold;">@message.MessageTitle</h4>
                        }
                        else if (message.Unread == false)
                        {
                            <h4>@message.MessageTitle</h4>
                        }

                    </button>
                </td>
            </tr>
        }
    </table>
</div>
<div class="right">

    @Html.Partial("ReadMessage")

</div>

When I click this message-element that is a button, I want to pass that messageId to the PartialView ReadMessage:

@model BlocketProject.Models.DbClasses.DbMessages


<h2>@Model.MessageTitle</h2><br />
<p>@Model.MessageText</p>

and the controller looks like this:

        [HttpPost]
    public ActionResult Inbox()
    {
        var allMessages =    ConnectionHelper.GetAllMessages(ConnectionHelper.GetUserByEmail(User.Identity.Name).UserId);
        var model = new ProfilePageViewModel();

        model.UserMessages = allMessages;

        return View("Inbox", model);

    }

    [HttpPost]
    public ActionResult ReadMessage(int messageId)
    {
        var model = ConnectionHelper.GetMessageByMessageId(messageId);
        return PartialView("ReadMessage", model);
    }

I've tried passing the messageId through a post as you can see in my controller, but then the partialView is returned as a new page and I simply want to render it in the Inbox view.

Any ideas?

EDIT: Jonesy's answer fixed my problem when I edited it like this:

Controller:

        public ActionResult ReadMessage(int messageId)
    {
        var model = ConnectionHelper.GetMessageByMessageId(messageId);
        return PartialView("ReadMessage", model);
    }

View:

<div class="left">
<table id="messageTable">
    @foreach (var message in Model.UserMessages)
    {
        <tr>
            <td>
                @using (Ajax.BeginForm("ReadMessage", new { @messageId = message.MessageId }, new AjaxOptions { UpdateTargetId = "showMessage" }, FormMethod.Post))
                {
                    <button type="submit" class="messageButton">
                        @if (message.Unread == true)
                        {
                            <h4 style="font-weight:bold;">@message.MessageTitle</h4>
                        }
                        else if (message.Unread == false)
                        {
                            <h4>@message.MessageTitle</h4>
                        }
                    </button>
                }
            </td>
        </tr>
    }
</table>
</div>
<div class="right" id="showMessage">
@Html.Partial("ReadMessage", new BlocketProject.Models.DbClasses.DbMessages())
</div>

Razor is run on the server, before the page is rendered. Once the page is on the client, and they can click a message, the concept of the PartialView is gone - it's all just one HTML page.

The easiest way for you to do this is to use an Ajax.BeginForm where your button is, and on click, update an element with a partial view retrieved from the server. Something like:

@using(Ajax.BeginForm("ReadMessage", "Messages", new AjaxOptions() { UpdateTargetId = "showMessage" })) {

//...

}

//...

<div class="right" id="showMessage">
    //ReadMessage partial rendered on button click
</div>

A little method that could help you :

protected ActionResult View(string viewName, object model)
{
    if (ControllerContext.IsChildAction)
        return PartialView(viewName, model);
    else if (Request.IsAjaxRequest())
        return PartialView(viewName, model);
    else
        return View(viewName, model);
}

This will return a PartialView when you call you action via @Html.RenderAction() or call the action via Ajax (jQuery).

You can then use jQuery to prevent the form to be posted and post it with Ajax or when you click on a message, you can also use jQuery to get the result from the action and insert it in your DOM.

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