简体   繁体   English

URL包含$ select时,自定义序列化程序不适用于oData 4的Web API 2

[英]Custom serializer not working in Web API 2 for oData 4 when the URL contains $select

I implemented a custom serializer by inheriting ODataEntityTypeSerializer. 我通过继承ODataEntityTypeSerializer实现了自定义序列化程序。 The serializer sets the value of "MessageStateName" by getting the name of BayStateEnum from the value of "MessageState". 序列化程序通过从“ MessageState”的值获取BayStateEnum的名称来设置“ MessageStateName”的值。 It works well only except when the URL contains "$select". 它仅在URL包含“ $ select”时有效。 I debugged the code and found it was executed and entityInstanceContext.EntityInstance had the correct value, but entityInstanceContext.EdmModel, which was of type System.Web.OData.Query.Expressions.SelectExpandBinder.SelectSome, still had an empty "MessageStateName". 我调试了代码,发现它已执行,并且EntityInstanceContext.EntityInstance具有正确的值,但是类型为System.Web.OData.Query.Expressions.SelectExpandBinder.SelectSome的entityInstanceContext.EdmModel仍然具有空的“ MessageStateName”。

public class CustomEntitySerializer : ODataEntityTypeSerializer
{
    public CustomEntitySerializer(ODataSerializerProvider serializerProvider)
        : base(serializerProvider)
    {
    }
    public override ODataEntry CreateEntry(SelectExpandNode selectExpandNode, EntityInstanceContext entityInstanceContext)
    {
        if (entityInstanceContext.EntityInstance is SmartLinkInfoModel)
        {
            var smartLinkInfo = entityInstanceContext.EntityInstance as SmartLinkInfoModel;
            if (smartLinkInfo.ModemIMEI != null)
            {
                smartLinkInfo.ModemIMEIString = "0x" + string.Join(string.Empty, smartLinkInfo.ModemIMEI.Select(b => (b - 48).ToString()));
            }
            if (smartLinkInfo.SmartLinkHardwareId != null)
            {
                smartLinkInfo.SmartLinkHardwareIdString = "0x" + string.Join(string.Empty, smartLinkInfo.SmartLinkHardwareId.Select(b => b.ToString()));
            }
            if (smartLinkInfo.XbeeSourceId != null)
            {
                smartLinkInfo.XbeeSourceIdString = "0x" + string.Join(string.Empty, smartLinkInfo.XbeeSourceId.Select(b => b.ToString()));
            }
        }
        else if (entityInstanceContext.EntityInstance is BayMessageModel)
        {
            var bayMessage = entityInstanceContext.EntityInstance as BayMessageModel;
            bayMessage.MessageStateName = Enum.GetName(typeof(BayStateEnum), bayMessage.MessageState);
        }
        return base.CreateEntry(selectExpandNode, entityInstanceContext);
    }
}

Your code to change the entityInstanceContext.EntityInstance is right, but it won't change the result of select, you can see 您更改entityInstanceContext.EntityInstance的代码是正确的,但是它不会更改select的结果,您可以看到

object propertyValue = entityInstanceContext.GetPropertyValue(structuralProperty.Name);

in ODataEntityTypeSerializer 's CreateStructuralProperty method, you should override this method, if the structuralProperty.Name is MessageStateName , then use (entityInstanceContext.EntityInstance as BayMessageModel).MessageStateName ODataEntityTypeSerializerCreateStructuralProperty方法中,如果structuralProperty.NameMessageStateName ,则应重写此方法,然后使用(entityInstanceContext.EntityInstance as BayMessageModel).MessageStateName

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM