.Net OData v4客户端生成 - IDataErrorInfo

时间:2015-07-17 19:37:24

标签: c# odata asp.net-web-api2 odata-v4

我使用OData Client Generator创建了一个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());
    }
}

是否有可能阻止错误属性包含在请求中?

3 个答案:

答案 0 :(得分:0)

使用OData客户端生成的模型是部分类。当您实现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.City和Error属性将会消失:

ODataContainer container = new ODataContainer(new Uri("http://localhost:45666/odata"));
container.AddToCities((Client.Model.City)city);

注意:此方法有自己的缺点,因为它可能会导致您在不同的命名空间下具有相同的类名,因此在使用相同的类名时通常必须使用完整的命名空间路径。您可以在UI模型上使用带有类名的不同前缀/后缀来避免它。例如CityViewModel

答案 1 :(得分:0)

也许OData Client Hook可以满足您的要求。查看相关问题( dealing with dynamic properties on oData client

答案 2 :(得分:0)

我的建议是:

  1. 在同一名称空间中创建一个部分类'City'(使用生成的Error类的相同名称空间)并实现IdataErrorInfo。
  2. 在服务器模型中添加public string Error {get; set;}属性。 modelBuilder.Entity<YourModelClass>().Ignore(x =>x.Error);

  3. 如果您使用的是EF代码优先方法,请在模型构建器中排除错误属性,以防止在数据库中创建“错误”列。 Error

  4. 无需在客户端代码中的“City”类中实现Error属性,因为客户端代码生成器会在生成的代码中生成<input type="text" id="numPpl" name="numPpl"> <br><br> <div id="demo"> </div> 属性。

    我有同样的问题,我用这种方式解决了。