C#MVC CMS – 自定义远程validation
在下面的链接中,我问了一个关于如何确保字段不包含相同值的问题(例如,当字段上存在唯一约束时,正确地导致C#在发出exception时抛出exception)。 根据我收到的答案,它解决了这个问题但提出了另一个问题。
确保另一条记录尚未包含字段的相同值
我现在面临的主要问题是当我创建一个新视图时。 validation按预期工作。 简而言之 – 系统需要检查ViewName和ViewPath(路由)是否都是唯一的,因此需要搜索数据库。
但是,当我编辑视图时,validation再次启动(实际上不应该这样做,因为很明显视图已存在,因为您正在编辑它)。
我现在的问题是如何自定义远程validation以使编辑与创建不同。 虽然我们不能编辑视图的名称以匹配现有视图,但我们也不应仅仅因为它与当前视图相同而停止保存当前视图。
下面是我的模型(不是(希望)由工具生成的部分:-):
[MetadataType(typeof(IViewMetaData))] public partial class View : IViewMetaData { } public interface IViewMetaData { [Required(AllowEmptyStrings = false, ErrorMessageResourceType = typeof(DALResources), ErrorMessageResourceName = "ErrorRequiredField")] [StringLength(50, ErrorMessageResourceType = typeof(DALResources), ErrorMessageResourceName = "ErrorLessThanCharacters")] [Display(ResourceType = typeof(DALResources), Name = "ViewName")] [Remote("IsViewNameAvailable", "Validation")] string ViewName { get; set; } [Required(AllowEmptyStrings = false, ErrorMessageResourceType = typeof(DALResources), ErrorMessageResourceName = "ErrorRequiredField")] [StringLength(400, ErrorMessageResourceType = typeof(DALResources), ErrorMessageResourceName = "ErrorLessThanCharacters")] [Display(ResourceType = typeof(DALResources), Name = "ViewPath")] [Remote("IsViewPathAvailable", "Validation")] string ViewPath { get; set; } [Display(ResourceType = typeof(DALResources), Name = "ViewContent")] string ViewContent { get; set; } }
我遇到问题的部分是[Remote]validation属性,定义如下:
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)] public class ValidationController : Controller { private FRCMSV1Entities db = new FRCMSV1Entities(); public JsonResult IsViewNameAvailable(View view) { bool isViewNameInvalid = db.View.Any(v => v.ViewName == view.ViewName && v.Id != view.Id); if (!isViewNameInvalid) return Json(true, JsonRequestBehavior.AllowGet); string suggestedViewName = string.Format(UI_Prototype_MVC_Resources.ErrorViewAlreadyExists, view.ViewName); for (int i = 1; i v.ViewName == altViewName); if (!doesAltViewNameExist) { suggestedViewName = string.Format(UI_Prototype_MVC_Resources.ErrorViewNotAvailableTry, view.ViewName, altViewName); break; } } return Json(suggestedViewName, JsonRequestBehavior.AllowGet); } public JsonResult IsViewPathAvailable(View view) { bool doesViewPathExist = db.View.Any(v => v.ViewPath == view.ViewPath && v.Id != view.Id); if (!doesViewPathExist) return Json(true, JsonRequestBehavior.AllowGet); string suggestedViewPath = string.Format(UI_Prototype_MVC_Resources.ErrorViewAlreadyExists, view.ViewPath); for (int i = 1; i v.ViewPath == altViewPath); if (!doesAltViewPathExist) { suggestedViewPath = string.Format(UI_Prototype_MVC_Resources.ErrorViewNotAvailableTry, view.ViewPath, altViewPath); break; } } return Json(suggestedViewPath, JsonRequestBehavior.AllowGet); } }
问题是,validation需要在创建和编辑时都一样。 它只需要对编辑进行额外的检查以确保我们仍然引用相同的记录,如果是这样,那么就没有必要显示validation消息,因为没有任何错误。
我的问题是:1。我如何按预期工作。 我可以看到两种方法都完全相同,这违反了DRY原则。 我怎样才能使它更通用并简化它。 然而,第一个问题实际上是我想要回答的问题,因为没有必要重构一些不起作用的东西。
有关更多信息,上面的代码也是以下链接的代码编辑:
https://msdn.microsoft.com/en-us/library/gg508808(VS.98).aspx
谢谢你的帮助。
您需要添加一个参数以将模型的ID属性作为AdditionalFields
传递。 假设它的int Id
,那么
[Remote("IsViewPathAvailable", "Validation", AdditionalFields = "Id")] public string ViewName { get; set; }
而方法应该是
public JsonResult IsViewNameAvailable(string viewName, int? id)
请注意,在“ Edit
视图中,您包含Id
属性的隐藏输入,因此其值将由jquery.validate远程函数回发。
然后,您可以检查id
参数是否为null
(即它是新的)或具有值(它是否存在)并调整查询以适应。
bool isViewNameInvalid; if (id.HasValue) { isViewNameInvalid = db.View.Any(v => v.ViewName == viewName && v.Id != id); } else { isViewNameInvalid = db.View.Any(v => v.ViewName == ViewName); }
目前发生的是Remote
只发布ViewName
属性的值,并且因为您的参数是模型,所以它使用默认的id
值( 0
)初始化,并且您的查询被转换为Any(v => v.ViewName == viewName && v.Id != 0);
我还建议使用视图模型而不是您的partial class
旁注:从生成ViewName
的代码中,您期望很多ViewName
具有相同的值,这意味着您可能在内部进行大量数据库调用for
循环。 您可以考虑使用linq .StartsWith()
查询来获取以ViewName
值开头的所有记录,然后检查循环中的内存中集。
- ASP.NET MVC中的DropdownList – 未发布值
- 无法加载文件或程序集“Newtonsoft.Json”或其依赖项之一
- 用于在MVC5中模拟ConfirmEmailAsync和其他UserManager方法的接口
- 在ASP.NET MVC站点中正确构建Lucene.Net用法
- 如何在Visual Studio社区2013中创建ASP.NET MVC 5 Web应用程序?
- ASP.NET MVC:以编程方式在静态内容上设置HTTP标头
- 如果FirstOrDefault返回null,则返回列表中的第一项
- ASP.Net MVC C#Chrome未在编辑模式下显示日期
- 在.Net 4.5中检查Active Directory组成员身份