web api 2,odata v4,ConcurrencyCheck做出错误回复。

时间:2015-02-07 08:25:56

标签: odata asp.net-web-api2

我的模特

public abstract class BaseEntit
{
    public DateTime rowCreatedDT { get; set; }    
    public DateTime rowLastModifiedDT { get; set; }      
    public int user_id1 { get; set; }     
    public int user_id2 { get; set; }
}
[Table("ab")]
public class Ab : BaseEntit
{
    [Key]
    public int id { get; set; }
    public string name { get; set; }         
}

配置

public static IEdmModel GetModel()
{
        ODataModelBuilder builder = new ODataConventionModelBuilder(); 
        var myEntity = builder.EntitySet<Ab>("abs");              
        return builder.GetEdmModel();
}
public static void Register(HttpConfiguration config)
{
    //config.EnableCors();           
    config.MessageHandlers.Add(new AuthenticationHandler());
    config.MapHttpAttributeRoutes();
    config.AddODataQueryFilter();
    config.Filters.Add(new NotImplExceptionFilterAttribute());
    config.MapODataServiceRoute("odata", "api", GetModel());
}

控制器

[ODataRoutePrefix("abs")]
public class AbController : ODataController
{
    protected DB db = new DB();
    protected override void Dispose(bool disposing)
    {
        db.Dispose();
        base.Dispose(disposing);
    }
    [ODataRoute("")]
    [EnableQuery]
    public IQueryable<Ab> get()
    {
        try
        {
            return db.abs;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

上面的代码工作正常。但是当我添加ConcurrencyCheck时,我得到一个错误响应。我做错了什么? (如果我使用ApiController而不是OData,它也可以正常工作) 还有1个问,我怎么能抓住异常?我正在使用vs2012。

public abstract class BaseEntit
{
    public DateTime rowCreatedDT { get; set; }
    [ConcurrencyCheck] //<-- add here
    public DateTime rowLastModifiedDT { get; set; }      
    public int user_id1 { get; set; }     
    public int user_id2 { get; set; }
}

1 个答案:

答案 0 :(得分:0)

是。到目前为止,DateTime属性不支持ETag。这是相应的github issue

但是,你可以解决:

1。创建自己的ETage Handlder。

例如:

public class MyODataEtagHanlder : IETagHandler
{
private const string NullLiteralInETag = "null";

private const char Separator = ',';

public TimeZoneInfo TimeZone { get; set; }

public EntityTagHeaderValue CreateETag(IDictionary<string, object> properties)
{
    if (properties.Count == 0)
    {
        return null;
    }

    StringBuilder builder = new StringBuilder();
    builder.Append('\"');
    bool firstProperty = true;

    foreach (object propertyValue in properties.OrderBy(p => p.Key).Select(p => p.Value))
    {
        if (firstProperty)
        {
            firstProperty = false;
        }
        else
        {
            builder.Append(Separator);
        }

        string str;
        if (propertyValue is DateTime)
        {
            str = GetUriRepresentationForDateTime((DateTime)propertyValue, TimeZone);
        }
        else
        {
            str = ODataUriUtils.ConvertToUriLiteral(propertyValue, ODataVersion.V4);
        }

        // base64 encode
        byte[] bytes = Encoding.UTF8.GetBytes(str);
        string etagValueText = Convert.ToBase64String(bytes);
        builder.Append(etagValueText);
    }

    builder.Append('\"');
    string tag = builder.ToString();
    return new EntityTagHeaderValue(tag, isWeak: true);
}

public IDictionary<string, object> ParseETag(EntityTagHeaderValue etagHeaderValue)
{
    string tag = etagHeaderValue.Tag.Trim('\"');

    // split etag
    string[] rawValues = tag.Split(Separator);
    IDictionary<string, object> properties = new Dictionary<string, object>();
    for (int index = 0; index < rawValues.Length; index++)
    {
        string rawValue = rawValues[index];

        // base64 decode
        byte[] bytes = Convert.FromBase64String(rawValue);
        string valueString = Encoding.UTF8.GetString(bytes);
        object obj = ODataUriUtils.ConvertFromUriLiteral(valueString, ODataVersion.V4);

        properties.Add(index.ToString(CultureInfo.InvariantCulture), obj);
    }

    return properties;
}

public static string GetUriRepresentationForDateTime(DateTime dateTime, TimeZoneInfo timeZoneInfo)
{
    object value = ConvertUnsupportedDateTime(dateTime, timeZoneInfo);
    return ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V4);
}

internal static DateTimeOffset ConvertUnsupportedDateTime(DateTime value, TimeZoneInfo timeZoneInfo)
{
    if (timeZoneInfo == null)
    {
        timeZoneInfo = TimeZoneInfo.Local;
    }

    if (value.Kind == DateTimeKind.Utc || value.Kind == DateTimeKind.Local)
    {
        return new DateTimeOffset(value.ToUniversalTime()).ToOffset(timeZoneInfo.BaseUtcOffset);
    }

    DateTimeOffset dateTimeOffset = new DateTimeOffset(value, timeZoneInfo.GetUtcOffset(value));
    return dateTimeOffset.ToUniversalTime().ToOffset(timeZoneInfo.BaseUtcOffset);
}
}

2。配置ETag处理程序

MyODataEtagHandler etagHandler = new MyODataEtagHandler();
etagHandler.TimeZone = TimeZoneInfo.Local;
config.SetETagHandler(etagHandler);
config.MapODataServiceRoute("odata", "api", GetModel());

3.然后您可以查询实体集。

例如:

{
  "@odata.context":"http://localhost/api/$metadata#abs","value":[
    {
      "@odata.etag":"W/\"MjAxNS0wMi0xNVQxMTozMDo1NC41ODU3MTc1KzA4OjAw\"","id":1,
"name":"ab #1","rowCreatedDT":"2015-02-15T11:30:54.5857175+08:00","rowLastModifi
edDT":"2015-02-15T11:30:54.5857175+08:00","user_id1":11,"user_id2":21
    },{
      "@odata.etag":"W/\"MjAxNS0wMi0xNVQxMTozMDo1NC41ODU3MTc1KzA4OjAw\"","id":2,
"name":"ab #2","rowCreatedDT":"2015-02-15T11:30:54.5857175+08:00","rowLastModifi
edDT":"2015-02-15T11:30:54.5857175+08:00","user_id1":12,"user_id2":22
    },{
      "@odata.etag":"W/\"MjAxNS0wMi0xNVQxMTozMDo1NC41ODU3MTc1KzA4OjAw\"","id":3,
"name":"ab #3","rowCreatedDT":"2015-02-15T11:30:54.5857175+08:00","rowLastModifi
edDT":"2015-02-15T11:30:54.5857175+08:00","user_id1":13,"user_id2":23
    },{
      "@odata.etag":"W/\"MjAxNS0wMi0xNVQxMTozMDo1NC41ODU3MTc1KzA4OjAw\"","id":4,
"name":"ab #4","rowCreatedDT":"2015-02-15T11:30:54.5857175+08:00","rowLastModifi
edDT":"2015-02-15T11:30:54.5857175+08:00","user_id1":14,"user_id2":24
    },{
      "@odata.etag":"W/\"MjAxNS0wMi0xNVQxMTozMDo1NC41ODU3MTc1KzA4OjAw\"","id":5,
"name":"ab #5","rowCreatedDT":"2015-02-15T11:30:54.5857175+08:00","rowLastModifi
edDT":"2015-02-15T11:30:54.5857175+08:00","user_id1":15,"user_id2":25
    }
  ]
}

感谢。