我正在尝试创建一个UniqueAttribute使用System.ComponentModel.DataAnnotations.ValidationAttribute
我希望这是通用的,因为我可以传递Linq DataContext,表名,字段并验证传入值是否唯一.
这是一个不可编译的代码片段,我现在卡在这里:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Data.Linq;
using System.ComponentModel;
namespace LinkDev.Innovation.Miscellaneous.Validation.Attributes
{
public class UniqueAttribute : ValidationAttribute
{
public string Field { get; set; }
public override bool IsValid(object value)
{
string str = (string)value;
if (String.IsNullOrEmpty(str))
return true;
// this is where I'm stuck
return (!Table.Where(entity => entity.Field.Equals(str)).Any());
}
}
}
Run Code Online (Sandbox Code Playgroud)
我应该在我的模型中使用它如下:
[Required]
[StringLength(10)]
[Unique(new DataContext(),"Groups","name")]
public string name { get; set; }
Run Code Online (Sandbox Code Playgroud)
编辑:请注意,根据这个:为什么C#禁止通用属性类型? 我不能使用属性的泛型类型.
所以我的新方法是使用Reflection/Expression树来动态构建Lambda表达式树.
HЕY!本主题与以下内容重复:为什么C#禁止通用属性类型?
我正在密切关注Roslyn编译器,并注意到泛型类型可用于属性.因此我的问题是:C#中是否有一个通用属性的好例子?
编辑:
事实证明他们实际上是不允许的:
error CS0698: A generic type cannot derive from 'Attribute' because it is an attribute class
Run Code Online (Sandbox Code Playgroud)
所以我的实际问题是:为什么这样呢?
我想在我的 WPF 应用程序中创建一个通用数据类型转换器,比如这个类模板:
[ValueConversion(typeof(T), typeof(string))]
class DataTypeConverter<T> : IValueConverter
Run Code Online (Sandbox Code Playgroud)
将 int、double、byte、ushort 等数据类型转换为字符串,反之亦然,并在我的类的不同属性类型的两种绑定中使用它,然后通过这行代码简单地创建任何类型:
class ushortTypeConverter : DataTypeConverter<ushort>{}
Run Code Online (Sandbox Code Playgroud)
如果可能,在错误输入的情况下绑定的文本框中显示验证消息。
是否可以编写这样的类模板?
我试图拦截ServiceRunner中的请求和响应以对它们运行验证.
1.我不知道如何(!result.IsValid)中止请求,或者这是否是正确的方法.
2.特别是对于响应,对象响应是未知的,直到动态运行时,这使得我很难为它创建IValidator,它在编译时需要已知类型.
请参阅代码中的注释:
public class CustomServiceRunner<T> : ServiceRunner<T> {
public CustomServiceRunner(IAppHost appHost, ActionContext actionContext)
: base(appHost, actionContext) { }
public override void BeforeEachRequest(IRequestContext requestContext, T request) {
var validator = AppHost.TryResolve<IValidator<T>>();
var result = validator.Validate(request);
//----------------------
//if (!result.IsValid)
// How to return result.ToResponseDto() and abort the request?
//----------------------
base.BeforeEachRequest(requestContext, request);
}
public override object AfterEachRequest(IRequestContext requestContext, T request, object response) {
//-----------------------
//Validating against response presents a more challenging issue
//I may have multiple response classes and returned response …Run Code Online (Sandbox Code Playgroud) c# ×4
binding ×1
generics ×1
linq-to-sql ×1
roslyn ×1
servicestack ×1
validation ×1
wpf ×1
xaml ×1