WCF Client Configuration in a Sharepoint Webpart - wcf

I have a Sharepoint 2010 webpart that calls a WCF service.
I've created a service proxy and manually coded the endpoint, see below.
In a conventional WCF client I'd use the config files for the configuration and use transforms when I was buiding for deployment to different environments.
How would I achieve the same through a Sharepoint webpart? I want to put the configuration somewhere that it can be changed for different build configurations.
ie. For a local deployment during testing, then a test server, production. We're trying to automate this as much as possible.
Thanks,
Tim
UPDATE:
I'm aware that you need to put config data in the web.config file in sharepoint. I'm looking for a way to put these config settings into source control and have them automatically populate / deploy for different builds and environments.
namespace CombinedPortal.WcfClient {
public class FrameworkServiceProxy : IFrameworkService
{
private IFrameworkService _proxy;
public FrameworkServiceProxy()
{
var endpoint = new EndpointAddress("http://server:1234/FrameworkService.svc");
var binding = new WSHttpBinding(SecurityMode.None);
_proxy = new ChannelFactory<IFrameworkService>(binding, endpoint).CreateChannel();
}
public Framework GetCurrentFramework(double uniqueLearnerNumber)
{
var fw = _proxy.GetCurrentFramework(uniqueLearnerNumber);
return fw;
}
} }

Your code is C# code which executes on the server.
When then user presses a button on a web part there is a POST back to the Sharepoint web server, where the C# code executes.
It is therefore the web.config of your SharePoint site which is used.

Related

ASP.NET Core (Blazor) Loading customer specific configuration on startup by using Url or Virtual Path

Our application (Server-side Blazor in .NET Core 3.1) runs within IIS on a Windows Server. We have multiple sites in IIS running the same application but with different URL's for different customers.
At startup in (ConfigureServices) we want to load customer configuration for the application from a config file. That way we can have multiple instances of the application running with different configs. Loading this information from the database is not an option because the config contains the details to connect to the database.
In ASP.NET Framework we would have access to the virtual path or (sub)domain name in the Global and then load the configuration based on that information.
We need the same access in our ASP.Net Core applications or another work around.
Is there any to achieve the same result?
A better way to distinguish sites is by URL. The domain name and port bound to each site in IIS will not be repeated.
You can refer to these code to get URL in startup.cs.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,IHostApplicationLifetime lifetime,IServiceProvider serviceProvider)
{
...other code...
lifetime.ApplicationStarted.Register(
() => logAddresses(app.ServerFeatures));
}
static void logAddresses(IFeatureCollection features)
{
var addressFeature = features.Get<IServerAddressesFeature>();
if (addressFeature != null)
{
foreach(var address in addressFeature.Addresses)
{
Console.Out.WriteLine(address);
}
}
}
I was able to grab the Application Pool ID from the Environment and then load the config section as the application config:
var appPool = Environment.GetEnvironmentVariable( "APP_POOL_ID", EnvironmentVariableTarget.Process )
van sectionname = SomeMagicToParseAppPool( appPool );
var config = Configuration.GetSection( sectionName );
if ( config == null ) throw new ApplicationException($" Cannot find config section for {host}");
services.Configure<ApplicationSettings>( config );
This allows me to load a different config for a different site. The only downside is that each application requires their own Application Pool. But that was already a requirement due to a .NET Core ASP.NET app having to run unmanaged in the Application Pool.

appsettings.json and Class libraries that use ConfigurationManager.AppSettings

I'm working on migrating an existing ASP.NET MVC app to ASP.NET Core. The solution has several class libraries (providing data access, services, etc). Many of those class libraries make use of the static ConfigurationManager.AppSettings["..."] way of getting the config from the web.config file.
With the ASP.NET Core app, though, there is no web.config file and it appears ConfigurationManager can't read appsettings.json.
I really like the new configuration system in ASP.NET Core, and am making use of it within the web app.
But is there a "simple" way to migrate these class libraries without having to rewrite them to use the new configuration system? Any basic replacement for the static ConfigurationManager.AppSettings["..."] calls that'll read appsettings.json? (note: we'll eventually rewrite them, but we'd rather do this one piece at a time)
If you're using .NET Standard 2.0 you can add a reference to the System.Configuration.ConfigurationManager NuGet package to get access to appSettings.
You can add an app.Config file (not web.Config) to your ASP.NET Core project to store the appSettings. This will be copied to the output folder and renamed as AppName.dll.config during the project build.
Disclaimer: I didn't try this with a class library, but this worked in LinqPad:
void Main()
{
var config = new Microsoft.Extensions.Configuration.ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
["test"] = "test",
["test2:test"] = "test2"
})
.Build();
foreach (var pair in config.AsEnumerable())
{
// Skips the (test2 = null) pair
if (pair.Value != null)
{
ConfigurationManager.AppSettings.Set(pair.Key, pair.Value);
}
}
ConfigurationManager.AppSettings["test"].Dump();
ConfigurationManager.AppSettings["test2:test"].Dump();
}
You could put something like this in your initialization code.
It sets all of the values available to the System.Configuration app setting collection.

Web Api documentation with swashbuckle

We are currently trying to start writing WebApi services for our products switching from traditional WCF SOAP based services. The challenge we have got is how to provide the api documentation. I came across the SwaggerUi/swash buckle.
One limitation we have is we do not want to host the WebApi services in IIS but in a Windows Service. I am new to Web Api so I might be doing things the wrong way.
So for testing, I am hosting the web api in a console application. I can use the HttpClient to invoke the Get method on the Web Api but I can't access the same if I type the url in a web browser (is this normal for self hosted web api?).
So I installed the Swashbuckle.core nuget package and included the following code in the Startup class (Owin selfhosted).
var config = new HttpConfiguration();
config
.EnableSwagger(c =>
{
c.IncludeXmlComments(GetXmlCommentsPath());
c.SingleApiVersion("v1", "WebApi");
c.ResolveConflictingActions(x => x.First());
})
.EnableSwaggerUi();
private static string GetXmlCommentsPath()
{
var path = $#"{AppDomain.CurrentDomain.BaseDirectory}\WebApiHost.XML";
return path;
}
When I browse to the following location
http://localhost:5000/swagger/ui/index
I get "page cannot be displayed" in IE. Similar for chrome.
Is there anything special that needs to be done when hosting a WebApi in a console/windows service application to get the documentation automatically?
(I have enabled Xml documentation for the project)
I have now attached a test project. Please follow the link below:
Test project
Regards,
Nas
Your problem is not with Swashbuckle, which is configured correctly. Instead it is with the fact that your OWin web app has closed by the time the browser navigates to the swagger URI. Your using statement means that the web app is shut down at the end of it - well before Chrome has opened and navigated to the swagger path. You need to ensure the web app is still running - then your path will be valid (although in your source code you have different ports 9000 and 5000 in your url variables).

Wcf Services in Ektron

I am working with WCF Services in Ektron(rrot/Workarea/Services).
When i am trying to consume the ContentService.svc service in a client using the following code,
ContentManagerClient cClient = new ContentManagerClient();
UpdatedContentService.ContentData data = new UpdatedContentService.ContentData();
data.m_strTitle = "test";
data.m_strHtml = "test";
data.m_intFolderId = 72;
data.m_intUserId = 1;
cClient.Add(data);
I am getting the following error ' The current user does not have permission to carry out this request'.
How can i authenticate an ektron user to perform this action from a client?
The answer you received on the ektron dev forums was a good one. (prior discussion for anyone with the same problem: http://developer.ektron.com/forums/?v=t&t=1280)
You will need to use the Auth service, not the content service. this can be done using the following steps:
Create a proxy object for the web service:
Run .Net tool wsdl.exe against your webservice address, e.g. http://localhost:/Workarea/webservices/AuthService.asmx
Compile into DLL by running “csc /t:library AuthenticationService.cs”:
Add the DLL as a reference to your DLL or console app
Copy the DLL to a Lib folder in your project
Add the DLL as a reference to your DLL or console app
Copy the DLL to a Lib folder in your project
Right click “Add reference” and browse to your created proxy DLL.
Add System.Web.Services as a reference to your DLL or console app
Call the proxy code from your app:
AuthenticationService auth = new AuthenticationService();
IAsyncResult response = auth.BeginisValidUser(username, password, etc...);
a working code example of this can be found at:
http://developer.ektron.com/Templates/CodeLibraryDetail.aspx?id=1036&blogid=116
This example was adapted from the VooDoo engineering example of pulling in the content service:
http://ektroneering.blogspot.com/2011/01/accessing-ektron-from-dll-or-console.html

How to host Web API in Windows Service

I have several resources that I'd like to expose using the WCF Web API. I've investigated the Web API using a Web host but our services all run as Windows Services in production so it's time for me to put the tests aside and verify that everything will work as we need it. I've looked as the sample app here: http://webapicontrib.codeplex.com/SourceControl/changeset/view/2d771a4d6f6f#Samples%2fSelfHosted%2fserver%2fProgram.cs but this does not work with the current version (preview 5) because the HttpConfigurableServiceHost class is not accessible from our code.
One of the most appealing aspects of the Web API is the simple startup using MapServiceRoute and the new WebApiConfiguration. I don't see, however, a way to define the base url and port for the services. Obviously, hosting the service in IIS eliminates this because we configure this information in IIS. How can I accomplish this when hosting in a Windows Service?
It's actually pretty simple. In a nutshell you need to instantiate HttpSelfHostServer and HttpSelfHostConfiguration and then call server.OpenAsync().
public void Start()
{
_server.OpenAsync();
}
public void Stop()
{
_server.CloseAsync().Wait();
_server.Dispose();
}
For an example on how to do this using Windows service project template and/or Topshelf library see my blog post: http://www.piotrwalat.net/hosting-web-api-in-windows-service/
The latest version just uses HttpServiceHost. http://webapicontrib.codeplex.com/SourceControl/changeset/view/ddc499585751#Samples%2fSelfHosted%2fserver%2fProgram.cs
Ping me on twitter if you continue to have problems.
This is the basic code using a console app. A Windows Service uses the same basic approach except you use the start and stop methods to start and stop the service and don't need to block.
static void Main(string[] args)
{
var host = new HttpServiceHost(typeof(PeopleService), "http://localhost:8080/people");
host.Open();
foreach (var ep in host.Description.Endpoints)
{
Console.WriteLine("Using {0} at {1}", ep.Binding.Name, ep.Address);
}
Console.ReadLine();
host.Close();
}
See this blog post.