.Net OData v4客户端生成-IDataErrorInfo
本文关键字:-IDataErrorInfo 客户端 OData v4 Net | 更新日期: 2023-09-27 18:03:12
我已经使用OData客户端生成器创建了一个OData v4客户端。这生成了分部类。我想用IDataErrorInfo扩展这个生成的类。
namespace Client.Model {
public partial class City : IDataErrorInfo
{
public String this[String columnName]
{
return "";
}
public String Error { get { return ""; } }
}
}
当我想创建一个新的城市并将其发送到服务器时
ODataContainer container = new ODataContainer(new Uri("http://localhost:45666/odata"));
container.AddToCities(city);
我收到一个错误
An exception of type 'Microsoft.OData.Client.DataServiceRequestException' occurred in Microsoft.OData.Client.dll.
The request is invalid. The property "Error" does not exist in Server.Model.City.
WebApi配置:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<City>("Cities");
builder.EntitySet<Country>("Countries");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: builder.GetEdmModel());
}
}
是否有可能阻止Error属性包含在请求中?
OData客户端生成的Model是分部类。当实现IDataErrorInfo
时,它会要求您实现Error
属性,当然服务器端不存在该属性。因为你做了一个操作,例如在实体City
上,这会序列化City对象,如果有Error属性,它也会被序列化。
解决方案可以是避免这种情况,并将客户端模型与UI分离。你可以试试这个:
namespace Client.Model {
public partial class City
{
public String this[String columnName]
{
return "";
}
}
}
使用继承创建与UI相关的模型类,与生成的模型类分离:
namespace UI.Model {
public class City : Client.Model.City, IDataErrorInfo
{
public String Error { get { return ""; } }
}
}
请确保在UI上使用UI.Model.City,并且当您为Add操作调用OData服务时,对UI.Model.City类对象执行显式强制转换以转换为Client.Model.CCity,Error属性将消失:
ODataContainer container = new ODataContainer(new Uri("http://localhost:45666/odata"));
container.AddToCities((Client.Model.City)city);
注意:这种方法有自己的缺点,因为它可能会导致您在不同的命名空间下拥有相同的类名,因此在使用相同的类名时,您通常必须使用完整的命名空间路径。您可以避免在UI模型上使用带有类名的不同前缀/后缀。例如CCD_ 4。
也许OData Client Hook可以满足您的需求。请参阅相关问题(处理oData客户端上的动态属性(
我的建议是:
- 在同一命名空间中创建分部类"City"(使用生成的
City
类的同一命名空间(并实现IdataErrorInfo -
在服务器模型中添加
Error
属性。public string Error {get; set;}
-
如果您使用EF代码优先的方法,请排除模型生成器中的error属性,以防止在数据库中创建"error"列。
modelBuilder.Entity<YourModelClass>().Ignore(x =>x.Error);
由于客户端代码生成器在生成的代码中生成Error
属性,因此无需在客户端代码中的"City"类中实现Error属性。
我遇到了同样的问题,我用这种方式解决了它。