Konfiguracja aplikacji Sharepoint przechowywana w liście
Opublikowano: 2019-08-27 , wyświetlono: 3687
Rozpoczynając tworzenie własnych aplikacji działających na platformie Sharepoint informacje o adresie witryny, litach z których pobierane były dane i inne dane potrzebne aplikacji na sztywno zaszywałem w kodzie. Później zacząłem tworzyć szablon listy, której kolumny odpowiadały poszczególnym zmiennym konfiguracji. To już dawało pewną elastyczność, jednak z czasem wyszły na jaw pewne problemy w przypadku rozbudowy aplikacji i dodawaniu nowych pół konfiguracji.
W którymś momencie pomyślałem by stworzyć rozwiązanie, które będzie mogło być użyte w każdej z aplikacji. Podstawą miała być lista składająca się z dwóch pól: tytułu i wartości. Do tego klasa pozwalająca na odczytywanie przechowywanych w liście informacji i udostępnianie ich aplikacji.
Poniżej format listy użytej do przechowywania konfiguracji
<Fields>
<Field ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"
Type="Text" Name="Title" DisplayName="$Resources:core,Title;"
Required="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3"
StaticName="Title" MaxLength="255" />
<Field Name="ParamValue" ID="{53060f42-51e9-4156-b003-33df0b216305}"
DisplayName="ParamValue"
StaticName="ParamValue" Type="Text" />
</Fields>
Następny etap to klasa, która odczytuje wartości z listy, przechowuje je i umożliwia do nich dostęp. Poniżej jej kod.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
namespace ChinaSoftLibrary.Util
{
public class AppParameters
{
private Dictionary<string, string> _items;
private const string SpKeyField = "Title";
private const string SpValueField = "ParamValue";
public string FieldKeyName { get; set; }
public string FieldValueName { get; set; }
public AppParameters()
{
init();
}
/// <summary>
/// load configuration parameters from sharepoint list
/// </summary>
/// <param name="siteUrl"></param>
/// <param name="listName"></param>
public void LoadSharepoint(string siteUrl, string listName)
{
try
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPList paramList = web.Lists[listName];
SPListItemCollection items = paramList.GetItems();
foreach (SPListItem item in items)
{
try { _items.Add(item[FieldKeyName].ToString(), item[FieldValueName].ToString()); }
catch { }
}
}
}
});
}
catch { }
}
public string GetValue(string key)
{
string v = "";
try { v = _items[key]; }
catch { v = ""; }
return (v);
}
public void SetValue(string key, string value)
{
try { _items[key] = value; }
catch {}
}
public string ToHtmlString()
{
string s = "";
s += "Configuration items <br/>" + System.Environment.NewLine;
foreach (var item in _items)
{
s += item.Key.ToString();
s += " ; ";
s += item.Value.ToString();
s += "; <br/>" + System.Environment.NewLine;
}
return (s);
}
private void init()
{
_items = new Dictionary<string, string>();
this.FieldKeyName = SpKeyField;
this.FieldValueName = SpValueField;
}
}
}
By mieć możliwość budowania rozwiązania w środowisku testowym i bez problemu przenosić je na produkcyjne podjąłem decyzję o użyciu wzorca fasady. Najpierw zdefiniowałem interfejs konfiguracji
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChinasoftServiceCore.Domain
{
public interface IAppConfiguration
{
string ConfigList { get; set; }
string SiteUrl { get; set; }
string GetDictionaryListTitle();
string GetRequestListTitle();
string GetResourceListTitle();
string GetCustomerListTitle();
string GetRequestEditFormUrl();
string GetRelativeEditFormUrl();
string GetSmtpHost();
int GetSmtpPort();
string GetSmtpFrom();
string GetSmtpReply();
bool GetSmtpAnonymous();
string GetSmtpUser();
string GetSmtpPassword();
string GetValue(string name);
bool IsDebug();
void SetValue(string name, string value);
string ToHtmlString();
}
}
A potem zająłem się jego implementacją. Dzięki takiemu podejściu konfiguracja może być przechowywana w pliku tekstowym, bazie danych lub statycznie w kodzie. Ważne by aplikacji podać odpowiedni obiekt, który implementuje interfejs IAppConfiguration. W poniższym przykładzie oczywiście implementacja korzysta z listy Sharepoint i wcześniej przedstawionej klasy AppParameters.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ChinaSoftLibrary.Util;
namespace ChinasoftServiceCore.Domain
{
public class AppConfiguration : IAppConfiguration
{
private const string DevFile = @"C:\AppConfigurationFiles\site-sos.txt";
private string _siteUrl;
private string _configList;
private AppParameters _parameters;
public AppConfiguration()
{
_parameters = new AppParameters();
_parameters.FieldKeyName = "Title";
_parameters.FieldValueName = "ParamValue";
_siteUrl = @"http://sharepoint";
_configList = @"Konfiguracja";
// dev version
if (File.Exists(DevFile))
_siteUrl = @"http://sp-dev-server/site/DevTeamSite";
_parameters.LoadSharepoint(_siteUrl, _configList);
}
public AppConfiguration(string siteUrl, string configList)
{
_parameters = new AppParameters();
_parameters.FieldKeyName = "Title";
_parameters.FieldValueName = "ParamValue";
_siteUrl = siteUrl;
_configList = configList;
_parameters.LoadSharepoint(_siteUrl, _configList);
}
public string GetRequestListTitle()
{
string title = "";
title = GetValue("ListRequest");
return (title);
}
public string GetDictionaryListTitle()
{
string title = "";
title = GetValue("ListDictionary");
return (title);
}
public string GetCustomerListTitle()
{
string title = "";
title = GetValue("ListCustomer");
return (title);
}
public string GetRequestEditFormUrl()
{
string url = "";
url = GetValue("SiteUrl") + GetValue("RequestEditForm");
return (url);
}
public string GetRelativeEditFormUrl()
{
string url = "";
Uri uri = new Uri(GetValue("SiteUrl"));
url = uri.LocalPath + GetValue("RequestEditForm");
return (url);
}
public string GetSystemEmail()
{
string url = "";
url = GetValue("SystemEmail");
return (url);
}
public string GetSmtpHost()
{
return (GetValue("SmtpHost"));
}
public int GetSmtpPort()
{
int v = Function.GetInt32(GetValue("SmtpPort"));
return (v);
}
public string GetSmtpFrom()
{
return (GetValue("SmtpFrom"));
}
public string GetSmtpReply()
{
return (GetValue("SmtpReply"));
}
public bool GetSmtpAnonymous()
{
bool result = false;
int v = Function.GetInt32(GetValue("SmtpAnonymous"));
if (v == 1)
result = true;
return (result);
}
public string GetSmtpUser()
{
return (GetValue("SmtpUser"));
}
public string GetSmtpPassword()
{
return (GetValue("SmtpPassword"));
}
public bool IsDebug()
{
bool dev = false;
if (_siteUrl.StartsWith(@"http://sp-dev-server /"))
dev = true;
return (dev);
}
public string GetValue(string name)
{
return (_parameters.GetValue(name));
}
public void SetValue(string name, string value)
{
_parameters.SetValue(name, value);
}
public string ToHtmlString()
{
string s = "";
s += "App Configuration parameters <br/>" + System.Environment.NewLine;
s += _parameters.ToHtmlString();
return (s);
}
#region Properties
public string SiteUrl
{
get { return _siteUrl; }
set { _siteUrl = value; }
}
public string ConfigList
{
get { return _configList; }
set { _configList = value; }
}
#endregion
}
}
Podsumowanie
To rozwiązanie na tyle sprawdza się u mnie, że na razie nie potrzebowałem czegoś więcej. Tutaj powinienem tez napisać parę słów na temat jak taka konfiguracja jest przekazywana aplikacji. Ja w każdym WebPart’cie definiuje zawsze dwa parametry:
CfgSiteUrl – adres url witryny, gdzie jest konfiguracja aplikacji
CfgListName – nazwa listy, w której przechowywana jest konfiguracja
Tutaj mogę odesłać do artykułu ASP.NET architektura dla formularzy ...
gdzie w prezenterze użyty jest obiekt konfiguracji i przedstawiony sposób korzystania z niego.