【问题标题】:Ajax postback partialview not getting loaded with updated imageAjax 回发部分视图未加载更新的图像
【发布时间】:2013-08-07 18:47:37
【问题描述】:

我正在尝试使用部分视图创建示例 MVC4 网页

在我的父页面,例如,Index.cshtml 页面上,我正在显示一个允许用户查看/更新个人资料照片的 partialView 页面

当索引页面加载时,如果有照片,我需要这个部分页面来显示照片

一旦页面加载完毕,当用户上传新照片时,我只需要partialView页面进行ajax回发并显示新照片。

我可以使用从数据库中获取的照片加载页面, 我可以通过单击“#btnPhotoUpload”按钮将新照片保存到数据库。 但是保存照片后,部分视图没有自动刷新。请帮助我如何让我的部分视图页面刷新并显示更新的照片。

这是我的索引页面,即“Index.cshtml”

@model MvcSamples.Models.ViewModels.UserInfoViewModel
@{

    ViewBag.Title = "Ajax Partial Postback demo";
    ViewBag.UserId = 1;
}

<h2>PersonalInfo example</h2>
<div id="photoForm">
    @Html.Partial("_UserPhoto")
</div>
<div id="OtherDetails">
    @Html.Partial("_UserDetails")
</div>

这是我的 PartialView,即 _UserPhoto.cshtml

@model MvcSamples.Models.ViewModels.UserInfoViewModel
@using (Ajax.BeginForm("SaveProfilePhoto", "Example", new { id = "1" }, new AjaxOptions { UpdateTargetId = "photoForm", OnSuccess = "onSuccess" }, new { encType = "multipart/form-data" }))
{ 
    @Html.AntiForgeryToken() 
    @Html.ValidationSummary(true) 
    <a>
        <img id="imgPhoto"  width="100px" height="100px"/>
        <label for="photo">Photo:</label>
        <input type="file" name="photo" id="photo" />
      <input id="btnPhotoUpload" type="button" value="Apply" />
    </a>

    <script type="text/javascript">
        $(document).ready(function () {

            $("#imgPhoto").attr('src', "@Url.Action("GetProfileImage", "Example", new { id = ViewBag.UserId })");

            $("#btnPhotoUpload").click(function (event) {
                //on-click code goes in here.
                event.preventDefault();
                SavePhotoToDb();

            });

            function SavePhotoToDb() {
                var json;
                var data;
                $.ajax({
                    type: "POST",
                    url: "/Example/SaveProfilePhoto",
                    data: new FormData($("#form0").get(0)),
                    dataType: "html",
                    contentType: false,
                    processData: false,
                    success: saveItemCompleted(data),
                    error: saveItemFailed
                });
            }

            function saveItemCompleted(data) {
                    $("#photoForm").html(data);
        }

        function saveItemFailed(request, status, error) {
            }
        });
    </script>
}

这是我的控制器 ExampleController:

namespace MvcSamples.Controllers
{
    public class ExampleController : Controller
    {
        IUserDetails usr = new UserDetails();

        // GET: /Example/
        [HttpGet]
        public ActionResult Index()
        {
            //usr.GetProfilePhoto(WebSecurity.GetUserId(User.Identity.Name));
            if (!string.IsNullOrWhiteSpace(User.Identity.Name))
            {
                ViewBag.UserId = WebSecurity.GetUserId(User.Identity.Name);
            }

            UserInfoViewModel model = new UserInfoViewModel();
            model.GenderList = usr.FillGenderTypesDropDownList();
            return View(model);
        }


        [HttpPost]
        public ActionResult SaveProfilePhoto(HttpPostedFileBase photo, UserInfoViewModel model)
        {
            string path = @"C:\Temp\";
            if (photo != null)
            {
                model.UserId = 1;//WebSecurity.GetUserId(User.Identity.Name);
                ViewBag.UserId = model.UserId;
                var binary = new byte[photo.ContentLength];
                photo.InputStream.Read(binary, 0, photo.ContentLength);
                UserPicModel upModel = new UserPicModel();
                upModel.UserPhoto = binary;
                upModel.UserId = model.UserId;
                usr.InsertProfilePhoto(upModel);

            }

            return PartialView("_UserPhoto", model); 
        }

        public FileResult GetProfileImage(int id)
        {
            byte[] barrImg = usr.GetProfilePhoto(id);
            return File(barrImg, "image/png");
        }

    }
}

更新:

正如@David Tansey 建议的那样,我在 SaveCompleted(data) 中添加了刷新图像的代码。

function RefreshImage() {
    $("#imgPhoto").attr('src', function () {
        // the datetime portion appended to the url avoids caching issues
        // and ensures that a fresh image will be loaded every time
        var d = new Date();

        return this.src + '?' + d.getTime();
    });
}

但上面的代码只有在我点击两次上传按钮后才会刷新图像。 实际上我需要在$("#btnPhotoUpload").click 之后立即刷新图像。有什么建议吗?

我也尝试在控制器上禁用缓存,但没有成功:

[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]

【问题讨论】:

    标签: c# jquery asp.net-mvc-4 razor


    【解决方案1】:

    我很确定问题在于浏览器正在缓存图像文件,并且在您上传新文件后没有“感知”到需要再次通过网络传输它。

    查看以下帖子,了解如何附加虚拟(但动态)查询字符串值以防止发生缓存。我认为这种方法可以解决您的问题。

    asp.net mvc jquery filling image

    希望对您有所帮助。

    【讨论】:

    • 按照您的建议,我添加了用于刷新图像的代码。但这只有在我单击两次上传按钮后才会刷新。实际上我需要在 $("#btnPhotoUpload") 之后立即刷新图像。点击任何建议?
    • 我认为这是因为第一次在 $(document).ready() 内“填充”IMG 控件(设置了 src 值)它没有虚拟查询字符串值。除了RefreshImage() 功能,您可以尝试在src 的第一个设置之后放置您拥有的单行代码吗?因此,您将有两条连续的行,它们都以$("#imgPhoto").attr('src' 开头... 第一个带有Url.Action,第二个带有动态查询字符串函数。那么我认为您将避免显式刷新图像。
    • 我试过了,但没有运气。我还注意到,如果我只是在“var d = new Date();”之后添加一个警报在触发警报期间正在加载新图像。但是如果我删除警报,则不会加载更新的图像。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多