I've tried resolving this from answers in other and similar posts, but no luck.
I'm Using MVC 5, framework 4.8 latest VS2017.
Thanks
My Config is: (including other attempts)
<configuration>
<appSettings>
<!--<add key="owin:AutomaticAppStartup" value="false" />-->
<add key="owin:HandleAllRequests" value="true"/>
<!--<add key="owin:AppStartup" value="Api.xxx" />-->
</appSettings>
</configuration>
Startup class is:
[assembly: OwinStartupAttribute(typeof(Api.xxx.Startup))]
namespace Api.xxx
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Allow all origins
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
….
}
}
}
and Api is:
namespace Api.xxx
{
[Route("values")]
public class ValuesController : ApiController
{
private static readonly Random _random = new Random();
public IEnumerable<string> Get()
{
var random = new Random();
return new[]
{
_random.Next(0, 10).ToString(),
_random.Next(0, 10).ToString()
};
}
}
}
I think you need to change
[assembly: OwinStartupAttribute(typeof(Api.xxx.Startup))]
to
[assembly: OwinStartup(typeof(Api.xxx.Startup))]
Reference: https://learn.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-startup-class-detection
Related
So i had this working, ive switched to paket and i guess some versions of dll's have changed.
However I still do not understand the error i am getting.
System.ArgumentException : LoggerName already in use
Parameter name: loggerName
my code is basically exactly as it is on here
http://www.tomdupont.net/2015/06/capture-xunit-test-output-with-nlog-and.html
public class NLogTests : IDisposable
{
private readonly ILogger _logger;
public NLogTests(ITestOutputHelper outputHelper)
{
_logger = outputHelper.GetNLogLogger();
}
public void Dispose()
{
_logger.RemoveTestOutputHelper();
}
[Fact]
public void Hello()
{
_logger.Trace("World Trace");
_logger.Debug("World Debug");
_logger.Warn("World Warn");
_logger.Error("World Error");
}
}
and config
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
throwExceptions="true">
<extensions>
<add assembly="xunit.NLog" />
</extensions>
<targets async="false">
<target xsi:type="TestOutput"
layout="${time}|${level:uppercase=true}|${logger}|${message}"
name="Test" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="Test" />
</rules>
</nlog>
The GetNLogLogger method has an overload that takes a logger name and a bool for incremental suffixes. Using these does not help.
I am really confused.
stacktrace:
System.ArgumentException
LoggerName already in use
Parameter name: loggerName
at Xunit.NLog.Targets.TestOutputTarget.Add(ITestOutputHelper testOutputHelper, String loggerName)
at Xunit.NLog.Helpers.TestOutputHelpers.AddTestOutputHelper(ITestOutputHelper testOutputHelper, String loggerName, Boolean addNumericSuffix)
at Xunit.NLogTestOutputExtensions.GetNLogLogger(ITestOutputHelper testOutputHelper, String loggerName, Boolean addNumericSuffix)
at ProjectRake.BusinessLogic.Spec.TautologiesToVerifyNLogOutput..ctor(ITestOutputHelper outputHelper) in M:\programming\ProjectRake\src\server\ProjectRake.BusinessLogic.Spec\TautologiesToVerifyNLogOutput.cs:line 19
edit:
have downgraded all xunit stuff to 2.1.0, same issue.
outputHelper.GetNLogLogger(); is calling AddTestOutputHelper("")
I guess it only works if you call it once.
You can use outputHelper.GetNLogLogger("myname"); or outputHelper.GetNLogLogger(typeof(NLogTests).Name);
I have a base class that I'm trying to use in a View. I understand now that #model is really an implementation of 'WebViewPage'. So, I believe there is probably a better way to accomplish what I want, maybe with an Action Filter or my BaseController object.
I was trying to do something like this:
public abstract class AuthenticatedViewPageBase : WebViewPage
{
private Login _user;
protected override void InitializePage()
{
_user = Session["User"] as Login;
}
public bool HasPermission(Permissions permission)
{
return HasPermission(new List<Permissions> { permission });
}
public bool HasPermission(List<Permissions> permissions)
{
if (_user == null)
_user = Session["User"] as Login;
return _user != null && permissions.Any(thisPerm => _user.Permissions.Any(p => p.PermissionId == (int)thisPerm));
}
}
And use it in a List View like this:
#using PublicationSystem.Model.Enums
#inherits PublicationSystem.Helpers.AuthenticatedViewPageBase
#model IEnumerable<PublicationSystem.Model.Profile>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_LayoutSmBanner.cshtml";
}
#if (HasPermission(new List<Permissions>
{
Permissions.userCreate
}))
{
<p>
#Html.ActionLink("Create New", "Create");
</p>
}
....
But of course, I cannot use #inherits and #model together. (The Profile class is a simple model.)
What would be a good way to get abilities of function like HasPermission in MVC?
I defined two similar classes:
public abstract class AuthenticatedViewPageBase : WebViewPage
{
//....
}
public abstract class AuthenticatedViewPageBase<TModel> : WebViewPage<TModel>
{
//....
}
Then set \Views\web.config like this:
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="PublicationSystem.Helpers.AuthenticatedViewPageBase">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.Optimization" />
<add namespace="PublicationSystem" />
</namespaces>
</pages>
</system.web.webPages.razor>
Now my pages can use #model as normally and get the custom methods from my abstract version of WebViewPage.
#model IEnumerable<PublicationSystem.Model.Profile>
We're using Log4net's ThreadContext.Stacks and it is mostly working well. My problem comes if there have been multiple ThreadContext.Stacks["key"].Push(...).
With a simple ConversionPattern:
<param name="ConversionPattern value="... topProp=%properties{key} ..."/>
I see log entries like:
... topProp=first second third ...
I'd really like to see only the most recently pushed value rather than all the values. I had hoped I could put something like the following in my appender/layout/ConversionPattern:
<param name="ConversionPattern value="... topProp=%properties{key}{1} ..."/>
but that doesn't work. I can kludge it by assuming/requiring all values to be the same length (say 5) and doing:
<param name="ConversionPattern value="... topProp=%5.5properties{key} ..."/>
But that isn't real attractive. Any ideas?
Thanks!
[Edit to add very simple example]
using System;
using System.IO;
using log4net;
using log4net.Config;
namespace ThreadLocalExample {
class Program {
private const string PropJobId = "Example:JobId";
static void Main() {
XmlConfigurator.Configure(new FileInfo("log4net.cfg"));
var log = LogManager.GetLogger(typeof(Program));
ThreadContext.Stacks[PropJobId].Push("Old");
log.Debug("Enter using");
using (ThreadContext.Stacks[PropJobId].Push("New")) {
log.Debug("stuff");
}
log.Debug("Out of using");
log.Debug("done.");
Console.ReadKey();
}
}
}
With the log4net configuration:
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<threshold value="ALL" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="[jobId=%P{Example:JobId}]: %m%n" />
</layout>
</appender>
Produces:
[jobId=Old]: Enter using
[jobId=Old New]: stuff
[jobId=Old]: Out of using
[jobId=Old]: done.
But I'd like:
[jobId=Old]: Enter using
[jobId=New]: stuff
[jobId=Old]: Out of using
[jobId=Old]: done.
I had the same problem, and it was not only about 'bad formatting', because I used database appender (AdoNetAppender) which expects integers. So after joining all stacked values together the result is not an integer any more. Consider an appender like this:
<appender name="DbAppender" type="log4net.Appender.AdoNetAppender">
...
<commandText value="INSERT INTO Log ([Id]) VALUES (#Id)" />
<parameter>
<parameterName value="#Id" />
<dbType value="Int32" />
<layout type="log4net.Layout.PatternLayout" value="%P{someId}" />
</parameter>
This appender will not accept any log message, where 'someId' is stacked twice or more - no logs in database ...
So, to solve this problem I gave up with stacks and turned back to flat properties.
I've coded some short extension:
public static class Log4NetExt {
public static IDisposable ThreadContextPush(string key, object value) {
object oldVal = ThreadContext.Properties[key];
ThreadContext.Properties[key] = value;
var topMostCleaner = new DispCleaner();
topMostCleaner.EvDispose += () => {
// Pop = restore old value
ThreadContext.Properties[key] = oldVal;
};
return topMostCleaner;
}
private class DispCleaner : IDisposable {
public event Action EvDispose;
public void Dispose() {
if (EvDispose != null) EvDispose();
}
}
}
And now, instead of:
using (ThreadContext.Stacks[PropJobId].Push("New")) {
write:
using (Log4NetExt.ThreadContextPush(PropJobId, "New")) {
and it works ok ;)
(This short code does not follow all best practises of building disposable objects, deleting event handlers and all this stuff, but it is short and I think it is safe in this simple case).
I have Done it via Filip solution modified as
public static class Log4NetExt
{
public static IDisposable ThreadContextSet(string key, object value)
{
//object oldVal = ThreadContext.Properties[key];
ThreadContext.Properties[key] = value;
var topMostCleaner = new DispCleaner();
topMostCleaner.EvDispose += () => {
// Pop = restore old value
//ThreadContext.Properties[key] = oldVal;
ThreadContext.Properties[key] = null;
};
return topMostCleaner;
}
private class DispCleaner : IDisposable
{
public event Action EvDispose;
public void Dispose()
{
if (EvDispose != null)
{
EvDispose();
}
}
}
}
And used it like
using (Log4NetExt.ThreadContextSet("ContextId", "Feed"))
using (Log4NetExt.ThreadContextPush("ContextValue", objFeed.FeedId))
{
}
I would like to use the new Rest DSL in Apache Camel 2.14 to create a rest interface. I would like to use the Jetty component and I have a basic example setup like this:
Spring Security Configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring-security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://camel.apache.org/schema/spring-security http://camel.apache.org/schema/spring-security/camel-spring-security.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<spring-security:http auto-config="true" use-expressions="true" >
<spring-security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
<spring-security:http-basic></spring-security:http-basic>
</spring-security:http>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="true"/>
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
</list>
</property>
</bean>
<spring-security:authentication-manager alias="authenticationManager">
<spring-security:authentication-provider user-service-ref="userDetailsService"/>
</spring-security:authentication-manager>
<spring-security:user-service id="userDetailsService">
<spring-security:user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN"/>
<spring-security:user name="user" password="user" authorities="ROLE_USER"/>
</spring-security:user-service>
<authorizationPolicy id="admin" access="ROLE_ADMIN"
authenticationManager="authenticationManager"
accessDecisionManager="accessDecisionManager"
xmlns="http://camel.apache.org/schema/spring-security"/>
<authorizationPolicy id="user" access="ROLE_USER"
xmlns="http://camel.apache.org/schema/spring-security"/>
Camel Route Configuration
restConfiguration().component("jetty").host("0.0.0.0").port(24999).bindingMode(RestBindingMode.json).dataFormatProperty("prettyPrint", "true");
rest("address").description("Contains services for addresses").
consumes("application/json").
produces("application/json").
get().
route().policy("admin").
to("bean:restAddressApi?method=queryAddress").endRest();
When I try to access this protected URL using wget with this:
wget --http-user=admin --http-password=admin http://localhost:24999/address/
Then I get this error in the console:
org.apache.camel.CamelAuthorizationException: Cannot find the Authentication instance.. Exchange[Message: [Body is null]]
at org.apache.camel.component.spring.security.SpringSecurityAuthorizationPolicy.beforeProcess(SpringSecurityAuthorizationPolicy.java:72)
at org.apache.camel.component.spring.security.SpringSecurityAuthorizationPolicy$AuthorizeDelegateProcess.process(SpringSecurityAuthorizationPolicy.java:120)
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.component.jetty.CamelContinuationServlet.service(CamelContinuationServlet.java:150)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.handler.ResourceHandler.handle(ResourceHandler.java:406)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:370)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:745)
What am I missing in my config to get this working?
Two options.
You can use basic auth with jetty rest DSL. I just spent some time working with basic auth, a jetty rest DSL service, and camel 2.15. I wrote up my experiences here: http://www.mooreds.com/wordpress/archives/2065 . I found the camel-jetty wiki page a bit out of date, full code here: https://github.com/mooreds/camel-rest-jetty-auth
You can use spring security (at least with version 2.15.2 of camel and 4.0.1.RELEASE of spring security, which is what I am using). To do so, you need to make sure you create a processor class, as outlined here: http://camel.apache.org/spring-security.html#SpringSecurity-Authentication and put it in front of every route before you call the policy. You also need to create an exception handler to present a nice message to an unauthorized user--here's what I did in my java routebuilder: onException(org.apache.camel.CamelAuthorizationException.class).handled(true).transform(simple("Access Denied with the Policy of ${exception.policyId} !")).setHeader(Exchange.HTTP_RESPONSE_CODE, simple("401"));
Here is how I solved it using Apache Camel 2.15.2. I use this backend together with an AngularJS frontent where I use an httpInterceptor to add the authenitcation header.
I use JWT to store a tenantId in the authorization header. This tenantId is used together with Hibernate and its Multi Tenancy Support.
Front end login controller, using AngularJs and written in TypeScript:
/// <reference path="../reference.ts"/>
module Controllers {
export class Credentials {
username:string;
password:string;
}
export interface ILoginControllerScope extends ng.IScope {
credentials:Credentials;
login:()=>void;
}
export class LoginController {
private _scope:ILoginControllerScope;
static $inject = ['$scope', '$http', 'UserService', '$location'];
constructor($scope:ILoginControllerScope, $http:ng.IHttpService, UserService:UserService, $location:ng.ILocationService) {
this._scope = $scope;
$scope.credentials = new Credentials();
$scope.login = ()=> {
$http.post('/api/authenticate', $scope.credentials)
.success(function (data:string, status:any, headers:any, config:any) {
// Remove all " characters from string.
data = data.replace(/"/gi, '');
UserService.setSecurityToken(data);
$location.path('/');
})
.error(function (data:any, status:any, headers:any, config:any) {
});
}
}
}
}
#Override
public void process(Exchange exchange) throws Exception {
Map<String, String> credentials = exchange.getIn().getBody(HashMap.class);
String username = credentials.get("username");
String password = credentials.get("password");
// Login logic that returns object() containing user info
exchange.getIn().setBody(jwtService.generateToken(tenantConfiguration));
}
}
}
This is the class JwtService that is responsible for creating a JWT Token:
package com.me.services;
import com.me.TenantConfiguration;
import com.google.common.collect.Maps;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.security.SecureRandom;
import java.util.Map;
import java.util.Random;
#Service
public class JwtService {
public static final String TENANT_ID = "tenant_id";
public static final String ROLE = "role";
#Value("${jwt.subject}")
private String jwtSubject;
private byte[] signingKey;
private SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
public SignatureAlgorithm getSignatureAlgorithm() {
return signatureAlgorithm;
}
public byte[] getSigningKey() {
if (this.signingKey == null) {
// Generate new signingKey
Random random = new SecureRandom();
signingKey = new byte[64];
random.nextBytes(signingKey);
}
return this.signingKey;
}
public String getJwtSubject() {
return jwtSubject;
}
public String generateToken(TenantConfiguration tenantConfiguration){
Map<String, Object> claims = Maps.newHashMap();
claims.put(TENANT_ID, tenantConfiguration.getSessionId());
String token = Jwts.builder().setSubject(this.getJwtSubject()).setClaims(claims).signWith(this.getSignatureAlgorithm(), this.getSigningKey()).compact();
return token;
}
}
To use this in a route I define it like this:
rest("api/messages").description("Restful API for messages").
get().id("GetMessages").route().to("springSecurityContextLoader").policy(authorizationPolicy).to("bean:restMessageApi?method=getAllMessages").endRest().
SpringSecurityContextloader
#Service
public class SpringSecurityContextLoader implements Processor {
#Inject
private JwtService jwtService;
#Override
public void process(Exchange exchange) throws Exception {
String authorization = exchange.getIn().getHeader("Authorization", String.class);
Jwt jwt = Jwts.parser().setSigningKey(jwtService.getSigningKey()).parse(authorization);
Map<String, Object> claims = (Map<String, Object>) jwt.getBody();
String tenantId = claims.get(JwtService.TENANT_ID).toString();
Authentication authentication = new PreAuthenticatedAuthenticationToken(tenantId, "something", Lists.newArrayList(new SimpleGrantedAuthority("ROLE_USER")));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
Taken from https://camel.apache.org/jetty.html
Jetty handlers and security configuration
You can configure a list of Jetty handlers on the endpoint, which can be useful for enabling advanced Jetty security features. These handlers are configured in Spring XML as follows:
<-- Jetty Security handling -->
<bean id="userRealm" class="org.mortbay.jetty.plus.jaas.JAASUserRealm">
<property name="name" value="tracker-users"/>
<property name="loginModuleName" value="ldaploginmodule"/>
</bean>
<bean id="constraint" class="org.mortbay.jetty.security.Constraint">
<property name="name" value="BASIC"/>
<property name="roles" value="tracker-users"/>
<property name="authenticate" value="true"/>
</bean>
<bean id="constraintMapping" class="org.mortbay.jetty.security.ConstraintMapping">
<property name="constraint" ref="constraint"/>
<property name="pathSpec" value="/*"/>
</bean>
<bean id="securityHandler" class="org.mortbay.jetty.security.SecurityHandler">
<property name="userRealm" ref="userRealm"/>
<property name="constraintMappings" ref="constraintMapping"/>
</bean>
I am a newbie at WCF. I created a WCF restful service in VS2010 (WCF service appl). It was targeted for Framework 4.0. I hosted this service on local IIS with appl pool set for framework 4.0. When I call the appl methods from browser or fiddler, they work fine. Now, I created a client console based. When I call any method from client I get the following Communication Exception:
** remote server returned an unexpected response: (405) Method Not Allowed.**
Service Interface file:
namespace MyService
{
[ServiceContract]
public interface ITestService
{
[WebGet(UriTemplate = "GetDateTime")]
[OperationContract]
string GetDateTime();
[WebGet(UriTemplate = "GetName")]
[OperationContract]
string GetName();
}
}
Class that implements the above interface:
namespace MyService
{
public class TestService : ITestService
{
public string GetDateTime()
{
return DateTime.Now.ToString();
}
public string GetName()
{
return "MY name is KingKong";
}
}
}
Web.config file:
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyService.TestService">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="" contract="MyService.ITestService">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- 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" />
TestService.svc
<%# ServiceHost Language="C#" Debug="true" Service="MyService.TestService" CodeBehind="TestService.svc.cs" %>
Client app.config:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://localhost/BestService/TestService.svc"
binding="webHttpBinding" bindingConfiguration="" contract="MyService.ITestService"
name="MyClientConfig" kind="" endpointConfiguration="" />
</client>
</system.serviceModel>
Client program calling proxy class
static void Main(string[] args)
{
TestServiceClient proxy = null;
try
{
proxy = new TestServiceClient();
Console.WriteLine("Test 1: List all products");
string sdatetime = proxy.GetName();
Console.WriteLine("Datetime: {0}", sdatetime);
Console.WriteLine();
// Disconnect from the service
proxy.Close();
}
catch (CommunicationException cex)
{
if (cex.InnerException != null)
{
Console.WriteLine("{0}", cex.InnerException.Message);
}
else
{
Console.WriteLine("General exception: {0}", cex.Message);
}
}
catch (Exception e)
{
if (e.InnerException != null)
{
Console.WriteLine("{0}", e.InnerException.Message);
}
else
{
Console.WriteLine("General exception: {0}", e.Message);
}
}
Console.WriteLine("Press ENTER to finish");
Console.ReadLine();
}
I added a service reference to the application and the Reference.cs file has following partial code:
namespace MyClient.MyService {
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="MyService.ITestService")]
public interface ITestService {
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITestService/GetDateTime", ReplyAction="http://tempuri.org/ITestService/GetDateTimeResponse")]
string GetDateTime();
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITestService/GetName", ReplyAction="http://tempuri.org/ITestService/GetNameResponse")]
string GetName();
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface ITestServiceChannel : MyClient.MyService.ITestService, System.ServiceModel.IClientChannel {
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class TestServiceClient : System.ServiceModel.ClientBase<MyClient.MyService.ITestService>, MyClient.MyService.ITestService {
public TestServiceClient() {
}
public TestServiceClient(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public TestServiceClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public TestServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public TestServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
public string GetDateTime() {
return base.Channel.GetDateTime();
}
public string GetName() {
return base.Channel.GetName();
}
}
}
Please help me as I have spent nearly 2 days trying to figure out the problem in the client
Thanks
VS2010 doesnt have the ability to generate a proxy for a RESTFUL service as it does for a SOAP based service. So the solution is write your own proxy class which inherits from the ClientBase class and use the Channel to call the web methods of the service.