svcutil.exe or testing wcf service JSON ouput? - c#

this post is off the back of my last question (thought i'd start a new question).
i am trying to create and test a simple (simple to you not me lol) WCF web service that outputs JSON. I beleive (with help) the application is ok but i need to test it and i a not sure how.
I'll attach my code below but here is what is happening, if i run the application it loads http://localhost:52002/ and i get the welcome to ASP.NET page, if run the application while i am in my .svc it loads http://localhost:52002/MyTestService.svc and i get the page:
You have created a service.
To test this service, you will need to create a client and use it to
call the service. You can do this using the svcutil.exe tool from the
command line with the following syntax:
svcutil.exe http://localhost:52002/MyTestService.svc?wsdl
I have been told i can http://localhost:52002/MyTestService.svc/GetResults to see the JSON output (see code below) but all i get is:
The webpage cannot be found
Any suggestions would be great, i apologies now for being abit new to all this and please ask you to maybe spell things out abit more then you normally would lol
Here is my code and tanks very much
Person.cs
[DataContract]
public class Person
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public int Age { get; set; }
public Person(string firstName, string lastName, int age)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Age = age;
}
}
MyTestServices.svc.cs
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = `AspNetCompatibilityRequirementsMode.Allowed)]`
public class TestService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public List<Person> GetResults()
{
List<Person> results = new List<Person>();
results.Add(new Person("Peyton", "Manning", 35));
results.Add(new Person("Drew", "Brees", 31));
results.Add(new Person("Tony", "Romo", 29));
return results;
}
MyTestService.svc
<%# ServiceHost Language="C#"
Service="TestService.TestService"
Factory="System.ServiceModel.Activation.ServiceHostFactory" %>
Web.Config
<configuration>
<connectionStrings>
<add name="ApplicationServices"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" timeout="2880" />
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.serviceModel>
<bindings />
<client />
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>

I always use fiddler to debug the request. With the new Web Api for WCF you can set the accept header for the client to application/JSON and the response will be formatted as JSON.

I am not a WCF expert, so I cannot tell you what is wrong with your current application, but I can give you instructions for setting up a very simple example using your code, which will return a result in Fiddler.
Create a new ASP.NET Empty Web Application
Add a code file with the following:
Normally I wouldn't put everything in one file, but for simplicity...
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace WebApplication1
{
[ServiceContract]
public interface ITestService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
List<Person> GetResults();
}
public class TestService : ITestService
{
public List<Person> GetResults()
{
List<Person> results = new List<Person>();
results.Add(new Person("Peyton", "Manning", 35));
results.Add(new Person("Drew", "Brees", 31));
results.Add(new Person("Tony", "Romo", 29));
return results;
}
}
[DataContract]
public class Person
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public int Age { get; set; }
public Person(string firstName, string lastName, int age)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Age = age;
}
}
}
Update the web.config file:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="test.svc"
service="WebApplication1.TestService"
factory="System.ServiceModel.Activation.WebServiceHostFactory" />
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>
</configuration>
You don't need a .svc file, so start the application, making note of the root url used by the ASP.NET Development Server. On the Request Builder tab of fiddler enter your url:
Click the Execute button and you should see your service results:
Hopefully you can use this to figure out what you need to update on your service to get it running. Good luck!

I do not see your interface, but you are missing some stuff if you want it to be rest.
//Add this to your method
[WebGet(UriTemplate="/Results")]
public List<Person> GetResults()
{
List<Person> results = new List<Person>();
results.Add(new Person("Peyton", "Manning", 35));
results.Add(new Person("Drew", "Brees", 31));
results.Add(new Person("Tony", "Romo", 29));
return results;
}
Now you should be able to call it using http://localhost:52002/MyTestService.svc/Results. Just change the uri tempalte to what you want it to be.
You may also need to change the factory to be the WebServiceHostFactory.
<%# ServiceHost Service="TestService.MyTestService"
Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

Related

Error in Retrieving Objects from WCF Service

New to WCF Services and needs some help.
So I have a client (basic console app) to test the WS (which is hosted on a test server not localhost)
With it I can pass and retrieve standard objects like string and int to and fro.
I can also pass custom classes to the WS but not retrieve them. I get either timeout or
An error occurred while receiving the http response to... this could be due
to the service endpoint binding not using the http protocol. this could also be due to an
http request context being aborted by the server (possibly due the
the service shutting down)
The underlying connection was closed. An unexpected error occurred on receive.
Unable to read data from the transport connection, an existing connection
was forcibly closed by the remote host.
I searched about endpoints and every single one seemed different and not obviously adaptable I am currently using the stock web.config when the project was created below which I think is where my issue is but finding difficult to know what to put.
WS Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<appSettings />
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
</system.webServer>
<connectionStrings>
<add name="CNS" connectionString="xyz" providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
Service Method in Question
public Request GetOrderByRef(string Ref)
{
AssetStockEntity db = new AssetStockEntity();
try
{
RequestEntity _requestef = new RequestEntity();
_requestef = db.RequestEntities.FirstOrDefault(x => x.Incident == Ref);
if (_requestef == null)
return null;
else
return TranslateRequestEntityToRequest(_requestef);
}
catch (Exception ex)
{
string debug = ex.ToString();
}
}
EDIT
Database Connection Test (Works as expected)
public string GetOrderByRefTest(string Ref)
{
AssetStockEntity db = new AssetStockEntity();
try
{
RequestEntity _requestef = new RequestEntity();
_requestef = db.RequestEntities.FirstOrDefault(x => x.Incident == Ref);
if (_requestef == null)
return null;
else
return _requestef.Requested_By;
}
catch (Exception ex)
{
string debug = ex.ToString();
return debug;
}
}
I'm using the translate call to convert EF objects to prevent exposure as from what I can understand is bad.
Class
[DataContract]
public class Request
{
[DataMember]
public int RId { get; set; }
[DataMember]
public string Incident { get; set; }
[DataMember]
public string Requested_By { get; set; }
[DataMember]
public string Authorised_By { get; set; }
[DataMember]
public virtual ICollection<Request_Items> Request_Items { get; set; }
}
Interface
[ServiceContract]
public interface Iws
{
[OperationContract]
Request GetOrderByRef(string Ref);
}
Test Console
static void Main(string[] args)
{
ASM.IwsClient ws = new ASM.IwsClient();
try
{
Console.WriteLine(ws.GetOrderByRef("ABC123").Requested_By);
Thread.Sleep(5000);
}
catch (Exception ex)
{
Console.WriteLine(ex);
Thread.Sleep(500000);
}
}
** Solved.
This issue was a parameter I left out for brevity was actually the cause, it wasn't serialised and thus rejected.
The cause was another parameter "Request_Items" which wasn't serialised with DataContract in its class.

Not Getting the Data in URL by Web Service

I am making web service and not getting the parse data through URL
Code of WEB SERVICE is this. my IService class
namespace DataService
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedResponse)]
List<RequestData> GetUser(RequestData data);
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "UsersList/{id}", RequestFormat = WebMessageFormat.Json)]
RequestData UsersList(string id);
}
[DataContract]
public class RequestData
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
[DataMember]
public string Address { get; set; }
}
}
this is my service1 class inherited by Iservice1 Class
namespace DataService
{
public class Service1 : IService1
{
public List<RequestData> GetUser(RequestData data)
{
List<RequestData> list = new List<RequestData>();
if (data.Name.ToUpper() == "MAIRAJ")
{
list.Add(new RequestData
{
Name = "Mairaj",
Age = 25,
Address = "Test Address"
});
list.Add(new RequestData
{
Name = "Ahmad",
Age = 25,
Address = "Test Address"
});
list.Add(new RequestData
{
Name = "Minhas",
Age = 25,
Address = "Test Address"
});
}
return list;
}
public RequestData UsersList(string userId)
{
if (userId == "1")
{
return new RequestData
{
Name = "Mairaj",
Age = 25,
Address = "Test Address"
};
}
else
{
return new RequestData
{
Name = "Amir",
Age = 25,
Address = "Test Address"
};
}
}
}
}
I am giving this URL after deploying web service http://116.58.61.180/ADG/Service1.svc
what Exact url should parse to get the data
this is my web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
I think you just forgot few things in your web.config :
<endpointBehaviors>
<behavior>
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
And
<protocolMapping>
<add binding="webHttpBinding" scheme="http" />
</protocolMapping>
If you don't put all this stuffs in your web.config you won't be able to get your services working.
The full Web.config would be like this :
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior>
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="webHttpBinding" scheme="http" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
For more details I had written few months ago a post on my blog about WCF and REST :
Simple WCF and REST service
WCF and POST method
Follow these steps:
Decorate your service class with follwing attribute
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1
Web.config should look like this
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</modules>
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>
Your Global.asax should look like this.
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}
private void RegisterRoutes()
{
// Edit the base address of Service1 by replacing the "Service1" string below
RouteTable.Routes.Add(new ServiceRoute("Service1", new WebServiceHostFactory(), typeof(Service1)));
}
}

WCF REST call returns "Method not allowed" exception

I am trying to create a WCF Restful Service.
Here is my contract: (The ActivateUser class extends the BaseResult class).
namespace SmartShopServerContract {
[ServiceContract]
public interface IService {
[OperationContract]
[WebGet(RequestFormat=WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json, UriTemplate="au/{eMail}/{password}/{idHandy}")]
ActivateUserResult ActivateUser(string eMail, string password, string idHandy);
}
// Basisklasse der Resultate --> alle Resultate haben einen definierten Status!
[DataContract]
public abstract class BaseResult {
private string status;
public BaseResult(string status) {
this.status = status;
}
[DataMember]
public string Status {
get { return this.status; }
}
}
// Result für ActivateUser
[DataContract]
public class ActivateUserResult : BaseResult {
public ActivateUserResult(string status)
: base(status) {
}
[DataMember]
public string CryptedPassword { get; set; }
}
}
Here is the implementation of the Service:
namespace SmartShopServerService {
public class ServiceSmartShop : IService {
public ActivateUserResult ActivateUser(string eMail, string password, string idHandy) {
return new ActivateUserResult("OK") {
CryptedPassword="testatsa"
};
}
And there is the Web.config file:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint helpEnabled="true" automaticFormatSelectionEnabled="false" defaultOutgoingResponseFormat="Json">
</standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
<services>
<service name="SmartShopServerService.ServiceSmartShop" behaviorConfiguration="RESTBehavior">
<endpoint address="/" binding="webHttpBinding" contract="SmartShopServerContract.IService" behaviorConfiguration="SmartShopBehavior"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="RESTBehavior">
<serviceMetadata httpGetEnabled="true" policyVersion="Policy15"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="SmartShopBehavior">
<webHttp automaticFormatSelectionEnabled="false"/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.5" sku=".NETFramework,Version=v4.5"/>
</startup>
<system.web>
<compilation debug="true"/>
</system.web>
<system.webServer>
<modules>
<remove name="WebDAVModule"/>
</modules>
</system.webServer>
</configuration>
I am testing this with the "VS2012 native tool commant prompt" like this:
svcutil.exe http://localhost:51162/SmartShopService.svc/au/data1/data2/data3
The code is being executed, but I am still getting a Method not allowed (405) exception.
Any thoughts on that?
--> currently local use
--> IIS Express (Visual Studio 2012)
You're using svcutil to create a proxy for a "RESTful WCF service". This does not work. The quick reason is that Web endpoints do not expose metadata for the svcutil tool to know what requests it needs to send to it. The long version is on the linked blog post.
The problem was the base class (BaseResult) for the ActivateUser class --> BaseResult
It seems like that it is not possible to extend a DataContract class and expect it to work.
Now i am using a Interface instead of a base class
public interface IResult {
string Status{get;set;}
}
[DataContract]
public class ActivateUserResult : IResult {
[DataMember]
public string CryptedPassword { get; set; }
[DataMember]
public string Status { get; set; }
}
This is working....thats all i know ;)

WCF method returning JSON / XML objects not working

I was new to WCF, i was trying to build a sample application using VS 2010 and code provided below
IProductService.cs
[ServiceContract]
public interface IProductService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml)]
Products SelectAllProducts();
}
[DataContract]
public class Product
{
[DataMember]
public int ProductId { get; set; }
[DataMember]
public string Name { get; set; }
}
[CollectionDataContract]
public class Products : System.Collections.ObjectModel.Collection<Product>
{
}
ProductService.cs
public class ProductService : IProductService
{
public Products SelectAllProducts()
{
var products = new Products();
var prod = new Product();
prod.ProductId = 1;
prod.Name = "SAMSUNG";
products.Add(prod);
prod = new Product();
prod.ProductId = 2;
prod.Name = "RELIANCE";
products.Add(prod);
return products;
}
}
http://localhost:1050/WCFService1/ProductService.svc/SelectAllProducts
Web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
and if try using the above url blank is getting displayed can some one help me ???
thanks in advance ..
Do some change in interface
[ServiceContract(Namespace = "JsonpAjaxService")]
interface IService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
method()
}
add some code on class like below
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService
your web.config file like this
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="None" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<standardEndpoints>
<webScriptEndpoint>
<standardEndpoint name="" crossDomainScriptAccessEnabled="true"/>
</webScriptEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>
I don't see the service binding the web.config. Try adding line such as below:
<services>
<service name="[Your Namespace].ProductService">
<endpoint address="" binding="webHttpBinding" contract="[Your Namespace].IProductService" />
</service>
</services>
Its important that you use webHttpBinding for REST WCF Services. Also you need to attach webHttpBehavior - that's possible by using WebServiceHostFactory in your svc file. For example,
<%#ServiceHost Language="C#" Service="[YourNameSpace].ProductService" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
See below for more info:
http://saravananarumugam.wordpress.com/2011/03/04/simple-rest-implementation-with-webhttpbinding/
http://msdn.microsoft.com/en-us/magazine/dd315413.aspx

Login form using Active directory groups in ASP.NET 2

Sorry if this has been asked before, but I have searched both Google and this site and can't find a complete work through aimed at beginners. I am trying to write a login page that authenticates against active directory groups using ASP.NET 2. I have found various articles but they all seem to be lacking key information for novices. I have managed to piece together a login page that works with a couple of active directory logins but I can't restrict it to only users who are members of specific active directory groups.
My web.config contains the following:
<connectionStrings>
<add name="ADConnectionString" connectionString="LDAP://domainname.local/DC=domainname,DC=local" />
</connectionStrings>
<authentication mode="Forms">
<forms
loginUrl="Login.aspx"
name=".ADAuthCookie" timeout="1000" />
</authentication>
<authorization>
<allow roles="DOMAINNAME\group"/>
<deny users="?"/>
</authorization>
<membership defaultProvider="MyADMembershipProvider">
<providers>
<add name="MyADMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider,
System.Web, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnectionString"
attributeMapUsername="sAMAccountName"/>
</providers>
</membership>
I have anonymised the real domain, but I believe this part works as it allows me to login if I use:
<allow roles="DOMAINNAME\username"/>
<deny users="?"/>
The rest of the project consists of a Login.aspx page with a WebControls.Login control and a Default.aspx page with the following in the page_load function to prove that the login has worked:
Response.Write("Hello, " + Server.HtmlEncode(User.Identity.Name));
I have tried
<allow roles="DOMAINNAME\group"/>
<deny users="*"/>
But that seems to deny everyone.
What am I missing?
From what I can tell the Authorization section of the web.config doesn't work like that for the ActiveDirectoryMembershipProvider. It seems you will need to check role/group memebership in code.
I spent a couple of days recently researching what you are attempting and didn't find anything. Ended up implementing our own AD login module to get the desired behavior. If you decide to implement your own solution I would recommend making use of the ActiveDirectoryMembershipProvider for authentication. Then just handle authorization yourself.
Try this changes in your web.config file
<configuration>
<configSections>
<section name="loginRedirectByRole" type="dirrerentloginusers.LoginRedirectByRoleSection" allowLocation="true" allowDefinition="Everywhere" />
<loginRedirectByRole>
<roleRedirects>
<add role="Manager" url="/Manager/ManagerPage.aspx" />
<add role="User" url="/User/UserPage.aspx" />
</roleRedirects>
<system.web>
<authentication>
<forms loginUrl="LoginForm1.aspx" protection="All"></forms>
</authentication>
<roleManager enabled="true"></roleManager>
<compilation debug="true" targetFramework="4.0" />
</system.web>
create a class for logintype
public class LoginRedirectByRoleSection : ConfigurationSection
{
[ConfigurationProperty("roleRedirects")]
public RoleRedirectCollection RoleRedirects
{
get
{
return (RoleRedirectCollection)this["roleRedirects"];
}
set
{
this["roleRedirects"] = value;
}
}
}
public class RoleRedirectCollection : ConfigurationElementCollection
{
public RoleRedirect this[int index]
{
get
{
return (RoleRedirect)BaseGet(index);
}
}
public RoleRedirect this[object key]
{
get
{
return (RoleRedirect)BaseGet(key);
}
}
protected override ConfigurationElement CreateNewElement()
{
return new RoleRedirect();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((RoleRedirect)element).Role;
}
}
public class RoleRedirect : ConfigurationElement
{
[ConfigurationProperty("role", IsRequired = true)]
public string Role
{
get
{
return (string)this["role"];
}
set
{
this["role"] = value;
}
}
[ConfigurationProperty("url", IsRequired = true)]
public string Url
{
get
{
return (string)this["url"];
}
set
{
this["url"] = value;
}
}
}
then add this code in your code behind page and redirect the user to his page
private void RedirectLogin(string username)
{
LoginRedirectByRoleSection roleRedirectSection = (LoginRedirectByRoleSection)ConfigurationManager.GetSection("loginRedirectByRole");
foreach (RoleRedirect roleRedirect in roleRedirectSection.RoleRedirects)
{
if (Roles.IsUserInRole(username,roleRedirect.Role))
{
// Response.Redirect(roleRedirect.Url);
FormsAuthentication.RedirectFromLoginPage(username,true);
Response.Redirect(roleRedirect.Url);
}
}
}
I don't see any RoleProvider in the web.config file you posted. I'd have thought you'd need a WindowsTokenRoleProvider if you want to use Windows group membership as ASP.NET roles.

Categories