Apakah ada cara untuk melakukan "Ganti Atau Masukkan" menggunakan transformasi web.config?

183

Saya menggunakan transformasi web.config seperti yang dijelaskan dalam posting di bawah ini untuk menghasilkan konfigurasi untuk lingkungan yang berbeda.

http://vishaljoshi.blogspot.com/2009/03/web-deployment-webconfig-transformation_23.html

Saya dapat melakukan transformasi "Ganti" dengan mencocokkan pada tombol, misalnya

<add key="Environment" value="Live" xdt:Transform="Replace" xdt:Locator="Match(key)" />

Dan saya bisa melakukan "Sisipan" misalnya

<add key="UseLivePaymentService" value="true" xdt:Transform="Insert" />

Tetapi yang benar - benar bermanfaat bagi saya adalah transformasi ReplaceOrInsert, karena saya tidak selalu dapat bergantung pada file konfigurasi asli yang memiliki / tidak memiliki kunci tertentu.

Apakah ada cara untuk melakukan ini?

Chris Haines
sumber
tautan yang Anda berikan tidak berfungsi seperti sekarang. Apakah Anda memiliki tautan lain untuk memahami konsep dengan mudah?
Ashish-BeJovial
@AshishJain tautannya berfungsi dengan baik untuk saya
Chris Haines

Jawaban:

105

Saya menemukan solusi murah. Itu tidak cantik dan tidak akan bekerja dengan baik jika Anda memiliki banyak elemen yang harus "Ganti Atau Sisipkan".

Lakukan "Hapus" dan kemudian "SisipkanSetelah | SisipkanSebelum".

Sebagai contoh,

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertAfter(/configuration/system.web/authentication)">
  <deny users="?"/>
  <allow users="*"/>
</authorization>
sebuah phu
sumber
17
Jika menggunakan VS2012, sekarang ada solusi yang lebih baik. Lihat di bawah stackoverflow.com/a/16679201/32055
Chris Haines
1
akankah "InsertIfMissing" Sisipkan Dan Ganti jika perlu?
Jessy
Saya lebih suka opsi ini daripada yang lain berkat penggunaan InsertAfter. InsertIfMissing tidak masuk akal jika Anda tetap melakukan Hapus.
Shane Courtrille
125

Sehubungan dengan xdt:Transform="Remove"penggunaan xdt:Transform="InsertIfMissing"dalam VS2012.

<authorization xdt:Transform="Remove" />
<authorization xdt:Transform="InsertIfMissing">
  <deny users="?"/>
  <allow users="*"/>
</authorization>
ADW334034
sumber
Sempurna! Ini yang kami tunggu-tunggu.
Chris Haines
9
Ini sama sekali tidak sesuai permintaan OP.
BradLaney
2
Jawabannya telah diedit untuk menunjukkan dengan lebih jelas bagaimana jawaban itu menjawab pertanyaan awal.
Bon
25
Saya tidak mengerti. Jika Anda menghapusnya, tentu saja itu akan hilang, itu hanya Sisipan pada saat itu, kan?
Chad Schouggins
6
@ChadSchouggins belum tentu: Removetugas hanya menghilangkan kejadian pertama. Beberapa elemen dapat memiliki banyak kejadian. Saya tidak dapat membayangkan bahwa Anda menginginkan ini, tetapi kemudian akan menghapus kejadian pertama dan melewatkan InsertIfMissingtugas. Tapi Anda akan benar jika dia menggunakannya RemoveAll.
Steven Liekens
89

Gunakan InsertIfMissingtransformasi untuk memastikan bahwa pengaturan aplikasi ada.
Kemudian gunakan Replacetransformasi untuk menetapkan nilainya.

<appSettings>
  <add key="Environment" xdt:Transform="InsertIfMissing" xdt:Locator="Match(key)" />
  <add key="Environment" value="Live" xdt:Transform="Replace" xdt:Locator="Match(key)" />
</appSettings>

Anda juga bisa menggunakan SetAttributes transformasi Replace. Perbedaannya adalah SetAttributestidak menyentuh node anak.

<appSettings>  
  <add key="UseLivePaymentService" xdt:Transform="InsertIfMissing" xdt:Locator="Match(key)" />
  <add key="UseLivePaymentService" value="true" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
</appSettings>

Teknik-teknik ini jauh lebih baik daripada menghapus + menyisipkan karena node yang ada tidak dipindahkan ke bagian bawah simpul induknya. Node baru ditambahkan di bagian akhir. Node yang ada tetap berada di tempatnya di file sumber.

Jawaban ini hanya berlaku untuk versi Visual Studio yang lebih baru (2012 atau lebih baru).

Steven Liekens
sumber
7

Metode yang lebih baik bagi saya adalah memasukkan elemen hanya jika tidak ada karena saya hanya mengatur atribut tertentu. Menghapus elemen akan membuang atribut lain dari elemen utama jika ada.

contoh: web.config (tanpa elemen)

<serviceBehaviors>
    <behavior name="Wcf.ServiceImplementation.AllDigitalService_Behavior">
        <serviceMetadata httpGetEnabled="true" />
    </behavior>
</serviceBehaviors>

web.config (dengan elemen)

<serviceBehaviors>
    <behavior name="Wcf.ServiceImplementation.AllDigitalService_Behavior">
        <serviceDebug httpsHelpPageEnabled="true" />
        <serviceMetadata httpGetEnabled="true" />
    </behavior>
</serviceBehaviors>

Menggunakan Locator dengan ekspresi XPath, saya menambahkan node jika tidak ada dan kemudian menetapkan atribut saya:

<serviceDebug xdt:Transform="Insert"
  xdt:Locator="XPath(/configuration/system.serviceModel/behaviors/serviceBehaviors/behavior[not(serviceDebug)])" />
<serviceDebug includeExceptionDetailInFaults="true" xdt:Transform="SetAttributes" />

kedua file web.config yang dihasilkan memiliki includeExceptionDetailInFaults = "true" dan yang kedua mempertahankan atribut httpsHelpPageEnabled di mana metode hapus / sisipkan tidak akan.

Dan
sumber
1
Saya suka ide ini, tetapi saya mendapatkan kesalahan jika elemen sudah ada "Tidak ada elemen dalam dokumen sumber yang cocok ...". Artinya, jika ada, "tidak" gagal, jadi itu adalah kesalahan.
selamat tinggal
Ini adalah teknik yang Anda butuhkan ketika Anda menggunakan versi XDT yang tidak mendukung elemen "InsertIfMissing" (ish) yang baru.
IanBru