我的博客中有一个带有局部视图的侧边栏,可让用户注册我的电子邮件新闻源。我想要做的是在发布一些数据后将用户返回到他们来自的页面,并在表单的部分视图中显示任何验证或返回消息。
问题是我的局部视图在新窗口中打开(没有布局)。我如何解决这个问题,以便返回我的博客,并在de sidebar中返回数据?
这是我的观点:
@using Blog.Models.Entities
@model Subscriber
<header>
<h2>Subscribe</h2>
</header>
<p>Subscribe to my e-mail newsfeed.</p>
@using (Html.BeginForm("Form", "Subscription"))
{
<div class="editor-label">@Html.LabelFor(subscriber => subscriber.Email)</div>
<div class="editor-field ">@Html.EditorFor(subscriber => subscriber.Email)</div>
@Html.ValidationMessageFor(subscriber => subscriber.Email)
<input type="submit" value="Subscribe" />
<p>@ViewBag.Result</p>
}
正在处理数据的相关控制器:
public ActionResult Form()
{
return PartialView("_Form");
}
[HttpPost]
public ActionResult Form(Subscriber subscriber)
{
if (ModelState.IsValid)
{
Subscriber foundSubscriber = _repository.Subscribers.Where(s => s.Email.Equals(subscriber.Email)).FirstOrDefault();
if (foundSubscriber != null)
{
ModelState.AddModelError("Email", "This e-mail address has already been added.");
return PartialView("_Form", subscriber);
}
_repository.SaveSubscriber(subscriber);
ViewBag.Result = "Succesfully subscribed to the newsletter.";
return PartialView("_Form");
}
ModelState.AddModelError("Email", "Please provide a valid e-mail address.");
return PartialView("_Form", subscriber);
}
答案 0 :(得分:1)
提交表单时,浏览器会向服务器发送HTTP Post请求。然后,浏览器显示Response的有效负载。你的帖子控制器动作正在返回一个PartialView,浏览器很乐意呈现它(即使它没有必要的html,head或body标签来使它真正有效的HTML)。
听起来您希望浏览器保留大部分页面加载和呈现,发布表单,然后获取生成的HTML并仅替换加载页面的一部分。简单地说,浏览器不够智能。
你可能想要做的是这样的事情:
我强烈推荐使用jQuery - 它可以更轻松地制作Ajax请求,处理成功回调,并用结果替换当前加载页面的一部分。我的理解是MS的'unobtrubiveive javascript'也可能有助于实现这一点,但我没有任何直接经验。
显然,所有这些只有在浏览器启用了javascript时才有效。
答案 1 :(得分:1)
我终于找到了问题的解决方案。我用AJAX实现了它,最后得到了以下代码:
_Index.cshtml
<header>
<h2>Subscribe</h2>
</header>
<p>Subscribe to my e-mail newsfeed.</p>
<div id="subscription-form">
@{Html.RenderPartial("_Form");}
</div>
_Form.cshtml
@using Blog.Models.Entities
@model Subscriber
@{
AjaxOptions ajaxOptions = new AjaxOptions
{
LoadingElementId = "loading",
LoadingElementDuration = 2000,
HttpMethod = "Post",
UpdateTargetId = "subscription-form"
};
}
<div id="loading" style="display: none;">
<p>Processing request...</p>
</div>
@using (Ajax.BeginForm("Index", "Subscription", ajaxOptions))
{
<div class="editor-label">@Html.LabelFor(subscriber => subscriber.Email)</div>
<div class="editor-field ">@Html.EditorFor(subscriber => subscriber.Email)</div>
@Html.ValidationMessageFor(subscriber => subscriber.Email)
<input type="submit" value="Subscribe" />
}
_Succes.cshtml
@using Blog.Models.Entities
@model Subscriber
<p id="subscription-result">@ViewBag.Result</p>
以下控制器操作方法:
public ActionResult Index()
{
return PartialView("_Index");
}
[HttpPost]
public PartialViewResult Index(Subscriber subscriber)
{
if (ModelState.IsValid)
{
Subscriber foundSubscriber = _repository.Subscribers.Where(s => s.Email.Equals(subscriber.Email)).FirstOrDefault();
if (foundSubscriber != null)
{
ModelState.AddModelError("Email", "This e-mail address has already been added.");
return PartialView("_Form", subscriber);
}
_repository.SaveSubscriber(subscriber);
ViewBag.Result = "Succesfully subscribed to the newsletter.";
return PartialView("_Succes", subscriber);
}
ModelState.AddModelError("Email", "Please provide a valid e-mail address.");
return PartialView("_Form", subscriber);
}
我希望这将有助于任何试图在未来实现同样目标的人。顺便说一下,我在这个博客上找到了解决方案:http://xhalent.wordpress.com/2011/02/05/using-unobtrusive-ajax-forms-in-asp-net-mvc3/。