2017-05-08 164 views
1

我試圖複製性在我的代碼屬性集找不到方法,異常System.ArgumentException

這裏更新供應商是我的供應商更新方法

public bool UpdateSupplier(PurchaseOrderHeader header, string newSupplier) 
    { 
     try 
     { 
      var oldSupplier = GetSupplierForPoHeader(header); 
      Reflection.CopyPropertyValues(oldSupplier, newSupplier); 
      Console.WriteLine($"{oldSupplier} : {newSupplier}"); 
      _context.SaveChanges(); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      Logger.LogException(ex); 
      throw; 
     } 
    } 

這裏是我的更新方法值。

public static void CopyPropertyValues(object source, object destination) 
    { 
     try 
     { 
      var destProperties = destination.GetType().GetProperties(); 

      foreach (var sourceProperty in source.GetType().GetProperties()) 
      foreach (var destProperty in destProperties) 
      { 
       if (destProperty.Name != sourceProperty.Name || 
        !destProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType) || 
        destProperty.Name == "Id") 
        continue; 

       destProperty.SetValue(destination, sourceProperty.GetValue(source, new object[] { }), 
        new object[] { }); 
       break; 
      } 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(@"Inner Exception: "+e.InnerException?.Message); 
      Console.WriteLine(@"Message: "+e.Message); 
     } 
    } 

任何想法?

我檢查了其他堆棧溢出問題,似乎沒有人正在解決我的問題,我是相當新的反思,所以我不知道如何去解決這個問題。

+0

在哪一行是拋出的錯誤?在if和break之間? –

+1

'var destProperties = destination.GetType()。GetProperties();'你得到所有的屬性,而不僅僅是具有setter的屬性。請參閱http://stackoverflow.com/questions/3390358/using-reflection-how-do-i-detect-properties-that-have-setters。 –

回答

1

檢查這些:

  • 嘗試設置該屬性需要有一個二傳手。 (PropertyInfo.CanSet
  • 是setter私有的,你必須告訴SetValue方法,它應該使用BindingFlags(或使用它們的代碼如下)來設置它。
  • 是屬性派生和setter私人,你仍然想要設置它,你需要從​​獲得屬性,因爲在派生類中找不到私有成員(但屬性是由於公共getter )或使用它們編碼波紋管。

如果你想訪問私有制定者,你會發現這個有用:

var setterMethod = propertyInfo.GetSetMethod(true); 
setterMethod.Invoke(instance, new [] { value }); 

請注意,你也可以得到索引器作爲屬性。他們有一個額外的論點。你可能也想排除他們(!propertyInfo.GetIndexParameters().Any())。

+0

你是對的,我有一個沒有被映射的屬性,所以我實際上並沒有意識到我使用它來做任何事情,但是refliction不會忽略[NotMapped]屬性,所以現在我硬編碼了一個修復程序,謝謝幫助。 –

+0

您可以使用反射自己訪問屬性,然後由代碼支持。 :-) –

0

GetProperties()方法有一個重載,它使用BindingFlags指定如何進行反射搜索;

source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.Public) // ... & and other flags you need 
0

此錯誤表示您的屬性沒有任何設置方法。你有這個固定的幾種方法,但我會指出其中只有2:

1在性能實現set方法:

public <type> PropertyName 
{ 
    get; 
    set; /// <-- here 
} 

2 - 使用這個屬性的支持字段: 每個屬性都有它是自己的後盾領域,與實現方法不同。如果您將您的財產實施爲:public <type> Name {get;set;},那麼您的支持字段的名稱是<Name >k__BackingField,您可以隨意更改。要檢索後臺使用此代碼:

meObject.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(prop => prop.Name.EndsWith("__BackingField")); 

這將返回您的自動屬性的後臺字段。


對您的問題做出最終結論。不要使用GetProperties(),因爲屬性總是有一些後臺字段。改爲使用GetFields(),因爲所有屬性都在做的只是修改其支持字段或返回(幾乎)常量值。

Online example

相關問題