第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

為什么 Delta.Patch 不會(huì)將字節(jié)數(shù)組更新為空值?

為什么 Delta.Patch 不會(huì)將字節(jié)數(shù)組更新為空值?

C#
慕無(wú)忌1623718 2023-09-24 16:12:20
我的對(duì)象模型有一個(gè)用于存儲(chǔ)圖像的字節(jié)數(shù)組。當(dāng)我嘗試通過(guò)Delta.Patch將此字節(jié)數(shù)組更新為新值時(shí),它工作得很好,但是當(dāng)我嘗試將其更新為 null 時(shí),它失敗了。這是我正在查看的代碼行update.Patch(entity);如果我查看該update對(duì)象,我可以看到其中update.ChangedProperties包含我的圖像屬性,因此它知道它知道應(yīng)該更新。我還可以看到它update._instance包含圖像字段具有空值的對(duì)象實(shí)例,并且我可以使用 Fiddler 來(lái)查看更改后的值作為空值發(fā)送。entity但是,當(dāng)我在調(diào)用后查看對(duì)象.Patch時(shí),新值應(yīng)該為空,字節(jié)數(shù)組不會(huì)更新。Delta 中的其他更新得到正確更新,但此字節(jié)數(shù)組除外。可能是什么原因造成的?我對(duì) OData 還很陌生,不確定我是否在這里遺漏了一些明顯的東西。
查看完整描述

1 回答

?
慕仙森

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超8個(gè)贊

我查看了 OData(WebAPI 版本)的源代碼并(可能)發(fā)現(xiàn)了核心問(wèn)題。問(wèn)題也適用于 ASP.NET Core 版本,因?yàn)樗c ASP.NET WebAPI 共享代碼庫(kù)。

問(wèn)題

你調(diào)用Patch(TStructuralType original)方法,方法又調(diào)用CopyChangedValues(TStructuralType original)方法。兩者都是班級(jí)的公共成員Delta<T>

public?void?Patch(TStructuralType?original){
????CopyChangedValues(original);
}

內(nèi)部CopyChangedValues(TStructuralType original)方法是一段處理將值復(fù)制到原始實(shí)例的代碼。代碼迭代PropertyAccessor<TStructuralType>數(shù)組并調(diào)用Copy(TStructuralType from, TStructuralType to)方法。

// For regular non-structural properties at current level.

PropertyAccessor<TStructuralType>[] propertiesToCopy =

? ? ? ? ? ? ? ? this._changedProperties.Select(s => _allProperties[s]).ToArray();

foreach (PropertyAccessor<TStructuralType> propertyToCopy in propertiesToCopy)

{

? ? propertyToCopy.Copy(_instance, original);

}

在里面Copy(TStructuralType from, TStructuralType to)實(shí)現(xiàn)PropertyAccessor<TStructuralType>你會(huì)發(fā)現(xiàn)對(duì)abstract的調(diào)用SetValue(TStructuralType instance, object value)。


public void Copy(TStructuralType from, TStructuralType to)

{

? ? if (from == null)

? ? {

? ? ? ? throw Error.ArgumentNull("from");

? ? }

? ? if (to == null)

? ? {

? ? ? ? throw Error.ArgumentNull("to");

? ? }

? ? SetValue(to, GetValue(from));

}

這個(gè)方法是通過(guò)FastPropertyAccessor<TStructuralType>類(lèi)來(lái)實(shí)現(xiàn)的。


public override void SetValue(TStructuralType instance, object value)

{

? ? if (instance == null)

? ? {

? ? ? ? throw Error.ArgumentNull("instance");

? ? }


? ? if (_isCollection)

? ? {

? ? ? ? DeserializationHelpers.SetCollectionProperty(instance, _property.Name, edmPropertyType: null,

? ? ? ? ? ? value: value, clearCollection: true);

? ? }

? ? else

? ? {

? ? ? ? _setter(instance, value);

? ? }

}

重要的代碼行是if (_isCollection). 該布爾標(biāo)志在構(gòu)造函數(shù)中設(shè)置并調(diào)用類(lèi)IsCollection()中的靜態(tài)方法TypeHelper。


public FastPropertyAccessor(PropertyInfo property)

? ? : base(property)

{

? ? _property = property;

? ? _isCollection = TypeHelper.IsCollection(property.PropertyType);


? ? if (!_isCollection)

? ? {

? ? ? ? _setter = PropertyHelper.MakeFastPropertySetter<TStructuralType>(property);

? ? }

? ? _getter = PropertyHelper.MakeFastPropertyGetter(property);

}

在IsCollection(Type clrType)我們遍歷調(diào)用IsCollection(this Type type, out Type elementType).


public static bool IsCollection(Type clrType)

{

? ? Type elementType;

? ? return TypeHelper.IsCollection(clrType, out elementType);

}

以下是注釋后面的重要幾行// see if this type should be ignored.(這很奇怪,可能表明有人忘記完成他已經(jīng)開(kāi)始的事情),其中僅排除string( ) 。char[]其他數(shù)組(包括byte[])會(huì)跳到以下代碼,該代碼會(huì)積極評(píng)估 byte[](以及任何其他數(shù)組類(lèi)型),因?yàn)檫@些類(lèi)型正在實(shí)現(xiàn)IEnumerable<T>接口。


public static bool IsCollection(Type clrType, out Type elementType)

{

? ? if (clrType == null)

? ? {

? ? ? ? throw Error.ArgumentNull("clrType");

? ? }


? ? elementType = clrType;


? ? // see if this type should be ignored.

? ? if (clrType == typeof(string))

? ? {

? ? ? ? return false;

? ? }


? ? Type collectionInterface

? ? ? ? = clrType.GetInterfaces()

? ? ? ? ? ? .Union(new[] { clrType })

? ? ? ? ? ? .FirstOrDefault(

? ? ? ? ? ? ? ? t => TypeHelper.IsGenericType(t)

? ? ? ? ? ? ? ? ? ? ? ? && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));


? ? if (collectionInterface != null)

? ? {

? ? ? ? elementType = collectionInterface.GetGenericArguments().Single();

? ? ? ? return true;

? ? }


? ? return false;

}

如果我們跳回方法實(shí)現(xiàn),我們最終會(huì)在類(lèi)中SetValue(TEntityType entity, object value)調(diào)用。DeserializationHelpers.SetCollectionProperty(entity, _property.Name, edmPropertyType: null, value: value, clearCollection: true);DeserializationHelpers


if (_isCollection)

{

? ? DeserializationHelpers.SetCollectionProperty(instance, _property.Name, edmPropertyType: null,

? ? ? ? value: value, clearCollection: true);

}

很明顯,此方法的實(shí)現(xiàn)非常具有防御性,可以避免在集合值為 時(shí)拋出異常null。該方法的第一行是,并且在要執(zhí)行的代碼塊之后if (value != null)沒(méi)有任何塊或代碼。else我們可以從字面上說(shuō),對(duì)于每個(gè)實(shí)現(xiàn) 的類(lèi)型,空值都會(huì)被忽略IEnumerable<T>,因此不會(huì)被設(shè)置。


internal static void SetCollectionProperty(object resource, string propertyName,

? ? IEdmCollectionTypeReference edmPropertyType, object value, bool clearCollection)

{

? ? if (value != null)

? ? {

? ? ? ? IEnumerable collection = value as IEnumerable;

? ? ? ? Contract.Assert(collection != null,

? ? ? ? ? ? "SetCollectionProperty is always passed the result of ODataFeedDeserializer or ODataCollectionDeserializer");


? ? ? ? Type resourceType = resource.GetType();

? ? ? ? Type propertyType = GetPropertyType(resource, propertyName);


? ? ? ? Type elementType;

? ? ? ? if (!TypeHelper.IsCollection(propertyType, out elementType))

? ? ? ? {

? ? ? ? ? ? string message = Error.Format(SRResources.PropertyIsNotCollection, propertyType.FullName, propertyName, resourceType.FullName);

? ? ? ? ? ? throw new SerializationException(message);

? ? ? ? }


? ? ? ? IEnumerable newCollection;

? ? ? ? if (CanSetProperty(resource, propertyName) &&

? ? ? ? ? ? CollectionDeserializationHelpers.TryCreateInstance(propertyType, edmPropertyType, elementType, out newCollection))

? ? ? ? {

? ? ? ? ? ? // settable collections

? ? ? ? ? ? collection.AddToCollection(newCollection, elementType, resourceType, propertyName, propertyType);

? ? ? ? ? ? if (propertyType.IsArray)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? newCollection = CollectionDeserializationHelpers.ToArray(newCollection, elementType);

? ? ? ? ? ? }


? ? ? ? ? ? SetProperty(resource, propertyName, newCollection);

? ? ? ? }

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? // get-only collections.

? ? ? ? ? ? newCollection = GetProperty(resource, propertyName) as IEnumerable;

? ? ? ? ? ? if (newCollection == null)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? string message = Error.Format(SRResources.CannotAddToNullCollection, propertyName, resourceType.FullName);

? ? ? ? ? ? ? ? throw new SerializationException(message);

? ? ? ? ? ? }


? ? ? ? ? ? if (clearCollection)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? newCollection.Clear(propertyName, resourceType);

? ? ? ? ? ? }


? ? ? ? ? ? collection.AddToCollection(newCollection, elementType, resourceType, propertyName, propertyType);

? ? ? ? }

? ? }

}

解決方案1


第一個(gè)可能的解決方案是創(chuàng)建自定義模型綁定程序并處理用于返回空字節(jié)數(shù)組并向模型綁定程序添加類(lèi)null的值。byte[]NullByteArrayModelBinder


免責(zé)聲明:沒(méi)有測(cè)試過(guò),但應(yīng)該可以。


public class NullByteArrayModelBinder : DefaultModelBinder {

? ? public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {

? ? ? ? if(bindingContext.ModelType == typeof(byte[])) {

? ? ? ? ? ? return base.BindModel(controllerContext, bindingContext) ?? new byte[0];

? ? ? ? }


? ? ? ? return base.BindModel(controllerContext, bindingContext);

? ? }

}

這種方法有一個(gè)缺點(diǎn)。OData 的使用者還需要在現(xiàn)在進(jìn)行檢查的array.Length > 0任何地方處理空數(shù)組。array != null


解決方案2


第二個(gè)選項(xiàng)是自定義序列化和反序列化。


序列化:從空array到null=>array.Length > 0 ? array : null;


反序列化:從null到空array=>array ?? new byte[0];


希望能幫助到你!


查看完整回答
反對(duì) 回復(fù) 2023-09-24
  • 1 回答
  • 0 關(guān)注
  • 137 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)