WCF DataService 使用其他类库的数据模型 - 无法再次运行该服务
我有一个 wcf 数据服务,它正在使用一些 poco 对象。为了在发生更改时验证此对象,我想使用 System.ComponentModel.DataAnnotations 元数据 - 验证。
出于测试目的,我创建了一个使用此 wcf 数据服务的控制台应用程序。一切正常。此外还应该有客户端验证。服务引用不会自动公开验证属性。因此,我们的想法是将所有数据模型/结构放在一个通用的 .net 类库中,例如:
[DataServiceKey("ADRESSEN_KEY")]
public partial class Adresse
{
[Required(ErrorMessage = "Das ADRESSEN_KEY-Feld darf nicht leer sein.")]
public int? ADRESSEN_KEY { get; set; }
public string ADRESSEN_NAM1 { get; set; }
public string ADRESSEN_STRA { get; set; }
[StringLength(4, ErrorMessage = "Die PLZ darf nur 4-stellig sein.")]
public string ADRESSEN_PLZ { get; set; }
public string ADRESSEN_ORT { get; set; }
} [DataServiceKey("ORDERUSER_KEY")]
public partial class OrderUser
{
[Required(ErrorMessage = "Das ORDERUSER_KEY-Feld darf nicht leer sein.")]
public int? ORDERUSER_KEY { get; set; }
public string ORDERUSER_NAME { get; set; }
public string ORDERUSER_VORNAME { get; set; }
public string ORDERUSER_USER { get; set; }
public string ORDERUSER_PWD { get; set; }
public int? ORDERUSER_ADRKEY { get; set; }
}
我引用的这两个“实体”(POCO)(因为它们位于同一解决方案中)并在 wcf 数据服务类中使用就像:
public class AllEntities
{
private List<OrderUser> _orderUserCollection = null;
private List<OrderUser> LoadDataOrderUser()
{
List<OrderUser> orderUsers = new List<OrderUser>();
i3.Data.DataReader dataReader = null;
try
{
dataReader = new i3.Data.DataReader("SELECT * FROM ORDERUSER", ConfigurationManager.ConnectionStrings["i3Database"].ConnectionString);
if (dataReader.HasRows)
{
do
{
orderUsers.Add(new OrderUser() {
ORDERUSER_KEY = Convert.ToInt32(dataReader["ORDERUSER_KEY"]),
ORDERUSER_NAME = dataReader["ORDERUSER_NAME"].ToString(),
ORDERUSER_VORNAME = dataReader["ORDERUSER_VORNAME"].ToString(),
ORDERUSER_USER = dataReader["ORDERUSER_USER"].ToString(),
ORDERUSER_PWD = dataReader["ORDERUSER_PWD"].ToString(),
ORDERUSER_ADRKEY = Convert.ToInt32(dataReader["ORDERUSER_ADRKEY"])});
} while (dataReader.Read());
}
}
catch { }
if (dataReader != null)
{
if (!dataReader.mRS.IsClosed)
dataReader.Close();
}
return orderUsers;
}
public IQueryable<OrderUser> OrderUserCollection
{
get { _orderUserCollection = LoadDataOrderUser(); return _orderUserCollection.AsQueryable<OrderUser>(); }
}
private List<Adresse> _adresseCollection = null;
private List<Adresse> LoadDataAdresse()
{
List<Adresse> adressen = new List<Adresse>();
i3.Data.DataReader dataReader = null;
try
{
dataReader = new i3.Data.DataReader("SELECT * FROM ADRESSEN", ConfigurationManager.ConnectionStrings["i3Database"].ConnectionString);
if (dataReader.HasRows)
{
do
{
adressen.Add(new Adresse()
{
ADRESSEN_KEY = Convert.ToInt32(dataReader["ADRESSEN_KEY"]),
ADRESSEN_NAM1 = dataReader["ADRESSEN_NAM1"].ToString(),
ADRESSEN_ORT = dataReader["ADRESSEN_ORT"].ToString(),
ADRESSEN_PLZ = dataReader["ADRESSEN_PLZ"].ToString(),
ADRESSEN_STRA = dataReader["ADRESSEN_STRA"].ToString()
});
} while (dataReader.Read());
}
}
catch { }
if (dataReader != null)
{
if (!dataReader.mRS.IsClosed)
dataReader.Close();
}
return adressen;
}
public IQueryable<Adresse> AdresseCollection
{
get { _adresseCollection = LoadDataAdresse(); return _adresseCollection.AsQueryable<Adresse>(); }
}
}
在这里,我将数据库的数据加载到对象中,在将数据模型放入其工作的类库之前,出于测试目的非常简单。
最后,在网络服务中,我像这样实例化我的“上下文”对象。正如在将数据模型放入类库之前所说,这也工作得很好...
public class i3DataService : DataService<AllEntities>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
config.SetEntitySetAccessRule("*", EntitySetRights.All); // für alle Entities soll CRUD zur Verfügung stehen
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All); // alle Operationen sind zulässig
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
我也能够构建解决方案,但一旦我在运行时调用服务,我就会收到如下错误:mettag can not已解决,肥皂合同异常...
有什么提示吗? 我现在可以使用 wcf ria 和实体框架,但我必须依赖“自定义”解决方法...
谢谢!
我越来越接近了,也许它与 Null-bale 类型有关:
不工作:
[Required(ErrorMessage = "Das ADRESSEN_KEY-Feld darf nicht leer sein.")]
public **int?** ADRESSEN_KEY { get; set; }
工作:
[Required(ErrorMessage = "Das ADRESSEN_KEY-Feld darf nicht leer sein.")]
public **int** ADRESSEN_KEY { get; set; }
继续搜索...因为所需的属性需要 null 或 string.Empty...
呃,有时我正在编写有趣的东西!
[MetadataType(typeof(Adresse))]
[DataServiceKey("ADRESSEN_KEY")]
public partial class Adresse
{
public int ADRESSEN_KEY { get; set; }
public string ADRESSEN_NAM1 { get; set; }
public string ADRESSEN_STRA { get; set; }
[StringLength(4, ErrorMessage = "Die PLZ darf nur 4-stellig sein.")]
public string ADRESSEN_PLZ { get; set; }
public string ADRESSEN_ORT { get; set; }
[Required(ErrorMessage = "Das ADRESSEN_TEST-Feld darf nicht leer sein.")]
public int? ADRESSEN_TEST { get; set; }
}
[MetadataType(typeof(OrderUser))]
[DataServiceKey("ORDERUSER_KEY")]
public partial class OrderUser
{
public int ORDERUSER_KEY { get; set; }
public string ORDERUSER_NAME { get; set; }
public string ORDERUSER_VORNAME { get; set; }
public string ORDERUSER_USER { get; set; }
public string ORDERUSER_PWD { get; set; }
[Required(ErrorMessage = "Das ORDERUSER_ADRKEY-Feld darf nicht leer sein.")]
public int? ORDERUSER_ADRKEY { get; set; }
}
则没有多大意义。
如果您指定关键数据字段,例如: [DataServiceKey("ORDERUSER_KEY")]
public int? ORDERUSER_KEY, { 得到;放;哪个
应该是唯一的并且可以立即为空!!!
所以代码现在可以正常工作了,无论如何,谢谢!
I've got a wcf dataservice which is using some poco object. In order to validate this objects when a change occurs I want to use the System.ComponentModel.DataAnnotations metadata - validation
.
For testing purpose I've created a console app which consumes this wcf dataservice. Everything is working fine. Additionally there should also be client side validation. The servicereference does not expose the validations attribute automatically. So the idea was to put all the data model / structure in a common .net class library like:
[DataServiceKey("ADRESSEN_KEY")]
public partial class Adresse
{
[Required(ErrorMessage = "Das ADRESSEN_KEY-Feld darf nicht leer sein.")]
public int? ADRESSEN_KEY { get; set; }
public string ADRESSEN_NAM1 { get; set; }
public string ADRESSEN_STRA { get; set; }
[StringLength(4, ErrorMessage = "Die PLZ darf nur 4-stellig sein.")]
public string ADRESSEN_PLZ { get; set; }
public string ADRESSEN_ORT { get; set; }
} [DataServiceKey("ORDERUSER_KEY")]
public partial class OrderUser
{
[Required(ErrorMessage = "Das ORDERUSER_KEY-Feld darf nicht leer sein.")]
public int? ORDERUSER_KEY { get; set; }
public string ORDERUSER_NAME { get; set; }
public string ORDERUSER_VORNAME { get; set; }
public string ORDERUSER_USER { get; set; }
public string ORDERUSER_PWD { get; set; }
public int? ORDERUSER_ADRKEY { get; set; }
}
This two "entities" (POCOs) i'm referencing (as they are situated in the same solution) and using in the wcf dataservice class like:
public class AllEntities
{
private List<OrderUser> _orderUserCollection = null;
private List<OrderUser> LoadDataOrderUser()
{
List<OrderUser> orderUsers = new List<OrderUser>();
i3.Data.DataReader dataReader = null;
try
{
dataReader = new i3.Data.DataReader("SELECT * FROM ORDERUSER", ConfigurationManager.ConnectionStrings["i3Database"].ConnectionString);
if (dataReader.HasRows)
{
do
{
orderUsers.Add(new OrderUser() {
ORDERUSER_KEY = Convert.ToInt32(dataReader["ORDERUSER_KEY"]),
ORDERUSER_NAME = dataReader["ORDERUSER_NAME"].ToString(),
ORDERUSER_VORNAME = dataReader["ORDERUSER_VORNAME"].ToString(),
ORDERUSER_USER = dataReader["ORDERUSER_USER"].ToString(),
ORDERUSER_PWD = dataReader["ORDERUSER_PWD"].ToString(),
ORDERUSER_ADRKEY = Convert.ToInt32(dataReader["ORDERUSER_ADRKEY"])});
} while (dataReader.Read());
}
}
catch { }
if (dataReader != null)
{
if (!dataReader.mRS.IsClosed)
dataReader.Close();
}
return orderUsers;
}
public IQueryable<OrderUser> OrderUserCollection
{
get { _orderUserCollection = LoadDataOrderUser(); return _orderUserCollection.AsQueryable<OrderUser>(); }
}
private List<Adresse> _adresseCollection = null;
private List<Adresse> LoadDataAdresse()
{
List<Adresse> adressen = new List<Adresse>();
i3.Data.DataReader dataReader = null;
try
{
dataReader = new i3.Data.DataReader("SELECT * FROM ADRESSEN", ConfigurationManager.ConnectionStrings["i3Database"].ConnectionString);
if (dataReader.HasRows)
{
do
{
adressen.Add(new Adresse()
{
ADRESSEN_KEY = Convert.ToInt32(dataReader["ADRESSEN_KEY"]),
ADRESSEN_NAM1 = dataReader["ADRESSEN_NAM1"].ToString(),
ADRESSEN_ORT = dataReader["ADRESSEN_ORT"].ToString(),
ADRESSEN_PLZ = dataReader["ADRESSEN_PLZ"].ToString(),
ADRESSEN_STRA = dataReader["ADRESSEN_STRA"].ToString()
});
} while (dataReader.Read());
}
}
catch { }
if (dataReader != null)
{
if (!dataReader.mRS.IsClosed)
dataReader.Close();
}
return adressen;
}
public IQueryable<Adresse> AdresseCollection
{
get { _adresseCollection = LoadDataAdresse(); return _adresseCollection.AsQueryable<Adresse>(); }
}
}
Here I'm loading the data of the database into the objects, very simple for testing purpose before putting the data model into the class library it worked.
Finally in the webservice I'm instanciating my "context"-object like this. as said before puting the data model into the class library this lso worked fine...
public class i3DataService : DataService<AllEntities>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
config.SetEntitySetAccessRule("*", EntitySetRights.All); // für alle Entities soll CRUD zur Verfügung stehen
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All); // alle Operationen sind zulässig
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
I'm also able to build the solution but as soon as I'm calling the service at runntime i'm getting an error like: mettag could not be resolved, soap contract exception aso...
any hints?
I now I could use wcf ria and entity framework but I have to rely on a "custom"-workaround...
Thank you!!!
I'm getting closer, perhaps it has something to do with Null-bale types:
not working:
[Required(ErrorMessage = "Das ADRESSEN_KEY-Feld darf nicht leer sein.")]
public **int?** ADRESSEN_KEY { get; set; }
working:
[Required(ErrorMessage = "Das ADRESSEN_KEY-Feld darf nicht leer sein.")]
public **int** ADRESSEN_KEY { get; set; }
keep on searching...because the required attribute needs null or string.Empty...
ugh man, sometimes i'm coding funny things!
[MetadataType(typeof(Adresse))]
[DataServiceKey("ADRESSEN_KEY")]
public partial class Adresse
{
public int ADRESSEN_KEY { get; set; }
public string ADRESSEN_NAM1 { get; set; }
public string ADRESSEN_STRA { get; set; }
[StringLength(4, ErrorMessage = "Die PLZ darf nur 4-stellig sein.")]
public string ADRESSEN_PLZ { get; set; }
public string ADRESSEN_ORT { get; set; }
[Required(ErrorMessage = "Das ADRESSEN_TEST-Feld darf nicht leer sein.")]
public int? ADRESSEN_TEST { get; set; }
}
[MetadataType(typeof(OrderUser))]
[DataServiceKey("ORDERUSER_KEY")]
public partial class OrderUser
{
public int ORDERUSER_KEY { get; set; }
public string ORDERUSER_NAME { get; set; }
public string ORDERUSER_VORNAME { get; set; }
public string ORDERUSER_USER { get; set; }
public string ORDERUSER_PWD { get; set; }
[Required(ErrorMessage = "Das ORDERUSER_ADRKEY-Feld darf nicht leer sein.")]
public int? ORDERUSER_ADRKEY { get; set; }
}
what does not make much sense is if you specify the keydatafield like:
[DataServiceKey("ORDERUSER_KEY")]
public int? ORDERUSER_KEY { get; set; }
which than should be unique and nullable at once!!!
so the code now works as it is supposed to be, thanks anyway!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
键属性不能为空,并且不允许为空值。因此,所讨论的类型不被识别为实体类型,这通常会导致各种问题、错误等。
Key properties must not be nullable and they don't allow null values. So the type in question is not recognized as an entity type which usually leads to all kinds of problems, errors and so on.