In VS I have created a continuous type web job. My web job SDK is 3.0.14. I could write a timerTribber however none of the bindings for blob/queue is available. What am I missing? Below is the code. I an on .NET 4.7.2. WHen I compile I get the error "error CS0404: Cannot apply attribute class 'Queue' because it is generic"
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
namespace WebJob2
{
public class Functions
{
// This function will get triggered every Min
public static void ProcessEveryMin([TimerTrigger("0 * * * * *", RunOnStartup = true)] TimerInfo timerTriggerInfo,
[Queue("queue1")] string message, TextWriter log)
{
message = "NextRun on " + timerTriggerInfo.Schedule.GetNextOccurrence(DateTime.Now).ToString();
log.WriteLine(message);
}
}
}
Firstly I don't know you want to write message to queue or read from queue, you are trying to get the message from queue however you assign other value to the message.
Then is about how to bind Queue to webjob. The below is my Program.cs main method. If you want to use Queue binding you need AddAzureStorageCoreServices() and AddAzureStorage().
static void Main(string[] args)
{
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddTimers();
b.AddAzureStorage();
});
builder.ConfigureLogging((context, b) =>
{
b.AddConsole();
});
var host = builder.Build();
using (host)
{
host.Run();
}
}
And below is my Function.cs.
using System;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Queue;
namespace ConsoleApp68
{
public class Functions
{
public static async Task ProcessEveryMinAsync([TimerTrigger("0 * * * * *", RunOnStartup = true)] TimerInfo timerTriggerInfo,
[Queue("myqueue") ] CloudQueue queue, ILogger logger)
{
logger.LogInformation("NextRun on " + timerTriggerInfo.Schedule.GetNextOccurrence(DateTime.Now).ToString());
CloudQueueMessage message= await queue.GetMessageAsync();
logger.LogInformation(message.AsString);
await queue.DeleteMessageAsync(message);
CloudQueueMessage testmessage = new CloudQueueMessage("test message");
await queue.AddMessageAsync(testmessage);
}
}
}
Here is my test result pic.
Related
I am trying to adapt the Microsoft example for AF 3.0/.NET Core 3.1/xUnit (see Strategies for testing your code in Azure Functions) to work with AF 3.0/.NET 5.0/xUnit. However, I am running into compilation issues.
The Azure Function is a simple HTTP Trigger (GET only), ExportFuncApp.csproj file is as follows:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.12" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.2.0" OutputItemType="Analyzer" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.5.2" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
The ExportFunc.cs file is as follows:
using System.Net;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
namespace ExportFuncApp
{
public class ExportFunc
{
[Function(nameof(ExportFunc))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req,
FunctionContext executionContext)
{
var logger = executionContext.GetLogger("ExportFunc");
logger.LogInformation("C# HTTP trigger function processed a request.");
var response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString("Welcome to Azure Functions!");
return response;
}
}
}
Nothing special there. However, XUnit tests provided by Microsoft (.NET Core 3.1) are not really applicable to .NET 5.0. There was a StackOverflow article on the subject: Testing an Azure Function in .NET 5. 4 solutions were given in the article and all of them have compile issues. The first solution given was (ExportFuncUnitTests2.cs):
using Xunit;
using ExportFuncApp;
using System.Threading.Tasks;
using System.IO;
using System.Text;
using Moq;
using Microsoft.Azure.Functions.Worker;
using System.Net;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.Functions.Worker.Http;
namespace ExportFuncAppUnitTestsXunit
{
public class ExportFuncUnitTests2
{
[Fact]
public async Task Http_trigger_should_return_known_string()
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddScoped<ILoggerFactory, LoggerFactory>();
var serviceProvider = serviceCollection.BuildServiceProvider();
var context = new Mock<FunctionContext>();
context.SetupProperty(c => c.InstanceServices, serviceProvider);
var byteArray = Encoding.ASCII.GetBytes("test");
var bodyStream = new MemoryStream(byteArray);
var request = new Mock<HttpRequestData>(context.Object);
request.Setup(r => r.Body).Returns(bodyStream);
request.Setup(r => r.CreateResponse()).Returns(() =>
{
var response = new Mock<HttpResponseData>(context.Object);
response.SetupProperty(r => r.Headers, new HttpHeadersCollection());
response.SetupProperty(r => r.StatusCode);
response.SetupProperty(r => r.Body, new MemoryStream());
return response.Object;
});
var result = await ExportFunc.Run(request.Object, context.Object);
result.HttpResponse.Body.Seek(0, SeekOrigin.Begin);
// Assert
var reader = new StreamReader(result.HttpResponse.Body);
var responseBody = await reader.ReadToEndAsync();
Assert.NotNull(result);
Assert.Equal(HttpStatusCode.OK, result.HttpResponse.StatusCode);
Assert.Equal("Hello test", responseBody);
}
}
}
This results in a compilation error in ExportFuncUnitTests2.cs:
CS1061 'HttpResponseData' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'HttpResponseData' could be found (are you missing a using directive or an assembly reference?)
for:
var result = await ExportFunc.Run(request.Object, context.Object);
The second solution given in the article involves FakeHttpRequestData.cs:
using System;
using System.Collections.Generic;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Azure.Functions.Worker;
using System.IO;
using System.Security.Claims;
namespace ExportFuncAppUnitTestsXunit
{
class FakeHttpRequestData : HttpRequestData
{
public FakeHttpRequestData(FunctionContext functionContext, Uri url, Stream body = null) : base(functionContext)
{
Url = url;
Body = body ?? new MemoryStream();
}
public override Stream Body { get; } = new MemoryStream();
public override HttpHeadersCollection Headers { get; } = new HttpHeadersCollection();
public override IReadOnlyCollection<IHttpCookie> Cookies { get; }
public override Uri Url { get; }
public override IEnumerable<ClaimsIdentity> Identities { get; }
public override string Method { get; }
public override HttpResponseData CreateResponse()
{
return new FakeHttpResponseData(FunctionContext);
}
}
}
and, FakeHttpResponseData.cs:
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Azure.Functions.Worker;
using System.Net;
using System.IO;
namespace ExportFuncAppUnitTestsXunit
{
class FakeHttpResponseData : HttpResponseData
{
public FakeHttpResponseData(FunctionContext functionContext) : base(functionContext)
{
}
public override HttpStatusCode StatusCode { get; set; }
public override HttpHeadersCollection Headers { get; set; } = new HttpHeadersCollection();
public override Stream Body { get; set; } = new MemoryStream();
public override HttpCookies Cookies { get; }
}
}
And the test is (ExportFuncUnitTests2.cs):
using Xunit;
using ExportFuncApp;
using System.Threading.Tasks;
using System.IO;
using System.Text;
using Moq;
using Microsoft.Azure.Functions.Worker;
using System;
using System.Net;
using Microsoft.Extensions.Logging.Abstractions;
namespace ExportFuncAppUnitTestsXunit
{
public class ExportFuncUnitTests2
{
[Fact]
public async Task Http_trigger_should_return_known_string()
{
// Arrange
var body = new MemoryStream(Encoding.ASCII.GetBytes("{ \"test\": true }"));
var context = new Mock<FunctionContext>();
var request = new FakeHttpRequestData(
context.Object,
new Uri("https://stackoverflow.com"),
body);
// Act
var function = new ExportFunc(new NullLogger<ExportFunc>());
var result = await function.Run(request, context);
result.HttpResponse.Body.Position = 0;
// Assert
var reader = new StreamReader(result.HttpResponse.Body);
var responseBody = await reader.ReadToEndAsync();
Assert.NotNull(result);
Assert.Equal(HttpStatusCode.OK, result.HttpResponse.StatusCode);
Assert.Equal("Hello test", responseBody);
}
}
}
The ExportFuncUnitTests2.cs has the following compilation errors:
CS1729 'ExportFunc' does not contain a constructor that takes 1 arguments
for:
var function = new ExportFunc(new NullLogger<ExportFunc>());
and
CS1503 Argument 2: cannot convert from 'Moq.Mock<Microsoft.Azure.Functions.Worker.FunctionContext>' to 'Microsoft.Azure.Functions.Worker.FunctionContext'
for:
var result = await function.Run(request, context);
I the article Guide for running C# Azure Functions in an isolated process was somewhat useful but no help in terms of unit testing. Maybe I am missing the point. Since there is no examples/documentation on how to do unit testing for AF 3.0 with .NET 5.0 from Microsoft then I should not be trying to do that?
Any pointers will be greatly appreciated. Thanks!
Your Run() function in ExportFunc is not awaitable. Therefore, you should replace the line:
var result = await function.Run(request, context)
with:
var result = function.Run(request, context).
If you want to test an awaitable function (i.e., async Run()), then you'd call it from your Unit Test with await.
I have created a brand new WebAPI project from Visual Studio template. Target Framework netcoreapp3.1. I have configured it with windows authentication. I created a request in Postman with NTLM configuration to call my API. When I debug my application and call the request via Postman I get the following error:
IIS 10.0 Detailed Error - 401.1 - Unauthorized
My Startup class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace WebApplication1
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
My Controller class:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries =
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
}
launchSettings.json:
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:52109",
"sslPort": 44396
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WebApplication1": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Postman config with result:
Postman auth config:
I have no clue what's the problem :-( I have called my API from Insomnia or SoapUI and it works just fine! Maybe my problem is related to that issue https://github.com/postmanlabs/postman-app-support/issues/8038
I recently read this article and it was all about finding, fixing and avoiding memory leaks. I had a feeling that my ASP.NET Core 3.1 app was leaking because it kept increasing the memory usage for the first few minutes but after I kept it opened for like 5 minutes, it sticked to 350 MB in the Diagnostic Tools in Visual Studio 2019. Everything is probably okay because I usually don't forget to dispose stuff (by using block) but I wanted to make sure because my web app is listening to web sockets event for lifetime unless a CancellationToken is requested by the user.
In that article, I saw that it's possible to test an object for memory leak.
[Test]
void MemoryLeakTest()
{
var weakRef = new WeakReference(leakyObject)
// Ryn an operation with leakyObject
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Assert.IsFalse(weakRef.IsAlive);
}
Can the following code be tested for memory leaks in unit testing using xUnit? More specifically, timer and _subscription.
using Binance.Entity;
using Binance.Extensions;
using Binance.Helpers;
using Binance.Interfaces;
using Binance.Models.Redis;
using Binance.Net;
using Binance.Net.Interfaces;
using Binance.Net.Objects;
using CryptoExchange.Net.Authentication;
using CryptoExchange.Net.Sockets;
using Hangfire;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Binance.Services
{
public interface IBotService
{
void RunStart(Bot bot);
Task StopAsync();
}
public class BotService : IBotService, IDisposable
{
private readonly ILogger _logger;
private readonly IConfiguration _configuration;
private readonly IBinanceClient _client;
private readonly IBinanceSocketClient _socketClient;
private readonly INotificationService _notificationService;
public BotService(
ILogger<BotService> logger,
IConfiguration configuration,
IBinanceClient client,
IBinanceSocketClient socketClient,
INotificationService notificationService)
{
_logger = logger;
_configuration = configuration;
_client = client;
_socketClient = socketClient;
_notificationService = notificationService;
}
private void ApplyCredentialsOnClient()
{
BinanceClient.SetDefaultOptions(new BinanceClientOptions()
{
ApiCredentials = new ApiCredentials(_configuration.GetValue<string>("BinanceConfig:ApiKey"), _configuration.GetValue<string>("BinanceConfig:SecretKey")),
AutoTimestamp = true,
AutoTimestampRecalculationInterval = TimeSpan.FromMinutes(30)
});
BinanceSocketClient.SetDefaultOptions(new BinanceSocketClientOptions()
{
ApiCredentials = new ApiCredentials(_configuration.GetValue<string>("BinanceConfig:ApiKey"), _configuration.GetValue<string>("BinanceConfig:SecretKey")),
AutoReconnect = true,
ReconnectInterval = TimeSpan.FromHours(24)
});
}
private UpdateSubscription _subscription;
public void RunStart(Bot bot)
{
BackgroundJob.Enqueue(() => Start(bot));
}
public void Start(Bot bot)
{
ApplyCredentialsOnClient();
bool locked = false;
Timer timer = null;
BinanceKline lastKnownKline = null;
_subscription = _socketClient.SubscribeToKlineUpdates(bot.CryptoPair.Symbol, bot.TimeInterval.Interval, async data =>
{
if (data.Data.Final)
{
lastKnownKline = data.Data.ToKline();
// Static logic
// Clean up
if (locked)
{
locked = false;
timer?.Dispose();
}
}
// This block won't be executed before the static block is executed first
else if (lastKnownKline != null && lastKnownKline.Close != data.Data.Close)
{
lastKnownKline = data.Data.ToKline();
if (!locked)
{
locked = true;
timer = new Timer(async state =>
{
// Real time logic
bool condition = true;
if (condition)
{
timer?.Change(Timeout.Infinite, 0);
}
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(scheduledTime));
}
}
}).Data;
}
public async Task StopAsync()
{
await _socketClient.Unsubscribe(_subscription);
}
private bool _disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
_client.Dispose();
}
_disposed = true;
}
}
}
I did the following and got the below error msg:
The error message :
An exception of type 'System.AggregateException' occurred in mscorlib.dll but was not handled in user code
Additional information: One or more errors occurred.
If there is a handler for this exception, the program may be safely continued.
Question :
a) What seems to be the problems in above code as I just wanted to retrieve a record.
b) Must use Async Methods in WinRT or Windows store app?
c) Will below code able to retrieve record from Navision?
-----1------- Windows store App to access Nav Web Services
1.1 Added the service reference in WinRT App
1.2 Added a class1.cs in WinRT App
private async void btnImportCustomer_Click(object sender, RoutedEventArgs e)
{
Task _asyncCustomer = Class1.Customer.Listing.GetAsyncRecords("Y007");
### encounterd error here: ####
string g_strmsg = _asyncCustomer.Result.No + " “ +_asyncCustomer.Result.Name;
}
-----2---------- Class1.cs use inside WinRT App Project:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MobileNAVSalesSystem
{
class Class1
{
public static string _webserviceurlpage = "http ://{0}:{1}/{2}/WS/{3}/Page/{4}";
public static string _webserviceurlcodeunit = "http://{0}:{1}/{2}/WS/{3}/Codeunit/{4}";
public static Uri _webserviceuripage = null;
public static Uri _webserviceuricodeunit = null;
#region Customer
public class Customer
{
public class Card
{
//Do something for Card Type
}
public class Listing
{
public static wsCustomerList.Customer_List_PortClient GetService()
{
_webserviceuripage = new Uri(string.Format(_webserviceurlpage, "msxxx", "7047", "DynamicsNAV_xxx", Uri.EscapeDataString("Global xxx Pte. Ltd."), "Customer List"));
System.ServiceModel.BasicHttpBinding _wSBinding = new System.ServiceModel.BasicHttpBinding();
_wSBinding.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.TransportCredentialOnly;
_wSBinding.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows;
_wSBinding.MaxBufferSize = Int32.MaxValue;
_wSBinding.MaxReceivedMessageSize = Int32.MaxValue;
//_wSBinding.UseDefaultWebProxy = false;
wsCustomerList.Customer_List_PortClient _ws = new wsCustomerList.Customer_List_PortClient(_wSBinding, new System.ServiceModel.EndpointAddress(_webserviceuripage));
_ws.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
_ws.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("xxx","xxxx", "companyName");
return _ws;
}
//-------------------------- Using Async Methods
public static async Task GetAsyncRecords(string _No)
{
wsCustomerList.Customer_List_PortClient _ws = GetService();
wsCustomerList.Customer_List _List = (await _ws.ReadAsync(_No)).Customer_List;
if (_ws.State == System.ServiceModel.CommunicationState.Opened)
await _ws.CloseAsync();
return _List;
}
public static async Task GetAsyncRecords(wsCustomerList.Customer_List_Filter[] _filters)
{
wsCustomerList.Customer_List_PortClient _ws = GetService();
wsCustomerList.Customer_List[] _List;
List _filterArray = new List();
_filterArray.AddRange(_filters);
_List = (await _ws.ReadMultipleAsync(_filterArray.ToArray(), null, 0)).ReadMultiple_Result1;
if (_ws.State == System.ServiceModel.CommunicationState.Opened)
await _ws.CloseAsync();
return _List;
}
public static async Task GetAsyncRecords(wsCustomerList.Customer_List_Filter[] _filters, string _bookmarkkey)
{
wsCustomerList.Customer_List_PortClient _ws = GetService();
wsCustomerList.Customer_List[] _List;
List _filterArray = new List();
_filterArray.AddRange(_filters);
_List = (await _ws.ReadMultipleAsync(_filterArray.ToArray(), _bookmarkkey, 0)).ReadMultiple_Result1;
if (_ws.State == System.ServiceModel.CommunicationState.Opened)
await _ws.CloseAsync();
return _List;
}
public static async Task GetAsyncRecords(wsCustomerList.Customer_List_Filter[] _filters, string _bookmarkkey, int _setsize)
{
wsCustomerList.Customer_List_PortClient _ws = GetService();
wsCustomerList.Customer_List[] _List;
List _filterArray = new List();
_filterArray.AddRange(_filters);
_List = (await _ws.ReadMultipleAsync(_filterArray.ToArray(), _bookmarkkey, _setsize)).ReadMultiple_Result1;
if (_ws.State == System.ServiceModel.CommunicationState.Opened)
await _ws.CloseAsync();
return _List;
}
}
}
#endregion
}
//--- end namespace
}
i know it is some time ago this question was posted, but others might stumble across it, so here goes:
a) What seems to be the problems in above code as I just wanted to retrieve a record.
it seems like your return type is incorrect.
b) Must use Async Methods in WinRT or Windows store app?
Yes, when using windows mobile platforms(windows store apps and windows phone apps), you have to use asynchronous calls.
c) Will below code able to retrieve record from Navision?
Hard to tell, but to me it seems like your data you try to retrieve is in a incorrect format. Ill give you a simple example from one of my current projects where I retrieve a login:
private async void Button_Click(object sender, RoutedEventArgs e)
{
await call();
}
private async Task call()
{
BasicHttpBinding binding = new BasicHttpBinding();
NetworkCredential cred = new NetworkCredential("username", "password", "domain");
WS_PortClient ws = new WS_PortClient(binding, new EndpointAddress("Webservice-URL"));
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
ws.ClientCredentials.Windows.ClientCredential = cred;
CheckLogin_Result s = await ws.CheckLoginAsync("parameter");
string k = s.return_value.ToString();
MessageDialog d = new MessageDialog(k, "message");
await d.ShowAsync();
}
Hope it helps!
I have configured a Orchard module to expose a service and have enabled it. I cannot work out the URL to use based on the following.
Routes.cs
namespace OrchardRestService
{
using System.Collections.Generic;
using System.ServiceModel.Activation;
using Orchard.Mvc.Routes;
using Orchard.Wcf;
public class Routes : IRouteProvider
{
#region Implementation of IRouteProvider
public IEnumerable<RouteDescriptor> GetRoutes()
{
return new[] {
new RouteDescriptor {
Priority = 20,
Route = new ServiceRoute(
"ContentService",
new OrchardServiceHostFactory(),
typeof(IContentService))
}
};
}
public void GetRoutes(ICollection<RouteDescriptor> routes)
{
foreach (var routeDescriptor in GetRoutes())
routes.Add(routeDescriptor);
}
#endregion
}
}
IContentService.cs:
namespace OrchardRestService
{
using System.ServiceModel;
using Orchard;
[ServiceContract]
public interface IContentService : IDependency
{
[OperationContract]
ContentResult GetContent(string contentPath);
}
}
ContentService.cs:
namespace OrchardRestService
{
using System.Collections.Generic;
using System.ServiceModel.Activation;
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ContentService : IContentService
{
public ContentResult GetContent(string contentPath)
{
var contentResult = new ContentResult
{ ContentValues = new Dictionary<string, string>(), Found = true, Path = contentPath };
return contentResult;
}
}
}
I've tried to follow what Bertrand Le Roy has written here and here but seem to be missing something.
My code is .Net 4 by the way so no need for an SVC file.
Closing as I'd be jumping through hoops to use N2 in this way rather than what it is designed for.