【问题标题】:Persist values between multiple Posts在多个帖子之间保留值
【发布时间】:2016-10-04 14:18:26
【问题描述】:

您好,我无法在多个帖子中保留值,并且我的控制器中的“Post1”操作函数始终将 MyViewModelObj.Field2 设为 null 。我希望它在第二个帖子中保留旧值 如何使 MyViewModel 模型类对象保持值?

Mymodels.cs(模型)

namespace RetainTest.Models
{

    public class MyViewModel
    {

        public string Field1 { get; set; }
        public string Field2 { get; set; }
        public string Field3 { get; set; }
        public string Field4 { get; set; }
    }
}

RetainView.cshtml(视图)

@model RetainTest.Models.MyViewModel

@{
    ViewBag.Title = "RetainView";
}

<h2>RetainView</h2>


@using (Html.BeginForm("Post1", "Retain", FormMethod.Post,
                             new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()
    @Html.HiddenFor(model => model.Field1);
    @Html.HiddenFor(model => model.Field2);
    @Html.HiddenFor(model => model.Field3);
    @Html.HiddenFor(model => model.Field4);

    <div class="form-horizontal">
        <h4>MyViewModel</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Field1, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Field1, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Field1, "", new { @class = "text-danger" })
            </div>
        </div>

        @{ 
            if (  Model.Field2 == "Val2")
            { 

                <div class="form-group">
                    @Html.LabelFor(model => model.Field2, htmlAttributes: new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.EditorFor(model => model.Field2, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Field2, "", new { @class = "text-danger" })
                    </div>
                </div>

            }
        }
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

RetainController.cs(控制器)

namespace RetainTest.Models
{
    public class RetainController : Controller
    {
        // GET: Retain
        public ActionResult Index()
        {
            MyViewModel MyViewModelObj = new MyViewModel();

            MyViewModelObj.Field1 = "Val1";
            return View("RetainView", MyViewModelObj);
        }
        [HttpPost]
        public ActionResult Post1(MyViewModel MyViewModelObj)
        {
            if (string.IsNullOrEmpty(MyViewModelObj.Field2 ))
            {
                MyViewModelObj.Field2 = "Val2";
            }
            return View("RetainView", MyViewModelObj);
        }

    }
}

【问题讨论】:

  • 您的视图对模型的每个属性都有一个隐藏的输入。 DefaultModelBinder 读取请求中每个属性的第一个名称/值对并忽略所有其他属性。由于隐藏的输入是第一位的,因此您的 EditorFor() 方法的值将被忽略。您只绑定模型的初始值,而不是编辑的值(使您的表单毫无意义)。删除隐藏的输入!
  • MyViewModelObj.Field2 = "Val2"; 将什么也不做(请参阅this answer 的第二部分以获得解释)。如果要显示具有不同值的视图,请遵循 PRG 模式(或使用ModelState.Clear();
  • 感谢@StephenMuecke,删除这三个语句修复了它。 @Html.HiddenFor(model => model.Field1); @Html.HiddenFor(model => model.Field2); @Html.HiddenFor(model => model.Field3); @Html.HiddenFor(model => model.Field4);我虽然隐藏的价值是针对一篇文章,但我意识到它会永远保留它

标签: asp.net asp.net-mvc-4 razor


【解决方案1】:

试试这个:

namespace RetainTest.Models
{

    public class MyViewModel
    {
        [Required(ErrorMessage = "Field1 is required")]
        public string Field1 { get; set; }

        [Required(ErrorMessage = "Field2 is required")]
        public string Field2 { get; set; }

        public string Field3 { get; set; }

        public string Field4 { get; set; }
    }
}

@model RetainTest.Models.MyViewModel

@{
    ViewBag.Title = "RetainView";
}

<h2>RetainView</h2> 
@using (Html.BeginForm("Post1", "Retain", FormMethod.Post, new { id = "form", enctype = "multipart/form-data"}))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(model => model.Field1);
@Html.HiddenFor(model => model.Field2);
@Html.HiddenFor(model => model.Field3);
@Html.HiddenFor(model => model.Field4);

<div class="form-horizontal">
    <h4>MyViewModel</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        <Label for="Field1" class="control-label col-md-2">Field1 </label>
        <div class="col-md-10">
            @if(Model.Field1 == "Val1")
            {
                <input type="text" name="Field1" id="Field1" class="form-control" value="@Model.Field1">
            }
            else 
            {
                <input type="text" name="Field1" id="Field1" class="form-control">
            }
            <span class="field-validation-valid text-danger" 
                    data-valmsg-for="Field1" 
                    data-valmsg-replace="true">
            </span>
        </div>
    </div> 
    <div class="form-group">
        <Label for="Field2" class="control-label col-md-2">Field2 </label>
        <div class="col-md-10">
            @if(Model.Field2 == "Val2")
            {
                <input type="text" name="Field2" id="Field2" class="form-control" value="@Model.Field2">
            }
            else 
            {
                <input type="text" name="Field2" id="Field2" class="form-control">
            }
            <span class="field-validation-valid text-danger" 
                data-valmsg-for="Field2" 
                data-valmsg-replace="true">
            </span>
        </div>
    </div>              
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
     @Scripts.Render("~/bundles/jqueryval")
}


namespace RetainTest.Models
{
    public class RetainController : Controller
    {
        private MyViewModel MyViewModelObj = new MyViewModel();

        // GET
        public ActionResult Index()
        {       
            if (Session["MyObj"] != null)               
                MyViewModelObj = (MyViewModel)Session["MyObj"];             
            else 
                MyViewModelObj.Field1 = "Val1";             

            return View("RetainView", this);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult Post1(FormCollection form)
        {
            MyViewModelObj.Field1 = form.Get("Field1");
            MyViewModelObj.Field2 = form.Get("Field2");

            if (string.IsNullOrEmpty(MyViewModelObj.Field2))                
                MyViewModelObj.Field2 = "Val2";             

            // here you need to store the data somewhere! 
            // session, database.
            // just an example: 
            Session.Add("MyObj", MyViewModelObj);

            return View("RetainView", this);
        }
    }
}

我使用会话来保留对象的值,但还有其他一些方法可以存储数据。上面的代码会将用户输入发布到控制器并在会话中保留他的值。

【讨论】:

  • 谢谢@V.T.我没有尝试,但删除隐藏值修复了它
【解决方案2】:

得到斯蒂芬·穆克的回答

“您的视图对模型的每个属性都有一个隐藏输入。DefaultModelBinder 读取请求中每个属性的第一个名称/值对并忽略所有其他属性。由于隐藏输入是第一个,因此您的 EditorFor( ) 方法被忽略。你只绑定模型的初始值,而不是编辑的值(使你的表单变得毫无意义)。删除隐藏的输入!"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-10
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    相关资源
    最近更新 更多