.Net OData v4 客户端生成 - IDataErrorInfo
.Net OData v4 Client Generation - IDataErrorInfo
我已经使用 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());
}
}
是否有可能阻止请求中包含 错误 属性?
OData 客户端生成的模型是部分 classes。当您实施 IDataErrorInfo
时,它会要求您实施 Error
属性 ,当然服务器端不存在。因为你做了一个操作,例如在实体 City
上序列化 City 对象,如果出现错误 属性 它也会被序列化。
一个解决方案可以避免这种情况,并使客户端模型与 UI 分开。你可以试试这个:
namespace Client.Model {
public partial class City
{
public String this[String columnName]
{
return "";
}
}
}
使用继承创建 UI 相关模型 classes,与生成的模型分开:
namespace UI.Model {
public class City : Client.Model.City, IDataErrorInfo
{
public String Error { get { return ""; } }
}
}
确保在 UI 上使用 UI.Model.City 并且在调用 OData 服务进行添加操作时,对 UI.Model.City class 对象执行显式转换以进行转换至 Client.Model.City,错误 属性 将消失:
ODataContainer container = new ODataContainer(new Uri("http://localhost:45666/odata"));
container.AddToCities((Client.Model.City)city);
注意: 这种方法有其自身的缺点,因为它可能会导致您在不同的命名空间下使用相同的 class 名称,因此您通常必须在以下情况下使用完整的命名空间路径使用相同的 class 名称。您可以在 UI 模型上使用不同的 prefix/postfix 和 Class 名称来避免它。例如CityViewModel
.
也许OData Client Hook可以满足您的要求。请参阅相关问题(
)
我的建议是:
- 在同一个命名空间中创建部分 class 'City'(使用与生成的
City
class 相同的命名空间)并实现 IdataErrorInfo。
在服务器模型中添加Error
属性。 public string Error {get; set;}
如果您使用的是 EF 代码优先方法,请排除模型构建器中的错误 属性,以防止在数据库中创建 'Error' 列。 modelBuilder.Entity<YourModelClass>().Ignore(x =>x.Error);
无需在客户端代码中实现 'City' class 中的错误 属性,因为客户端代码生成器会在生成的代码中生成 Error
属性。
我遇到了同样的问题,我是这样解决的。
我已经使用 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());
}
}
是否有可能阻止请求中包含 错误 属性?
OData 客户端生成的模型是部分 classes。当您实施 IDataErrorInfo
时,它会要求您实施 Error
属性 ,当然服务器端不存在。因为你做了一个操作,例如在实体 City
上序列化 City 对象,如果出现错误 属性 它也会被序列化。
一个解决方案可以避免这种情况,并使客户端模型与 UI 分开。你可以试试这个:
namespace Client.Model {
public partial class City
{
public String this[String columnName]
{
return "";
}
}
}
使用继承创建 UI 相关模型 classes,与生成的模型分开:
namespace UI.Model {
public class City : Client.Model.City, IDataErrorInfo
{
public String Error { get { return ""; } }
}
}
确保在 UI 上使用 UI.Model.City 并且在调用 OData 服务进行添加操作时,对 UI.Model.City class 对象执行显式转换以进行转换至 Client.Model.City,错误 属性 将消失:
ODataContainer container = new ODataContainer(new Uri("http://localhost:45666/odata"));
container.AddToCities((Client.Model.City)city);
注意: 这种方法有其自身的缺点,因为它可能会导致您在不同的命名空间下使用相同的 class 名称,因此您通常必须在以下情况下使用完整的命名空间路径使用相同的 class 名称。您可以在 UI 模型上使用不同的 prefix/postfix 和 Class 名称来避免它。例如CityViewModel
.
也许OData Client Hook可以满足您的要求。请参阅相关问题(
我的建议是:
- 在同一个命名空间中创建部分 class 'City'(使用与生成的
City
class 相同的命名空间)并实现 IdataErrorInfo。 在服务器模型中添加
Error
属性。public string Error {get; set;}
如果您使用的是 EF 代码优先方法,请排除模型构建器中的错误 属性,以防止在数据库中创建 'Error' 列。
modelBuilder.Entity<YourModelClass>().Ignore(x =>x.Error);
无需在客户端代码中实现 'City' class 中的错误 属性,因为客户端代码生成器会在生成的代码中生成 Error
属性。
我遇到了同样的问题,我是这样解决的。