I've run into a bit of a pickle here. I have a custom profile that I used in two applications in the same solution. The first was a web application that I built to import a custom set of user profiles and attributes from an old .net application into the .net membership membership, roles, profile tables. I built a profile common class that inherits from profilebase. Both applications have a copy of the same class within their namespaces.
using System;
using System.Web.Security;
using System.Web.Profile;
using System.Collections.Specialized;
namespace WebProject
{
public class ProfileCommon : ProfileBase
{
public static ProfileCommon GetUserProfile(string username)
{
return Create(username) as ProfileCommon;
}
public static ProfileCommon GetUserProfile()
{
return Create(Membership.GetUser().UserName) as ProfileCommon;
}
[SettingsAllowAnonymous(false)]
public string FirstName
{
get
{
return base["FirstName"] as string;
}
set
{
base["FirstName"] = value;
}
}
[SettingsAllowAnonymous(false)]
public string LastName
{
get
{
return base["LastName"] as string;
}
set
{
base["LastName"] = value;
}
}
[SettingsAllowAnonymous(false)]
public string Email
{
get
{
return base["Email"] as string;
}
set
{
base["Email"] = value;
}
}
[SettingsAllowAnonymous(false)]
public StringCollection Sites
{
get
{
return base["Sites"] as StringCollection;
}
set
{
base["Sites"] = value;
}
}
}
}
My profile provider section in my web config file looks like this.
<profile defaultProvider="WebProjectProfileProvider" inherits="WebProject.ProfileCommon">
<providers>
<clear />
<add name="WebProjectProfileProvider" applicationName="/" type="System.Web.Profile.SqlProfileProvider" connectionStringName="Test"/>
</providers>
</profile>
If I use one application to perform the user import and another that uses the membership, roles and profiles that I created would this cause the "The settings property '' was not found." error? I can't seem to pinpoint where the error is being caused and some of the most common causes I've already checked. This is the first time I've used this feature in .net on such a large scale. Any help is greatly appreciated.
Thanks.
I found my problem. The issue was in the calling code. I had run into so many issues regarding the profile that I forgot to change the calling code back to the static method
ProfileCommon.GetUserProfile();
The other issues I had run into as well was declaring the profile's properties in the web config and declaring them in a profile common class. This was causing me to get flip flopping errors such as "the property has already been defined." and "The settings property '' was not found."
In short, declare the ProfileCommon proxy class within code and not in the web.config IF you are using a "Web Application" solution. Declare the properties in web.config if you are using a "web site" solution.
The best example I've come accross on the web was from this site.
ASP.NET Profiles in Web Application Projects
It describes how to use custom profiles in a nice concise summary and gives a full explanation of why this method is performed for web applications and why it's done differently for web sites. Hope this saves many head aches.
Related
I have been trying to add Azure application insights to a few projects. The whole experience was seamless with a .net core app. However, when I tried to update the Cloud role name property, that is where I could not find a lot for an OWIN based app. I want the name of the bubble in Insights Application Map to appear what I set in this property (My API for example) but it keeps resorting to the resource name that I have for this resource in Azure (my-azure-api). After scouring through most online resources, I was able to do the following which does not work.
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
namespace MyApp.Insights
{
public class RoleNameInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
// set role name correctly here.
telemetry.Context.Cloud.RoleName = "My API";
}
}
}
Also added the following in the applicationinsights.config
<Add Type="MyApp.Insights.RoleNameInitializer, MyApp"/>
Added the following to the startup class too (Just as a precaution)
using IntegratedTeleHealthPlatformApi.Insights;
using Microsoft.ApplicationInsights.Extensibility;
using Owin;
namespace MyApp
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
TelemetryConfiguration
.Active
.TelemetryInitializers
.Add(new RoleNameInitializer());
ConfigureAuth(app);
ApplyDatabaseMigrations();
}
}
}
I just setup a simple owin based asp.net project(asp.net web application, then in nuget install Microsoft.Owin.Host.SystemWeb).
After the setup, in visual studio -> Project -> Add Application Insights Telemetry:
My custom TelemetryInitializer as below:
Then just add the initializer to the applicationinsights.config:
And after execution, the role name is the one which I set in the initializer:
Please have a try if it's ok at your side. And to make sure your RoleNameInitializer is called, you can set breakpoint there to see if it's called or not.
I have a very weird scenario which I can't seem to figure out what's going on. I have a web service which is written in C# and the target framework is 3.5. I have many Classes and Methods but for simplicity I will make use of only two classes in the question.
public class PathNames
{
private string _pathA = "Some Path";
private string _pathB = "Another Path";
public string BaseDirectoryPath
{
get
{
return Path.Combine(_pathA, _pathB);
}
}
}
The second class is as follows:
public class UserInformation
{
public string UserName { get; set; }
...//more properties
}
Both of the above classes are in the same namespace.
The web service is referenced in a WebForm Application with the target framework being 4.0. Everything seems to be working fine and I can see the UserInformation class when I view it in Object Browser. However the PathNames class does not seem to be visible in the Object Broswer.
Both of the source files in question are set to Compile in the File Properties windows. I have 5 classes similar to that of UserInformation and same settings in the File Properties window where they are just simple POCO and only have public auto propteries. These all seem to be coming through and I can access them and see them in the Object Browser. For some strange reason I cannot PathNames class to come through. I have tried to add some new dummy classes and have the same issue as PathNames class. Can someone tell me what I am doing wrong please.
The web service old ASMX
Web service client is being created through VS add service reference
Using VS 2017 pro - version 15.6.7.
After publish if I de-compile the dll then the PathNames class is there. So it's clearly in the dll.
I have look at this but still no luck.
Using Data Contracts in web service
Service can't expose private/read-only properties. DataMember attribute is used for marking public members or properties (with public getter and setter) of class marked with DataContract attribute. DataContract can be used as parameter or return value of operation.
Windows Communication Foundation (WCF) uses a serialization engine called the Data Contract Serializer by default to serialize and deserialize data (convert it to and from XML), and XML serialization (by default) doesn't serialize read=only properties.
For More Information you can read the MS Docs for Data Contracts :- https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-data-contracts
To understand the various Limitation of Data Contracts please refer : -https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/types-supported-by-the-data-contract-serializer
Solution :
Anyway. What are you trying to do? Exposing properties means that you expect some stateful behavior. If you going to use this property in operation contract, which is seems to be, then you you must define the properties with public getter and setter so it can be serialized.
As the #Nikosi stated in previous answer, you have to define public setter for your BaseDirectoryPath property.
The only difference based on the example provided that one property is readonly while the other can be modified.
In order to make the class serializable consider rafactoring the property
public class PathNames {
private string _pathA = "Some Path";
private string _pathB = "Another Path";
public PathNames() {
BaseDirectoryPath = Path.Combine(_pathA, _pathB);
}
public string BaseDirectoryPath { get; set; }
}
You can use a default constructor to set the default value of the property
or just have an empty setter on the property
public class PathNames {
private string _pathA = "Some Path";
private string _pathB = "Another Path";
public string BaseDirectoryPath {
get {
return Path.Combine(_pathA, _pathB);
}
set {
//No OP
}
}
}
You can see how creating a Custom ASP.NET Web Service.
Might you need to rebuild web service ASP.Net and add your assembly to the global assembly cache (GAC).
I hope this help you.
I have written a WCF API. It runs (ran) just fine.
Now that I need to open it up to public access I tried to implement API Key verification following the example of Ron Jacobs and the accompanying video on endpoint.tv
This basically just uses a list of GUIDs stored in an xml file that represent the valid API keys. The authorization request key is passed via query string and validated in a custom ServiceAuthorizationManager like this:
protected override bool CheckAccessCore(OperationContext operationContext)
{
return IsValidAPIKey(operationContext);
}
public static bool IsValidAPIKey(OperationContext operationContext)
{
string key = TvinQuery.GetAPIKey(operationContext);
Guid apiKey;
// Convert the string into a Guid and validate it
if (Guid.TryParse(key, out apiKey) && TvinQuery.APIKeys.Contains(apiKey))
{
return true;
}
else
{
return false;
}
}
TvinQuery.APIKeysis a simple List<string> containing the valid guids from the xml file.
The solution compiles, but when I publish it on my server and try to access the service there, I get a FileNotFound exception for file or assembly "WCFWebHttp" or one of its dependencies.
The cause for this is very obviously this part in the service behavior node of web.config:
<serviceAuthorization serviceAuthorizationManagerType="WCFWebHttp.APIKeyAuthorization, WCFWebHttp" />
Unfortunately, neither a search through my assemblies nor through my file system nor an internet search nor a nuget package search came up with an assembly of that name.
Event viewer and enabled tracing did not reveal any further information either.
What is it? How can I solve this error? Is there anything wrong or missing with the example? It worked just fine in the video and that was a live presentation. :-?
As from this picture:
at https://blogs.msdn.microsoft.com/rjacobs/2010/06/14/how-to-do-api-key-verification-for-rest-services-in-net-4/
it looks like WCFWebHttp is an assembly implemented in the source code of the sample you've used (which I can't download right now to make sure because of server error).
First off, I know that this falls into the category of "not recommended practice", but I have a requirement to convert Word documents to PDF, via an ASP.Net site, and I have been using the Word Interop as it is free, simple to implement and Word is already installed on the server.
When I have been testing, it is working for me but after publishing users are reporting "Unauthorised access" errors. I have admin rights to the server and I found that adding the users as admin on the server works but I do not want to grant admin rights to every user.
So one of a number of things needs to happen, is there an alternative, free, library for converting a Word document to PDF that I could be using? Is there an easy way to get my users access to the Interop library without giving admin rights? Is there a way to impersonate an admin user for this part of the web application, seeing as the application requires Windows Authentication?
Is there anything else I have not thought of that could benefit me?
You can use impersonation to run code as a different user. There is a good impersonation class available on CodeProject here, http://www.codeproject.com/Articles/10090/A-small-C-Class-for-impersonating-a-User.
Just create a new admin account on the machine with access to do what you want, store the credentials in the web.config in app settings, (encrypt them if you want to with rijandael and decrypt them with code, etc.
But long store short, you use it like this,
using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
{
//This code is running elevated as the specified user
}
//This code is reverted back to the previous user.
I actually wrote my own web.config ConfigurationElement for storing credentials. It looks like this,
public class CredentialConfigurationElement : ConfigurationElement
{
#region Properties
[ConfigurationProperty("userName", DefaultValue="", IsRequired=true)]
public string UserName
{
get { return (string)this["userName"];}
set { this["userName"] = value; }
}
[ConfigurationProperty("password", DefaultValue = "", IsRequired = true)]
public string Password
{
get { return (string)this["password"]; }
set { this["password"] = value; }
}
#endregion
#region Explicit Operators
public static implicit operator NetworkCredential(CredentialConfigurationElement value)
{
return new NetworkCredential(value.UserName, value.Password);
}
public static implicit operator CredentialConfigurationElement(NetworkCredential value)
{
return new CredentialConfigurationElement() { UserName = value.UserName, Password = value.Password };
}
#endregion
}
However, to use it, you need to make a Custom ConfigurationSection, a class that inherits from ConfigurationSection and exposes the CredentialConfigurationElement as a property.
E.g. you could make a new section called CodeImpersonatorSection : ConfigurationSection
And in there expose the CredentialConfigurationElement as a property called ImpersonationCredentials.
Then use (CodeImpersonatorSection)WebConfigurationManager.GetSection("/yoursectionnamehere"); to get an instance to the configuration.
Optionally modify the Impersonator class to do that automatically, and change it to have a static method like
Impersonator.RunUnderImpersonation(p => {
//This code is impersonating the configured user.
});
My Question Is This
What configuration step have I missed to make Mvc Surface Controllers work in Umbraco?
My theory is that since there is a folder in the default Umbraco install called /umbraco/ which is used to connect to the CMS that the physical path is interfiering with the route /umbraco/surface/{Controller}/{Action} thus resulting in the ASP.NET YSOD (and an IIS 404
when I try to access a controller on that route that isn't defined.)
Background Information
I have added this class to my App_Code folder in a freshly downloaded copy of Umbraco 6.1.6:
public class MembersController : SurfaceController
{
public ActionResult Index()
{
return Content("Hello, Member!");
}
}
When I navigate to what I think should be the route for my Index() method, I get a YSOD that says the resource could not be found:
the code is not executed and the above error is displayed; however, if I change the Uri to garbage I get an IIS 404 error:
I started getting this in an existing site, thinking my site was screwed up I tried it in a new copy of Umbraco 6.1.6 and got the exact same results.
For the record, I have also tried MembersSurfaceController and its associated Uri, which has the exact same result as above. YSOD when I hit the valid route, and IIS 404 when I don't.
I have changed my umbracoSettings.config to MVC in the /config/ directory as well.
update
I'm using the out-of-the-box web.config file, which has this:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="UrlRewriteModule" />
<add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter" />
.
..
...
On my default Umbraco site I don't have any rewrite rules defined; but on my actual site I have several rewrite rules in place. I'm thinking that's not causing it since I'm seeing the same behavior on both sites though...
I have tried removing UrlRewrite completely I get the same results.
The following approach works for me in Umbraco 7.1, and I expect it to work in 6.1 as well:
Create folder called 'Controllers' within your App_Code folder, and put your surface controllers in there (so that they will be within the 'Controllers' namespace).
E.g. I have the following controller in the App_Code\Controllers folder (and hence, within the 'Controllers' namespace):
namespace Controllers
{
public class ServiceCentersController : SurfaceController
{
public ActionResult GetServiceCenters(string country = "", string region = "", string city = "")
{
...
}
}
}
My site runs on localhost, so I can invoke the GetServiceCenters action by navigating to:
http://localhost/umbraco/Surface/ServiceCenters/GetServiceCenters?country=aa®ion=bb&city=cc
You need a namespace for your controller - the code posted above doesn't have any namespace:
public class MembersController : SurfaceController
{
public ActionResult Index()
{
return Content("Hello, Member!");
}
}
That is why making a namespace of Controllers works ... but you could make this any logically named namespace you want.