【问题标题】:Pass entity, from view to controller传递实体,从视图到控制器
【发布时间】:2014-02-25 12:04:22
【问题描述】:

在我看来,这就是我所拥有的

        @foreach (var match in Model.CommonMatches)
        {
            <tr>

                <td>@match.StartDateTime</td>
                <td>@match.EndDateTime</td>
                <td>@match.AvailableAttendees.Count()</td>
                <td>@Html.ActionLink("Accept", "AcceptAppointment", "Appointment", new {commonMatch = @match })</td>
            </tr>
        }

Model.CommonMatches 的类型为 List&lt;Window&gt;

public class Window
{
    public DateTime StartDateTime { get; set; }
    public DateTime EndDateTime { get; set; }
    public IEnumerable<DataModels.Attendee> AvailableAttendees { get; set; }

}

这是从控制器传递值的方式

[HttpGet]
public ActionResult ViewStatus(Guid appointmentId)
{
    var status = new ViewStatus
    {
        AttendeesWhoResponded = _appointmentRepository.GetAppointmentDetails(appointmentId).Attendees.Where(a=>a.HasResponded == true).ToList(),
        NotAttending = _appointmentRepository.GetAppointmentDetails(appointmentId).Attendees.Where(a=>a.HasResponded == true && a.Responses == null).ToList(),
        CommonMatches = _appointmentRepository.FindCommonMatches(appointmentId)
    };
    return View(status);
}

ViewStatus 类

public class ViewStatus
{
    public ViewStatus()
    {
        AttendeesWhoResponded = new List<DataModels.Attendee>();
        NotAttending = new List<DataModels.Attendee>();
    }
    public List<DataModels.Attendee> AttendeesWhoResponded { get; set; }

    public List<DataModels.Attendee> NotAttending { get; set; }
    public IEnumerable<Window> CommonMatches { get; set; }
}

view的ActionLink正在调用的控制器中的动作是:

[HttpGet]
public ActionResult AcceptAppointment(Window commonMatch)
{
    return Content("ac");
}

当我在控制器的操作中检查commonMatch 的值时。我得到了StartDateTimeEndDateTime,但我没有得到AvailableAttendees 的所有价值。目前显示为null

我期待的可用参加者是IEnumerable&lt;Attendee&gt; 类型。是不是不能以我传递的方式传递对象?

我应该怎么做才能在控制器中同时获取 AvailableAttendees 的所有值以及日期?

编辑 1:

<table class ="table-hover table-striped">
    <thead>
        <tr>
            <td>Start time</td>
            <td>End time</td>
            <td>Number of Attendees</td>
        </tr>
    </thead>


            @for (var count = 0; count < Model.CommonMatches.Count();count++ )
            {
                using (Html.BeginForm("AcceptAppointment", "Appointment", FormMethod.Post))
                {
                    <tr>
                        <td>@Model.CommonMatches[count].StartDateTime</td>
                        <td>@Model.CommonMatches[count].EndDateTime</td>
                        <td>@Model.CommonMatches[count].AvailableAttendees.Count()</td>
                        @*<td>@Html.ActionLink("Accept", "AcceptAppointment", "Appointment", new { commonMatch = @match })</td>*@


                    @for(var j=0;j<Model.CommonMatches[count].AvailableAttendees.Count();j++)
                    {
                        <td>@Model.CommonMatches[count].AvailableAttendees[j].FirstName</td>//to check if the value is null or not, just a test
                        <td>@Html.HiddenFor(m=>Model.CommonMatches[count].AvailableAttendees[j].FirstName)</td>
                        <td>@Html.HiddenFor(m=>Model.CommonMatches[count].AvailableAttendees[j].LastName)</td>
                        <td>@Html.HiddenFor(m=>Model.CommonMatches[count].AvailableAttendees[j].Email)</td>
                        <td>@Html.HiddenFor(m=>Model.CommonMatches[count].AvailableAttendees[j].AttendeeId)</td>
                    }
                        <td><input type="submit" value="Accept"/></td>
                     </tr>

                }
            }


</table>

【问题讨论】:

  • 你是如何从控制器传递模型的?
  • @Andrei 有问题地添加了它。所有值都传递给视图。我可以在浏览器中看到值。
  • 如果您没有包含 availableAttendee 但想使用延迟加载,您应该将 virtual 添加到 IEnumerable
  • @S4NDERR 在将对象从视图传递到控制器时是否也有效?
  • @Biplov13 我想我现在明白你的问题了,类似的问题在这里:stackoverflow.com/questions/16321736/…

标签: c# javascript jquery asp.net asp.net-mvc


【解决方案1】:

您需要将模型发回,这将涉及将您的控制器方法更改为:

控制器

[HttpPost]
public ActionResult AcceptAppointment(List<Window> model)
{
    return Content("ac");
}

查看

您的视图需要一个表单和一个提交按钮,而不是ActionLink。我已将表格格式取出以简化以下内容。

使用 for 循环索引您的集合,以便模型绑定器知道如何处理它们,这实际上是两个循环,因为它是集合中的集合。隐藏的值也必须被渲染才能被回发(请原谅任何错别字)。

@for(var i = 0; i < Model.CommonMatches.Count; i ++)
{
            <div>
                @using (Html.BeginForm("AcceptAppointment", "Appointment", FormMethod.Post)
                {
                @Html.HiddenFor(m => Model.CommonMatches[i].StartDateTime)
                @Html.HiddenFor(m => Model.CommonMatches[i].EndDateTime)
                @Model.CommonMatches[i].StartDateTime <br/>
                @Model.CommonMatches[i].EndDateTime <br/>

                @for(var j = 0; Model.CommonMatches[i].AvailableAttendees.Count; j++)
                {
                      @Html.HiddenFor(m => Model.CommonMatches[i].AvailableAttendees[j].Prop1)<br/>
                      @Html.HiddenFor(m => Model.CommonMatches[i].AvailableAttendees[j].Prop2)<br/>
                }

                 <input type="submit" value="Accept" />
        </div>
        }
}

【讨论】:

  • 我认为这会起作用,但我需要找到如何在表格中添加&lt;input&gt; 标签。现在它说不可能在表内有 标记。你有什么想法吗?
  • @Biplov13, &lt;input&gt; 不能是&lt;table&gt; 的直系子级。但可以在&lt;td&gt;
  • @Murali 所以我需要为 标签创建一个 标签,隐藏值怎么样,它们也需要在 内吗?因为我现在没有得到任何数据。
  • @Biplov13 是的,它们都可以在 的内部。
  • 出于某种奇怪的原因,在控制器中显示AvailableAttendees Count = 0 我尝试检查该属性是否包含值,并发现它确实包含该值。
【解决方案2】:

有很多事情需要注意

<td>@Html.ActionLink("Accept", "AcceptAppointment", "Appointment", new {commonMatch = @match })</td>

来电

[HttpGet]
public ActionResult AcceptAppointment(Window commonMatch)
{
    return Content("ac");
}

您在此处使用链接&lt;a href&gt; 进行导航。基本上你正在发出一个获取请求。在获取请求中,您只能通过Query String 将数据传递给服务器。但是您的情况,在导航到 url 之前动态准备查询字符串有点复杂。但是您可以使用 onclick=prepareHref(this) 之类的 JavaScript 来做到这一点;

@Html.ActionLink("Accept", "AcceptAppointment", "Appointment", 
  new {commonMatch = @match }, new {onclick=prepareHref(this)})

然后在Javascript中

function prepareHref(obj)
{
 var qsData="?StartDateTime='2014-02-25'&EndDateTime='2014-02-25'&AvailableAttendees[0].prop1=value1, etc"; // data should be obtained from other td elements
 obj.href=obj.href+qsData;
}

但这不是建议的做法。

如果你想打开其他页面并显示 url,最好传递 id 并再次加载数据。

选项 1:

如@hutchonoid 所解释的,更好的方法是在隐藏字段中提交详细信息。

选项 2:

或在 jQuery ajax $.post 方法中提交详细信息。无论哪种方式,您都需要使用POST

@Html.ActionLink("Accept", "AcceptAppointment", "Appointment", 
  new {commonMatch = @match }, new {onclick=postMyData()})


function postMyData(){
    var postData={};
    postData.StartDateTime='';
    postData.EndDateTime='';
    postData.AvailableAttendees=[];
    //for each AvailableAttendees prepare object
    postData.AvailableAttendees[0]= {};
    postData.AvailableAttendees[0].prop1=value1;



    $.post('/Appointment/AcceptAppointment/',{data:postData},function(data){

    });
    return false;
}

[HttpPost]
public ActionResult AcceptAppointment(Window commonMatch)
{
    return Content("ac");
}

【讨论】:

  • 你能看到我的问题中的编辑吗?现在在控制器中显示AvailableAttendees count=0
猜你喜欢
相关资源
最近更新 更多
热门标签