Can't change ServiceName using ConfigurationManager.Appsettings in the Initialize method? - windows-services

I modified my ProjectInstaller class to append the ServiceName with a value from the app.config file:
private void InitializeComponent()
{
System.ServiceProcess.ServiceInstaller serviceInstaller;
this.serviceProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller();
serviceInstaller = new System.ServiceProcess.ServiceInstaller();
//
// serviceInstaller1
//
serviceInstaller.ServiceName = "Varicent Upload Service - " + ConfigurationManager.AppSettings["DataSetName"].ToString();
serviceInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
//
// serviceProcessInstaller1
//
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller,
serviceInstaller});
}
My app.config file has the following:
<appSettings>
<add key="DataSetName" value="Activities"/>
</appSettings>
The problem is that the ConfigurationManager.AppSettings["DataSetName"].ToString() throws a NULL exception. Is there a limitation on when you can make a call to the app.config file?

Related

Consuming WCF Data Service EF , Failed to SaveChange()

I am consuming WCF Data Service as Following:
DataMan.ContextWrapper context = new DataMan.ContextWrapper(new Uri("http://localhost:2060/PCM/DataMan.svc/rest/"));
DataMan.Report newReport = DataMan.Report.CreateReport("123123123123", DateTime.Now, "999.199905171156550187000.25");
newReport.Title = "tt";
newReport.StudyAcDate = Convert.ToDateTime("2016-05-04 12:09:00");
newReport.Body = "asdasd";
newReport.Auther = "ali.h";
newReport.ApproverComment = "cm";
newReport.Approver = "admin";
context.AddToReports(newReport);
DataServiceResponse response = context.SaveChanges();
but after calling SaveChange() I have got the following error:
The server encountered an error processing the request. The exception message is 'Incoming message for operation 'ProcessRequestForMessage' (contract 'IRequestHandler' with namespace 'http://tempuri.org/') contains an unrecognized http body format value 'Xml'. The expected body format value is 'Raw'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.'. See server logs for more details.
and my WCF Data Service is as following:
public class ContextWrapper : DataAccessDbContext
{
public ContextWrapper() : base("connection string")
{
}
}
[JSONPSupportBehavior]
public class DataMan : EntityFrameworkDataService<ContextWrapper>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetEntitySetAccessRule("Studies", EntitySetRights.None);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.UseVerboseErrors = true; // TODO - Remove for production?
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
protected override void HandleException(HandleExceptionArgs args)
{
base.HandleException(args);
}
}
I also implemented and configured WebContentTypeMapper to bypass mentioned Error as following:
public class ContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType(string contentType)
{
return WebContentFormat.Raw;
}
}
Custom binding:
<binding name="XmlMapper">
<webMessageEncoding webContentTypeMapperType="MARCO.SOA.PCMServiceLib.ContentTypeMapper,MARCO.SOA.PCMServiceLib.Core"/>
<httpTransport manualAddressing="true"/>
</binding>
</customBinding>
Service endpoint:
<service behaviorConfiguration="Commom2.Behavior" name="MARCO.SOA.PCMServiceLib.DataMan">
<endpoint address="rest" behaviorConfiguration="Rest.Behavior" binding="webHttpBinding"
bindingConfiguration="XmlMapper" contract="System.Data.Services.IRequestHandler">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:2060/PCM/DataMan.svc"/>
</baseAddresses>
</host>
</service>
but it still get exception, I think something went wrong with my configuration.
Any help would be truly appreciated.
Thanks in advance.
okay, after much trouble I finally solved the problem,
so we need to initiate factory property for serviceActivation
So my relative address was:
<serviceHostingEnvironment>
<serviceActivations>
.
.
.
<add relativeAddress="DataMan.svc" service="MARCO.SOA.PCMServiceLib.DataMan"/>
.
.
.
</serviceActivations>
</serviceHostingEnvironment>
and I have changed it to
<serviceHostingEnvironment>
<serviceActivations>
.
.
.
<add relativeAddress="DataMan.svc" service="MARCO.SOA.PCMServiceLib.DataMan" factory="System.Data.Services.DataServiceHostFactory, Microsoft.Data.Services, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
.
.
.
</serviceActivations>
</serviceHostingEnvironment>
now everything is now working nice.
more info about DataServiceHostFactory
Note:
By this we don't need to override GetMessageFormatForContentType of WebContentTypeMapper and force it to return WebContentFormat.Raw or another content format and don't need any customBinding in config file.
Thanks to all.

Writing to .config files

I am having an issue somewhat similar to this question: C#: Config file error
BACKGROUND
My situation is this: I am using NLog and I have setup a Database target. My app shows an installation page on first run from which I build a connection string for other purposes but would also like to save that same connection string to the NLog.config file. After much searching it would appear that NLog can be changed programatically, but for whatever reason cannot save the changes back to the .config file. Therefore, my plan was to simply do the following:
WHAT I HAVE TRIED
Change the connectionString attribute to simply be connectionStringName instead. Example: connectionStringName="NLogConnection"
Move the <connectionStrings> element from my Web.config to a separate file: ConnectionStrings.config.
Update web.config accordingly:
<connectionStrings configSource="ConnectionStrings.config" />
Write code as follows:
string filePath = HostingEnvironment.MapPath(Path.Combine(httpRequest.ApplicationPath, "ConnectionStrings.config"));
var fileMap = new ExeConfigurationFileMap
{
ExeConfigFilename = filePath
};
var configFile = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
configFile.ConnectionStrings.ConnectionStrings["NLogConnection"].ConnectionString = connectionString;
configFile.Save();
OUTCOME
Seemed like a nice plan. However.. the code above throws an error about not having a <configuration> tag and if I add that tag, the site throws an error about the tag being there! No win situation here... does anyone have any ideas on how to solve this one? Ideally it would be nice if there was a way to properly modify external .config files which are only a part of the main web config. I may have to revert to manually reading/writing the raw XML.. but I would prefer not to if there's a better/more elegant way.
SOLUTION
Many thanks to #Julian; I now have a working solution. I added this in my Global.asax:
private static void TryUpdateNLogConnectionString(string connectionString)
{
try
{
var target = LogManager.Configuration.FindTargetByName("database");
DatabaseTarget databaseTarget = null;
var wrapperTarget = target as WrapperTargetBase;
// Unwrap the target if necessary.
if (wrapperTarget == null)
{
databaseTarget = target as DatabaseTarget;
}
else
{
databaseTarget = wrapperTarget.WrappedTarget as DatabaseTarget;
}
databaseTarget.ConnectionString = connectionString;
}
catch { }
}
You can change settings programmatically in NLog, but you can't serialize those settings to the XML, yet.
What you can do:
Save the setting to the <appSettings> when changed
read the <appSettings> when needed.
eg
using System.Web.Configuration;
using System.Configuration;
Configuration config = WebConfigurationManager.OpenWebConfiguration("/");
config.AppSettings.Settings["NlogConnectionString"].Value = "NewValue";
config.Save(ConfigurationSaveMode.Modified);
Edit the connectionstring when needed in NLog:
DatabaseTarget databaseTarget = LogManager.Configuration.FindTargetByName(targetName) as DatabaseTarget;
databaseTarget.ConnectionString = System.Configuration.ConfigurationManager.AppSettings["NlogConnectionString"];

How to set Password and Username in web.config

In my MVC Application I use the connection string is set in the Web.config via
Private connectionString As String = ConfigurationManager.ConnectionStrings("DBCS").ConnectionString
and have no problems with my db connection. But since I need a password and username to log into my database I hardcoded that in the web.config
<connectionStrings>
<add name="DBCS" connectionString="server=win\SQLExpress;database=myDb; uid=myUsername;password=myPassword" providerName="System.Data.SqlClient" />
</connectionStrings>
I am looking for a way to send the password and username from the userinterface to the config.web file first off I thought the ConfigurationManager Class should provide a property for that but I cannot find something. Can anyone explain to me how to do this?
You can save this value in app settings:
<appSettings>
<add key="DBCS" value="Data Source=win\SQLExpress;Initial Catalog=myDb;User ID={0};Password={1}" />
</appSettings>
and then do the following:
using System.Data.SqlClient;
public void DoDatabaseOperations(string _Username, string _Password)
{
string connetionString = null;
SqlConnection cnn ;
connetionString = string.Format(ConfigurationManager.AppSettings("DBCS"), _Username, _Password);
cnn = new SqlConnection(connetionString);
try
{
cnn.Open();
// your code here
cnn.Close();
}
catch (Exception ex)
{
// handle exception
}
}
VB.NET Equivalent:
Imports System.Data.SqlClient
Public Sub DoDatabaseOperations(_Username As String, _Password As String)
Dim connetionString As String = Nothing
Dim cnn As SqlConnection
connetionString = String.Format(ConfigurationManager.AppSettings("DBCS"), _Username, _Password)
cnn = New SqlConnection(connetionString)
Try
cnn.Open()
' your code here
cnn.Close()
' handle exception
Catch ex As Exception
End Try
End Sub

Entity Framework with oracle can´t change connection string

I´m using Entity Framework (latest Version) with the Oracle Driver (latest Version) in an ASP.NET MVC 5 Application. I want to set the connection string for my model during runtime, but every time I do it receives the data from the table that I used to create the model. It´s the same when I change the connection string in the web.config. Does anybody know why it behaves this way?
this is how i create the connection string:
public static string CreateConnectionString(string userName, string service)
{
const string providerName = "Oracle.ManagedDataAccess.Client";
OracleConnectionStringBuilder oraBuilder = new OracleConnectionStringBuilder();
oraBuilder.DataSource = service + ":1521/" + service;
oraBuilder.UserID = userName;
oraBuilder.Password ="xxx";
oraBuilder.PersistSecurityInfo = true;
EntityConnectionStringBuilder efBuilder = new EntityConnectionStringBuilder();
efBuilder.Metadata = "res://*/Model2.csdl|res://*/Model2.ssdl|res://*/Model2.msl";
efBuilder.Provider = providerName;
efBuilder.ProviderConnectionString = oraBuilder.ConnectionString;
return efBuilder.ConnectionString;
}
this is the overload of the model´s constructor:
public Entities(string connectionString)
: base(connectionString)
{
}
this ist my connection string:
try this connection string:
<connectionStrings>
<add name="VoccDbContext" connectionString="metadata=res://*/Entities.Vocc.VoccModel.csdl|res://*/Entities.Vocc.VoccModel.ssdl|
res://*/Entities.Vocc.VoccModel.msl;provider=Oracle.DataAccess.Client;provider connection string="DATA SOURCE=sameDbName;PASSWORD=somePass;USER ID=someUser;""providerName="System.Data.EntityClient" />
</connectionStrings>
DIRECTORY_SERVERS=(tnsnames.somesite.org:389:636)
DEFAULT_ADMIN_CONTEXT="dc=site,dc=com"
DIRECTORY_SERVER_TYPE=OID
here( LDAP.ORA file) to be modified with correct LDAP Parameters
Do not edit XXXModels.cs. Try to edit XXXModels.Context.tt.
Add following code after public <#=code.Escape(container)#>()...}
public <#=code.Escape(container)#>(string connectionString)
: base(connectionString)
{
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
this.Configuration.LazyLoadingEnabled = false;
<#
}
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
// Note: the DbSet members are defined below such that the getter and
// setter always have the same accessibility as the DbSet definition
if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
{
#>
<#=codeStringGenerator.DbSetInitializer(entitySet)#>
<#
}
}
#>
}

Calling HttpHandler from an area

I have a simple asp.net mvc 4 website with an admin area. I have defined a custom http handler to handle uploads from a plupload script that runs in the admin area. Here is the code for the handler :
public class CategoryImageUploadHandler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
try
{
HttpPostedFile file = context.Request.Files[0];
var categoryID = context.Request["categoryID"];
var fileName = Path.GetFileName(file.FileName);
var parentPath = HttpContext.Current.Server.MapPath("~/Files/Content");
var targetDir = Path.Combine(parentPath, categoryID);
var targetFile = Path.Combine(targetDir, fileName);
//check if Directory exists
if (Directory.Exists(targetDir))
file.SaveAs(targetFile);
else
{
Directory.CreateDirectory(targetDir);
file.SaveAs(targetFile);
}
context.Response.Write("/"+categoryID+"/"+fileName);
}
catch (Exception ex)
{
context.Response.Write("0");
context.Response.Write(ex.Message);
}
}
public bool IsReusable
{
get { return false; }
}
}
This is sitting in the Handlers/ directory of the main site. This is how I have registered the handler :
<system.webserver>
<add name="CategoryImageUploadHandler path="Admin/CategoryImageUploadHandler.ashx" verb="*" type="Hitaishi.Web.Handlers.CategoryImageUploadHandler, Hitaishi.Web"/>
<system.web>
<httpHandlers>
<add path="Admin/CategoryImageUploadHandler.ashx" verb="*" type="Hitaishi.Web.Handlers.CategoryImageUploadHandler, Hitaishi.Web"/>
Routeconfig.cs:
routes.IgnoreRoute("{*allashx}", new { allashx = #".*\.ashx(/.*)?" });
However, when the plupload sends a POST to the http handler from the Admin area, the call is still picked up by routing as it tries to look for /Admin/CategoryImageUploadHandler.ashx
I have tried playing with slashes to check if the path I am giving is wrong or changing path in the registrations, but nothing seems to work. I am still getting 404 errors.
In a nutshell, I need a way to reference a HttpHandler defined in the main MVC area of the website from another mvc area of the website. Can anyone help with this?
why are you not using routes.MapPageRoute
so probably you can do
routes.MapPageRoute(
"CategoryImageUploaded",
"Admin/CategoryImageUploadHandler.ashx",
"~/Admin/CategoryImageUploadHandler.ashx")
//please verify you path to .ashx before trying

Resources