发布忽略模型更改 Razor ASP.NET

ign*_*zzo 5 c# asp.net asp.net-mvc razor asp.net-mvc-4

我有一个控制器,它返回一个带有模型的局部视图。

包含局部视图的视图有一个按钮,当点击按钮时,控制器的一个函数被调用,它返回与模型更新相同的局部视图。新模型加载没有任何问题,但页面没有重新加载,视图与 onclik 之前的视图相同。

局部视图代码

<div class="well">
    @if (publication.Coments != null) {
         foreach (var comments in publication.Coments) {
             <div class="row">
                  <div class="col-md-12">
                       <a href="../../Client/ProfilePerNick?nick=@comments.Nick">@comments.Nick</a>
                       <span class="pull-right">@comments.DateComment.ToShortDateString()</span>
                       <p>@comments.Message</p>
                   </div>
              </div>
         }
    }
</div>
Run Code Online (Sandbox Code Playgroud)

控制器的方法使用下一个代码返回局部视图:

   ViewData["publication"] = publication;
   return PartialView("details_comment");
Run Code Online (Sandbox Code Playgroud)

我在视图中调用局部视图:

 @Html.Partial("../Home/ListPublication")
Run Code Online (Sandbox Code Playgroud)

我调试了页面,模型重新加载正常,但部分视图没有重新加载。

Mil*_*Joe 4

我在评论中提到我遇到了同样的问题,但今天晚些时候我在 MSDN 上发现,如果您POST. 对于我的场景,我必须ModelState.Clear()在更改返回视图模型上的任何值之前使用。为了更好地解释,我将尝试尽可能贴近地描述我的案例,并尝试结合上下文:

查看模型

// ~/Models/SomeFeatureModels.cs
public class SomeViewModel {
    public int Id {get;set;}
    public string SomeField{get;set;}
    public string SomeOtherField{get;set;}
    public DateTime CreatedOn{get;set;}
}
public class SomeOtherViewModel {
    public int Id {get;set;}
    public string SomeField{get;set;}
    public string SomeOtherField{get;set;}
    public DateTime CreatedOn{get;set;}
}
public class IndexViewModel {
    public string FeatureTitle{get;set;}
}
Run Code Online (Sandbox Code Playgroud)

模板

<!-- ~/Views/Some/SomeInfo.cshtml -->
@model.App.Models.SomeInfoViewModel
@using(Html.BeginForm("AddSomeInfo", "Some", FormMethod.Post, new { @id="frmAddSomeInfo" }) {
  <div id="some-info">
    @Html.DisplayFor(m=>m.SomeField)
    @Html.EditorFor(m=>m.SomeField)
    @Html.ValidatorFor...
    <input type="submit">Go</input>
  </div>
}

<!-- ~/Views/Some/SomeInfo.cshtml -->
@model.App.Models.SomeOtherInfoViewModel 
@using(Html.BeginForm("AddSomeOtherInfo", "Some", FormMethod.Post, new { @id="frmAddSomeOtherInfo" }) {
  <div id="some-other-info">
    @Html.DisplayFor(m=>m.SomeField)
    @Html.EditorFor(m=>m.SomeField)
    @Html.ValidatorFor...
    <input type="submit">Go</input>
  </div>
}

<!-- ~/Views/Some/Index.cshtml -->
@model App.Models.IndexViewModel
@{
   layout: "someLayout.cshtml"
}
<h2>Model.FeatureTitle</h2>

@{ RenderAction("SomeInfo") }
@{ RenderAction("SomeOtherInfo") }

@section scripts {
//bundle must include:
// jquery, jquery.unobtrusive.ajax, jquery.validate, jquery.validate.unobtrusive
<script>
    $(function() {
        $('#frmAddSomeInfo').submit(function(e) {

            e.preventDefault(); 

            var form = $(this);
            if (form.valid()) {
                $.ajax({
                    url: form.action,
                    type: form.method,
                    data: form.serialize()
                }).done(function(payload) {
                    $('#some-info').html(payload);
                }).fail(function(jqXHR, error, errorThrown) {
                    // handle
                });
            }
        });

        $('#frmAddSomeOtherInfo').submit(function(e) {

            e.preventDefault(); 

            var form = $(this);
            if (form.valid()) {
                $.ajax({
                    url: form.action,
                    type: form.method,
                    data: form.serialize()
                }).done(function(payload) {
                    $('#some-other-info').html(payload);
                }).fail(function(jqXHR, error, errorThrown) {
                    // handle
                });
            }
        });
    });
</script>
}
Run Code Online (Sandbox Code Playgroud)

控制器

// ~/Controllers/SomeController.cs
public class SomeController: Controller {
    // This would be the landing view of a given controller
    public ActionResult Index() {
        // for this view model I have basically typed the things that 
        // are a concern of Index, like page title and other things
        // but nothing related to the view models that I will be
        // updating or inserting
        var viewModel = somePrivateMethodToBuildMyViewModel();
        return View(viewModel);
    }

    public PartialViewResult SomeInfo() {
        // this is technically a fresh instance with normalized
        // or localized default data that I will be sending 
        // when the index requests this partial view
        var someViewModel = somePrivateMethodToBuildSomeViewModel();
        return PartialView(someViewModel);
    }

    [HttpPost]
    public PartialViewResult AddSomeInfo(SomeViewModel viewModel) {
        // this is where I am checking if my view model is alright
        // and then the "issue" will occur
        if (!ModelState.IsValid) {
            // ... handle  
        } else { 
            // I was doing "normal stuff" like 
            // translating view model to an entity (let's call it model)
            // committing changes with some ORM and get and id and timestamp back
            // and naturally assign these values to the view model 

            viewModel.Id = model.id;
            viewModel.createdOn = model.created_on; 
        }
        // then return the same view and same model **types** of the request
        return PartialView("SomeInfo", viewModel);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我必须使用的部分ModelState.Clear()。我已将我的POST操作更改为:

// ~/Controllers/SomeController.cs
public class SomeController: Controller {

    // ...        

    [HttpPost]
    public PartialViewResult AddSomeInfo(SomeViewModel viewModel) { 
        if (!ModelState.IsValid) {
            // ... handle  
        } else {  

            // Included this line for valid model state handling
            ModelState.Clear();

            // then persist, etc

            // then change view model
            viewModel.Id = model.id;
            viewModel.createdOn = model.created_on; 
        }
        // then returning the view model to the same partial should now work
        return PartialView("SomeInfo", viewModel);
    }
}
Run Code Online (Sandbox Code Playgroud)

抱歉,这有点太多了,但我只是想展示我如何让它在我的场景中发挥作用。