加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – MVC4将复杂对象从View传递到Controller,新视图不

发布时间:2020-12-16 07:17:04 所属栏目:asp.Net 来源:网络整理
导读:我是MVC的新手,在尝试将现有网站移植到MVC4时遇到了这个问题. 我们使用的模型中大部分数据都是由服务调用填充的,所以显然我们希望将调用保持在最低限度.问题是,当我尝试将模型传递回控制器时,模型中的复杂对象总是变为空.我已经能够使用ajax将数据保留在回调
我是MVC的新手,在尝试将现有网站移植到MVC4时遇到了这个问题.

我们使用的模型中大部分数据都是由服务调用填充的,所以显然我们希望将调用保持在最低限度.问题是,当我尝试将模型传递回控制器时,模型中的复杂对象总是变为空.我已经能够使用ajax将数据保留在回调控制器上;但是,我需要操作来返回一个新视图,并且在操作完成后,视图的代码会执行,但是没有重定向(我认为这是ajax的重点,我认为我要求的是一个解决方案将以相同的方式持久保存数据但实际重定向).

这是我的模型:

public class DistributionModel
{
    public string typeOfDistribution { get; set; }
    public Document document { get; set; }
    public string thumbnailUrl { get; set; }
    public MergeFieldModel mergeFields { get; set; }
}

public class MergeFieldModel
{
    public MergeFields documentMergeFields { get; set; }
}

这是我正在使用的控制器操作:

public ActionResult Index(DistributionModel distributionModel)
    {
        distributionModel.mergeFields = new MergeFieldModel() { documentMergeFields = MergeFieldsHelper.GetDocumentMergeFields(distributionModel.document.Id) };
        return View("Index",distributionModel);
    }

我尝试使用href =@Url.Action(“Index”,Model)而不是下面块中的按钮来调用控制器并执行重定向(重定向本身确实有效,但我必须在其中执行另一个服务调用控制器检索与我在调用视图中使用的文档相同的文档)因为模型中的Document对象保持返回为控制器的NULL.

以下是调用控制器并实际返回完整模型的视图部分:我认为我正在寻找的是一种在没有ajax的情况下实现此目的的方法,以便我可以获得重定向到分发/索引页面(这是从Distribution / DocumentDetails页面中触发)

<button id="EmailDistribution" data-corners="false" data-theme="a">EMAIL</button>

         $('#EmailDistribution').click(function () {
              var model = @Html.Raw(Json.Encode(Model));
              $.ajax({
              url: '@Url.Action("Index","Distribution")',type: 'POST',contentType: 'application/json; charset=utf-8',data: JSON.stringify(model),processData: false,});                
         });

谢谢,任何帮助将非常感谢.

解决方法

我不确定我是否完全理解你的问题,但我可以告诉你,你需要将模型的每一个值都放在一个表格中,并发布到你想要不为空的控制器动作中.

这正是您在ajax调用中所做的:您当前将整个模型转换为json并使用jQuery功能将其再次转换为发布数据.假设您有以下模型,例如:

public class TestModel {
    public string A { get; set; }
    public string B { get; set; }
}

您的javascript代码将创建一个类似于{A:’值为’,B:’值为B’}的字符串,它将使用jQuery转换为HTTP POST请求:

POST /Controller/Index HTTP/1.1
Host: demo.loc
User-Agent: Mozilla/5.0 whatever
Content-Type: application/x-www-form-urlencoded; charset=utf-8

A=Value+for+a&B=Value+for+B

因此,将调用Index操作,DefaultModelBinder将值绑定到模型属性.这适用于整数类型,如整数,也适用于复杂类型,例如集合. DefaultModelBinder处理这些类型的转换.

让我们来看看更复杂的模型:

public class ComplexSubModel {
    public ICollection<string> StringList { get; set; }
}

public class ComplexModel {
    public ComplexSubModel SubModel { get; set; }
}

DefaultModelBinder还能够绑定以下模型:

POST /Controller/Index HTTP/1.1
Host: demo.loc
User-Agent: Mozilla/5.0 whatever
Content-Type: application/x-www-form-urlencoded; charset=utf-8

ComplexModel.SubModel.StringList[0]=First+entry&ComplexModel.SubModel.StringList[1]=Second+entry&ComplexModel.SubModel.StringList[2]=Third+entry

这将导致ComplexModel的新实例,其SubModel属性设置为ComplexSubModel的新实例,其属性StringList设置为System.Collection.Generic.List< string>的新实例.包含三个字符串第一个条目,第二个条目和第三个条目

现在您需要做的是将模型属性渲染为隐藏字段,以便它们包含在回发中:

@using (Html.BeginForm()) {
    @Html.HiddenFor(m => m.SubModel.StringList[0])
    @Html.HiddenFor(m => m.SubModel.StringList[1])
    @Html.HiddenFor(m => m.SubModel.StringList[2])
}

回发中包含的每个属性都不会为空,但可能是由用户伪造的,因为它们很容易重新传输到服务器,假设它们是在隐藏字段中呈现的.实际上,您无法确定重新传输的值是您之前通过服务调用获取的值.

另一种可能性是将服务调用的结果保存在TempData字典中,该字典实际上将值存储在用户会话中,并在回发操作中重新读取它们时将其销毁,或者直接将值存储在会议:

public ActionResult Index() {
    // Do service calls

    #region Variant a
    TempData["ServiceResultA"] = foo;
    TempData["ServiceResultB"] = bar;
    #endregion

    #region Variant b
    Session["ServiceResultA"] = foo;
    Session["ServiceResultB"] = bar;
    #endregion

    var model = new DistributionModel();
    // Set properties and stuff

    return View("Index",model);
}

[HttpPost]
public ActionResult Index(DistributionModel model) {
    // Read "cached" service calls

    #region Variant a
    var foo = (TResultA)TempData["ServiceResultA"];
    var bar = (TResultB)TempData["ServiceResultB"];
    #endregion

    #region Variant b
    var foo = (TResultA)Session["ServiceResultA"];
    var bar = (TResultB)Session["ServiceResultB"];
    #endregion

    // Do stuff

    return RedirectToAction(...);
}

这两种变体都有优点和缺点,比如在一个浏览器会话中浏览两个选项卡时可能会出现问题,或者在使用会话状态服务器时需要将类序列化.然而,程序总是一样的:你要么必须这样做

>每次从服务中获取数据时获取数据(价格昂贵)或
>将它们保存在服务器上的任何位置(TempData,Session和stuff)或者其他
>使用表单提交(可以由用户伪造,并不总是很容易).

选择你的毒药.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读