MVC 4.5&从VIEW发布到Controller的淘汰赛 - 模型为空

时间:2014-02-07 23:48:45

标签: c# asp.net-mvc knockout.js knockout-2.0

我正在模拟按钮点击和启动画面。您可以运行此代码并看到它几乎可以工作。

我的观点如下:

@model MvcApplication1.Models.ReportModel
@using Newtonsoft.Json;

@{
    ViewBag.Title = "Home Page";
 }
@section featured {


<div id="divLoading" style="margin: 0px; padding: 0px; position: fixed; right: 0px;
top: 0px; width: 100%; height: 100%; background-color: #666666; z-index: 30001;
opacity: .8; filter: alpha(opacity=70);display:none">
<p style="position: absolute; top: 30%; left: 45%; color: White;">
    Running reports, please wait...<img src="../../Images/ajax-loading.gif">
</p>

<section class="featured">
    <div class="content-wrapper">
        <hgroup class="title">
            <h1>@ViewBag.Title.</h1>
            <h2>@ViewBag.Message</h2>
        </hgroup>

        <div id="inputContainer">

        </div>

        <div id="reportContainer">
            Run report
            <span data-bind="text: Date"></span>


            <table>
                <tr style="font-weight:bold">

                    <td>
                        Report Name
                    </td>
                    <td>
                        Number Of Rows
                    </td>
                    <td>
                       Has Data
                    </td>
                    <td>
                        Result Message
                    </td>
                    <td>
                        Check
                    </td>
                </tr>

                <tbody data-bind="foreach: Report">
                    <tr>
                        <td> <span data-bind="text: ReportName"></span></td>
                        <td><span data-bind="text: NumberOfRows"></span></td>
                        <td><span data-bind="text: HasData"></span></td>
                        <td><span data-bind="text: ResultMessage"></span></td>
                        <td><input type="checkbox" data-bind="checked: checkBox"></td>
                    </tr>
                 </tbody>

        </table>            
        </div>

    </div>
</section>

}

<button onclick="JavascriptFunction();">HTTPPost Button</button>
@section scripts {
<script type="text/javascript" src="~/Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript" src="~/Scripts/knockout-2.2.0.js"></script>
<script type="text/javascript" language="javascript">

    //SET INITIAL VALUES ON PAGE WITH KNOCKOUT
    @*var initialModel = new KOViewModel(@Html.Raw(Json.Encode(Model)));*@
    var initialModel =   @Html.Raw(JsonConvert.SerializeObject(Model));
    @*var initialModel2 = @Html.Raw(JsonConvert.DeserializeObject(Model.ToString()))*@
    //SET THE KNOCKOUT OBSERVABLES
    var viewmodel =
      {
           Date: ko.observable(initialModel.Date),
          Report: ko.observableArray(initialModel.ReportList)
       };

        //FUNCTION TO SHOW A LOADING SCREEN
        function JavascriptFunction() {
            var url = '@Url.Action("PostMethod", "Home")';
            $("#divLoading").show();

            var postModel = {
                ReportDate: viewmodel.Date(),
                ReportList: viewmodel.Report()
            };

            $.post(url, postModel, function (res) {
                $("#divLoading").fadeOut(100);
                viewmodel.Date(res.ReportDate);
                viewmodel.Report(res.ReportList);
            }, "json");
        }

//APPLY KNOCKOUT BINDINGS
$(document).ready(function() {
   ko.applyBindings(new viewmodel);

    });
</script>
    }

我的课程看起来像:

        public class ReportModel
    {
        public string ReportDate { get; set; }
       public List<Common.Rep> ReportList { get; set; }
    }

public class Rep
{
    public string ReportName { get; set; }
    public int NumberOfRows { get; set; }
    public string HasData { get; set; }
    public bool checkBox { get; set; }
    public string ResultMessage { get; set; }
}

我的控制器看起来像:

此方法有效:

    public ActionResult Index()
    {
        var model = new ReportModel();
        model.ReportDate = "1/31/2014";
        model.ReportList = new List<Models.Common.Rep>();
        //add a report
        model.ReportList.Add(
              new Models.Common.Rep()
            {
                ReportName = "test report",
                NumberOfRows = 50,
                HasData = "Yes",
                checkBox = false,
                ResultMessage = "Message"
            });
        model.ReportList.Add(

            //add another report
     new Models.Common.Rep()
     {
         ReportName = "test report 2",
         NumberOfRows = 50,
         HasData = "Yes 2",
         checkBox = false,
         ResultMessage = "Message 2"
     });

        return View(model);
    }

我的问题是,使用以下方法,模型是全为空。

   [HttpPost]
    public JsonResult PostMethod(ReportModel model)
    {
        System.Threading.Thread.Sleep(1000);
        model.ReportDate = "1/31/2014";
        foreach (var row in model.ReportList)
        {
            row.ReportName = "TSET TSET TSETLKJAKL:GJGH";
        }

        return Json(model); 
    }

知道为什么要传递模型:   [HttpPost]         public JsonResult PostMethod(ReportModel model)

是NULL吗?有什么需要改变这条线 $ .post(url,postModel,function(res)....

谢谢你!

1 个答案:

答案 0 :(得分:7)

您的问题是您希望post一个JSON字符串,但jQuery的$.post尝试将该数据发送为application/x-www-form-urlencoded,这不是您的控制器所期望的。请记住,$.post的第三个参数指定了您希望接收响应的格式,而不是发送的格式请求 in。

您需要使用$.ajax代替,以便正确设置内容类型:

        $.ajax({
          type: 'POST',
          url: url,
          contentType: 'application/json',
          data: ko.toJSON( postModel),
          dataType: 'json',
          success: function (res) {
            $("#divLoading").fadeOut(100);
            viewmodel.Date(res.ReportDate);
            viewmodel.Report(res.ReportList);
          }
        });