Skip to content

Commit

Permalink
组件提交表单,服务端验证失败时还原页面并显示ModelState的错误信息 #406
Browse files Browse the repository at this point in the history
  • Loading branch information
SeriaWei committed Dec 29, 2020
1 parent 8e4aa7c commit bc71eb4
Show file tree
Hide file tree
Showing 22 changed files with 198 additions and 89 deletions.
38 changes: 13 additions & 25 deletions src/ZKEACMS.FormGenerator/Controllers/FormDataController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,33 @@
using System.Net;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Primitives;
using ZKEACMS.Filter;
using Easy;

namespace ZKEACMS.FormGenerator.Controllers
{
[DefaultAuthorize(Policy = PermissionKeys.ViewFormData)]
public class FormDataController : BasicController<FormData, int, IFormDataService>
{
private const string ExcelContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

public FormDataController(IFormDataService service) : base(service)
private readonly ILocalize _localize;
public FormDataController(IFormDataService service, ILocalize localize) : base(service)
{
_localize = localize;
}
[HttpPost, AllowAnonymous]
public IActionResult Submit(string next, string FormId)
{
var pathArray = next.Split("?");

Dictionary<string, StringValues> queryDic = null;
if (pathArray.Length > 1)
{
queryDic= QueryHelpers.ParseQuery(pathArray[1]);
}
else
{
queryDic = new Dictionary<string, StringValues>();
}
queryDic.Remove("status");
queryDic.Remove("msg");
[HttpPost, AllowAnonymous, RenderRefererPage]
public IActionResult Submit(string FormId)
{
var result = Service.SaveForm(Request.Form, FormId);
if (result.HasViolation)
{
queryDic.Add("status", "error");
queryDic.Add("msg", WebUtility.UrlEncode(result.ErrorMessage));
}
else
ModelState.Merge(result);
if (!result.HasViolation)
{
queryDic.Add("status", "complete");
TempData["Message"] = _localize.Get("Form have submited");
}
return Redirect(QueryHelpers.AddQueryString(pathArray[0], queryDic.ToDictionary(m => m.Key, m => m.Value.ToString())));
return View();
}

[HttpPost, DefaultAuthorize(Policy = PermissionKeys.ManageFormData)]
public override IActionResult Delete(int id)
{
Expand Down
7 changes: 5 additions & 2 deletions src/ZKEACMS.FormGenerator/Service/FormDataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,16 @@ public ServiceResult<FormData> SaveForm(IFormCollection formCollection, string f
{
if (!validator.Validate(field, dataitem, out string message))
{
result.RuleViolations.Add(new RuleViolation(field.DisplayName, message));
return result;
result.RuleViolations.Add(new RuleViolation(item, message));
}
}
formData.Datas.Add(dataitem);
}
}
if (result.HasViolation)
{
return result;
}
if (formData.Datas.Any())
{
formData.Title = formData.Datas.FirstOrDefault().FieldValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@
@Html.DropDownList(Model.ID + "[2]", items, new Dictionary<string, object> { { "class", "form-control" }, { "data-district", district ?? L("-- District --").Text } })
</div>
</div>

<span class="field-validation-valid" data-valmsg-for="@(Model.ID + "[0]")" data-valmsg-replace="true"></span>
@Html.ValidationMessage(Model.ID + "[0]")
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
}

</div>
<span class="field-validation-valid" data-valmsg-for="@Model.ID" data-valmsg-replace="true">
<span id="@(Model.ID)-error" class="">@L("Please select at least one option")</span>
</span>
@Html.ValidationMessage(Model.ID, L("Please select at least one option").Text)
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
@Html.TextBox(Model.ID, Model.Value, Model.Attributes)
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</div>
<span class="field-validation-valid" data-valmsg-for="@Model.ID" data-valmsg-replace="true"></span>
@Html.ValidationMessage(Model.ID)
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</label>
}
@Html.DropDownList(Model.ID, items, L("-- Select --").Text, Model.Attributes)
<span class="field-validation-valid" data-valmsg-for="@Model.ID" data-valmsg-replace="true"></span>
@Html.ValidationMessage(Model.ID)
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</label>
}
@Html.TextBox(Model.ID, Model.Value, Model.Attributes)
<span class="field-validation-valid" data-valmsg-for="@Model.ID" data-valmsg-replace="true"></span>
@Html.ValidationMessage(Model.ID)
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</label>
}
@Html.TextBox(Model.ID, Model.Value, Model.Attributes)
<span class="field-validation-valid" data-valmsg-for="@Model.ID" data-valmsg-replace="true"></span>
@Html.ValidationMessage(Model.ID)
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</label>
}
@Html.TextArea(Model.ID, Model.Value, Model.Attributes)
<span class="field-validation-valid" data-valmsg-for="@Model.ID" data-valmsg-replace="true"></span>
@Html.ValidationMessage(Model.ID)
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</label>
}
@Html.TextBox(Model.ID, Model.Value, Model.Attributes)
<span class="field-validation-valid" data-valmsg-for="@Model.ID" data-valmsg-replace="true"></span>
@Html.ValidationMessage(Model.ID)
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
</div>
}
</div>
<span class="field-validation-valid" data-valmsg-for="@Model.ID" data-valmsg-replace="true"></span>
@Html.ValidationMessage(Model.ID)
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
}
</label>
}
@Html.TextBox(Model.ID, Model.Value, Model.Attributes)
<span class="field-validation-valid" data-valmsg-for="@Model.ID" data-valmsg-replace="true"></span>
@Html.TextBox(Model.ID, Model.Value, Model.Attributes)
@Html.ValidationMessage(Model.ID)
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
}
@Html.TextBox(Model.ID, Model.Value, Model.Attributes)
<img src="/Validation/Code" class="validation-code" style="cursor:pointer" onclick="$(this).attr('src','/Validation/Code?v='+new Date().getTime())" />
<span class="field-validation-valid" data-valmsg-for="@Model.ID" data-valmsg-replace="true"></span>
@Html.ValidationMessage(Model.ID)
@if (Model.Description.IsNotNullAndWhiteSpace())
{
<dl>
Expand Down
12 changes: 3 additions & 9 deletions src/ZKEACMS.FormGenerator/Views/Widget.Form.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,16 @@
Script.Reqiured("form-widget").AtFoot();
}
<div class="form-widget">
@if (ViewContext.HttpContext.Request.Query["status"] == "error")
{
<div class="alert alert-danger alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
@System.Net.WebUtility.UrlDecode(ViewContext.HttpContext.Request.Query["msg"])
</div>
}
@if (ViewContext.HttpContext.Request.Query["status"] == "complete")
@if (TempData["Message"] != null)
{
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
@L("Form have submited")
@TempData["Message"]
</div>
}

<form method="post" asp-action="Submit" asp-controller="FormData">
@Html.HiddenForCurrentPagePath()
<input type="hidden" name="next" value="@ViewContext.HttpContext.Request.GetAbsoluteUrl()" />
<input type="hidden" name="FormId" value="@Model.ID" />
<div class="row">
Expand Down
25 changes: 17 additions & 8 deletions src/ZKEACMS.Message/Controllers/MessageHandleController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Copyright 2018 ZKEASOFT
* http://www.zkea.net/licenses
*/
using Easy;
using Easy.Constant;
using Easy.Extend;
using Easy.Mvc.Extend;
Expand All @@ -11,6 +12,7 @@
using Microsoft.AspNetCore.Mvc;
using System;
using System.Net;
using ZKEACMS.Filter;
using ZKEACMS.Message.Models;
using ZKEACMS.Message.Service;

Expand All @@ -21,24 +23,31 @@ public class MessageHandleController : Controller
private readonly IMessageService _messageService;
private readonly ICommentsService _commentService;
private readonly IApplicationContextAccessor _applicationContextAccessor;
private readonly ICookie _cookie;
public MessageHandleController(IApplicationContextAccessor applicationContextAccessor, IMessageService messageService, ICommentsService commentsService, ICookie cookie)
private readonly ILocalize _localize;
public MessageHandleController(IApplicationContextAccessor applicationContextAccessor,
IMessageService messageService,
ICommentsService commentsService,
ILocalize localize)
{
_applicationContextAccessor = applicationContextAccessor;
_messageService = messageService;
_commentService = commentsService;
_cookie = cookie;
_localize = localize;
}
[HttpPost, ValidateAntiForgeryToken]
public IActionResult PostMessage(MessageEntity entity, string redirect)
[HttpPost, ValidateAntiForgeryToken, RenderRefererPage]
public IActionResult PostMessage(MessageEntity entity)
{
if (ModelState.IsValid)
{
_cookie.SetValue("Message", "true", 1);
entity.Status = (int)RecordStatus.InActive;
_messageService.Add(entity);
var result = _messageService.Add(entity);
ModelState.Merge(result);
if (!result.HasViolation)
{
TempData["Message"] = _localize.Get("Thank You for your submit!");
}
}
return Redirect(redirect);
return View(entity);
}
[HttpPost, ValidateAntiForgeryToken]
public IActionResult PostComment(string CommentContent, string PagePath, string ReplyTo, string Title)
Expand Down
5 changes: 5 additions & 0 deletions src/ZKEACMS.Message/Service/MessageWidgetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public MessageWidgetService(IWidgetBasePartService widgetBasePartService, IAppli
}
public override WidgetViewModelPart Display(WidgetDisplayContext widgetDisplayContext)
{
if (widgetDisplayContext.Model is MessageEntity messageEntity)
{
return widgetDisplayContext.ToWidgetViewModelPart(messageEntity);
}

return widgetDisplayContext.ToWidgetViewModelPart(new MessageEntity());
}
}
Expand Down
19 changes: 11 additions & 8 deletions src/ZKEACMS.Message/Views/Widget.Message.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,13 @@
Script.Reqiured("validate").AtFoot();
}
<div class="message">
@if (ViewContext.HttpContext.Request.Cookies.Any(key => key.Key == "Message"))
{
<div class="alert alert-info">
<h4>@L("Thank You for your submit!")</h4>
</div>
}
@using (Html.BeginForm("PostMessage", "MessageHandle", FormMethod.Post))
{
@Html.HiddenForCurrentPagePath()
@Html.HiddenFor(m => m.Status)
@Html.HiddenFor(m => m.Description)
@Html.HiddenFor(m => m.Reply)
<input type="hidden" value="@ViewContext.HttpContext.Request.Path.ToString()" name="redirect" />

<div class="row">
<div class="col-md-6">
<div class="form-group">
Expand All @@ -38,6 +33,14 @@
</div>
</div>
</div>
<input type="submit" value="@L("Submit")" class="btn btn-default" />
@if (TempData["Message"] != null)
{
<p class="alert alert-info">
@TempData["Message"]
</p>
}
<p>
<input type="submit" value="@L("Submit")" class="btn btn-default" />
</p>
}
</div>
13 changes: 13 additions & 0 deletions src/ZKEACMS/Extend/HtmlHelperExtend.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,18 @@ public static IHtmlContent EmailLinkButton(this IHtmlHelper html, string link, s
{
return html.Partial("EmailLinkButton", new Tuple<string, string, bool>(link, text, center));
}
public static IHtmlContent HiddenForCurrentPagePath(this IHtmlHelper html)
{
var request = html.ViewContext.HttpContext.Request;
if (request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase))
{
var pagePath = request.Query["CurrentPagePath"];
return html.Hidden("CurrentPagePath", pagePath.Count > 0 ? pagePath : request.Path);
}
else
{
return html.Hidden("CurrentPagePath", request.Form["CurrentPagePath"]);
}
}
}
}
25 changes: 25 additions & 0 deletions src/ZKEACMS/Extend/ModelStateDictionaryExtend.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* http://www.zkea.net/
* Copyright 2020 ZKEASOFT
* http://www.zkea.net/licenses */

using Easy.RepositoryPattern;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ZKEACMS
{
public static class ModelStateDictionaryExtend
{
public static void Merge<T>(this ModelStateDictionary modelState, ServiceResult<T> serviceResult)
{
foreach (var item in serviceResult.RuleViolations)
{
modelState.AddModelError(item.ParameterName, item.ErrorMessage);
}
}
}
}

0 comments on commit bc71eb4

Please sign in to comment.