WCF Service Creation - wcf

I am trying to build a small WCF service and wanted to utilize it in a test application.
PFB service code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace HelloIndigo
{
[ServiceContract(Namespace="http://www.thatindigoirl.com/samples/2006/06")]
public interface IHelloIndigoService
{
[OperationContract]
string HelloIndigo();
}
public class HelloIndigoService : IHelloIndigoService
{
public string HelloIndigo()
{
return "Hello indigo";
}
}
}
Host Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace Host
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(HelloIndigo.HelloIndigoService), new Uri("http://localhost:8000/HelloIndigo")))
{
host.AddServiceEndpoint(typeof(HelloIndigo.IHelloIndigoService), new BasicHttpBinding(), #"HelloIndigoService");
host.Open();
Console.WriteLine("Press <ENTER> to terminate the service hosy");
Console.ReadLine();
}
}
}
}
Whenever I am trying to run Host I am getting below mentioned error in host.Open() statement.
HTTP could not register URL
http://+:8000/HelloIndigo/. Your
process does not have access rights to
this namespace (see
http://go.microsoft.com/fwlink/?LinkId=70353
for details).
Can anyone help me with this

You need to run the host app with elevated privileges (i.e., "As Administrator"). Under Vista/Win7, only administrative accounts have the permission to register socket listeners.

Related

Can we use Microsoft.AspNet.WebApi.Client from an ASP.NET Core application?

We want to be able to use the package Microsoft.AspNet.WebApi.Client from our ASP.NET Core MVC web application to make an HTTP call to an outside system. It does work but I couldn't find the corresponding source code in .NET core (github). Is it okay to use this library from the ASP.NET road map point of view? Will it be supported in ASP.NET Core going forward? Most importantly, will this package be supported in non-Windows platforms, as part of ASP.NET Core/.NET Core?
You can try what I did for a REST Client. I found that the assembly you have mentioned in it's latest version does not work in the recently released ASP.Net Core 1.0. Instead of "Microsoft.AspNet.WebApi.Client", use "System.Net.Http".
Then where you would have built an Http POST request like this:
using AvailabilityPricingClient.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AvailabilityPricingClient.Core.Model;
using System.Net.Http;
using System.Net.Http.Headers;
namespace AvailabilityPricingClient.Client
{
public class ProductAvailabilityPricing : IProductAvailabilityPricing
{
private HttpClient _client;
public ProductAvailabilityPricing(string apiUrl)
{
_client = new HttpClient();
_client.BaseAddress = new Uri(apiUrl);
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public void Dispose()
{
_client.Dispose();
}
public async Task<IEnumerable<Availablity>> GetAvailabilityBySkuList(IEnumerable<string> skuList)
{
HttpResponseMessage response = _client.PostAsJsonAsync("/api/availabilityBySkuList", skuList).Result;
if (response.IsSuccessStatusCode)
{
var avail = await response.Content.ReadAsAsync<IEnumerable<Availablity>>();
return avail;
}
return null;
}
}
}
You will now build like this:
using AvailabilityPricingClient.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AvailabilityPricingClient.Core.Model;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
namespace AvailabilityPricingClient.Client
{
public class ProductAvailabilityPricing : IProductAvailabilityPricing
{
private HttpClient _client;
public ProductAvailabilityPricing(string apiUrl)
{
_client = new HttpClient();
_client.BaseAddress = new Uri(apiUrl);
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public void Dispose()
{
_client.Dispose();
}
public async Task<IEnumerable<Availablity>> GetAvailabilityBySkuList(IEnumerable<string> skuList)
{
var output = JsonConvert.SerializeObject(skuList);
HttpContent contentPost = new StringContent(output, System.Text.Encoding.UTF8, "application/json");
HttpResponseMessage response = _client.PostAsync("/api/availabilityBySkuList", contentPost).Result;
if (response.IsSuccessStatusCode)
{
var avail = await response.Content.ReadAsStringAsync()
.ContinueWith<IEnumerable<Availablity>>(postTask =>
{
return JsonConvert.DeserializeObject<IEnumerable<Availablity>>(postTask.Result);
});
return avail;
}
return null;
}
}
}
This way you interface does not change only the body of your request code changes.
This is working for me....Good luck....

How to authenticate WEB API controller method using HMACSHA256

I am new to WEB api. I would appreciate if somebody could give me the sample code for authenticate a user by creating hash using HMACSHA256.Following is my API Controller Code.I want GetCategoryNewsByFilter to be authenticated before calling it.
using NewsBytesApi.Attributes;
using NewsBytesApi.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace NewsBytesApi.Controllers
{
public class ValuesController : ApiController
{
NewsLetterDBEntities dataContext = null;
public List<storyRepo> GetCategoryNewsByFilter()
{
dataContext = new NewsLetterDBEntities();
List<storyRepo> lstStoryRepo = new List<storyRepo>();
storyRepo obj = new storyRepo();
obj.StoryContent = "ABC";
obj.StoryHeader = "DEF";
lstStoryRepo.Add(obj);
return lstStoryRepo;
}
}
}

Why am I getting null data on wcf deserialization?

I've a system where I'm exchanging messages across different point to point comms channels- between Windows and embedded systems, and have done it all as pretty standard custom serialize/deserialize functions pretty much entirely done by hand, since that makes it easy to port between C# on the Windows side and C on the embedded.
Now I want to add a chunk that communicates between PCs on the net at large. Rather than do another batch of the same stuff, use TcpClient/TcpListener and keep track of overlapping messages and responses, I decided to have a look at WCF.
After looking at lots of messages on here, and docs etc elsewhere, I've come up with a very simple app that exchanges messages, with the server containing one function that takes and returns an interface instance, rather than a fixed class. Even though the example has only one kind of message- hence only one type is set using the KnownType and ServiceKnownType attributes, I picture there being a few tens of different types of messages that could be sent, and I want to be able to add them fairly easily as things evolve.
Although no errors are generated by the code, the object that's instantiated at the far end has none of the data that was sent. I've tried packet sniffing to see if I can confirm the data's actually going on the wire but I can't understand the wire protocol. So I don't know if the data's disappearing in the client on transmission or in the server. If I change the code to use instances of TestMessageType directly rather than using the interface, it works fine.
The solution's made of three projects; a "types" assembly and then client and server console apps that reference that assembly. The types assembly contains this code;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;
namespace WCF_TCP_Sandpit
{
public interface ITestInterface
{
Int64 I64Value {get; set;}
}
[ServiceContract]
public interface IServer
{
[OperationContract]
[ServiceKnownType(typeof(TestMessageType))]
ITestInterface Test(ITestInterface msg);
}
[DataContract]
[KnownType(typeof(TestMessageType))]
public class TestMessageType : ITestInterface
{
Int64 _v1;
public long I64Value
{
get { return _v1; }
set { _v1 = value; }
}
public static Type[] KnownTypes()
{
return new Type[] { typeof(TestMessageType) };
}
}
}
The server code is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using WCF_TCP_Sandpit;
using System.Runtime.Serialization;
namespace Server
{
class Program : IServer
{
static void Main(string[] args)
{
using (ServiceHost serviceHost = new ServiceHost(typeof(Program), new Uri("net.tcp://127.0.0.1:9000")))
{
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
}
}
#region IServer Members
public ITestInterface Test(ITestInterface msg)
{
ITestInterface reply = new TestMessageType();
reply.I64Value = msg.I64Value * 2;
return reply;
}
#endregion
}
}
and the client code is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCF_TCP_Sandpit;
using System.ServiceModel;
namespace Client
{
class Program
{
static void Main(string[] args)
{
ITestInterface m,r;
int i = 0;
ChannelFactory<WCF_TCP_Sandpit.IServer> srv
= new ChannelFactory<WCF_TCP_Sandpit.IServer>
(new NetTcpBinding(), "net.tcp://127.0.0.1:9000");
WCF_TCP_Sandpit.IServer s;
s = srv.CreateChannel();
while (true)
{
m = new WCF_TCP_Sandpit.TestMessageType();
m.I64Value = i++;
r = s.Test(m);
Console.WriteLine("Sent " + m.I64Value + "; received " + r.I64Value);
System.Threading.Thread.Sleep(1000);
}
}
}
}
Can anyone cast some light on what's going wrong?
Don't you need the DataMember attribute on your I64Value property?

How do I authenticate a WCF Data Service?

I've created an ADO.Net WCF Data Service hosted in a Azure worker role. I want to pass credentials from a simple console client to the service then validate them using a QueryInterceptor. Unfortunately, the credentials don't seem to be making it over the wire.
The following is a simplified version of the code I'm using, starting with the DataService on the server:
using System;
using System.Data.Services;
using System.Linq.Expressions;
using System.ServiceModel;
using System.Web;
namespace Oslo.Worker
{
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
public class AdminService : DataService<OsloEntities>
{
public static void InitializeService(
IDataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
}
[QueryInterceptor("Pairs")]
public Expression<Func<Pair, bool>> OnQueryPairs()
{
// This doesn't work!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (HttpContext.Current.User.Identity.Name != "ADMIN")
throw new Exception("Ooops!");
return p => true;
}
}
}
Here's the AdminService I'm using to instantiate the AdminService in my Azure worker role:
using System;
using System.Data.Services;
namespace Oslo.Worker
{
public class AdminHost : DataServiceHost
{
public AdminHost(Uri baseAddress)
: base(typeof(AdminService), new Uri[] { baseAddress })
{
}
}
}
And finally, here's the client code.
using System;
using System.Data.Services.Client;
using System.Net;
using Oslo.Shared;
namespace Oslo.ClientTest
{
public class AdminContext : DataServiceContext
{
public AdminContext(Uri serviceRoot, string userName,
string password) : base(serviceRoot)
{
Credentials = new NetworkCredential(userName, password);
}
public DataServiceQuery<Order> Orders
{
get
{
return base.CreateQuery<Pair>("Orders");
}
}
}
}
I should mention that the code works great with the signal exception that the credentials are not being passed over the wire.
Any help in this regard would be greatly appreciated!
Thanks....
You must throw an exception of type DataServiceException.

WCF Relocation of DataContracts

This is a fully functional WCF Hello World program. I.e. I am able to run this program without any Exception.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace DataContractsNamespace
{
[DataContract]
public class AccountInfo
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace Clients
{
public class BankProxy : ServiceContractsNamespace.IBank
{
ServiceContractsNamespace.IBank channel;
public BankProxy()
{
channel = ChannelFactory<ServiceContractsNamespace.IBank>.CreateChannel(new BasicHttpBinding(), new EndpointAddress("http://localhost:8000/Services/BankService"));
}
public decimal GetAcccountBalance(string AcctNo)
{
return channel.GetAcccountBalance(AcctNo);
}
public DataContractsNamespace.AccountInfo GetAccountInfo(string AcctNo)
{
return channel.GetAccountInfo(AcctNo);
}
}
}
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Text;
namespace ServiceContractsNamespace
{
[ServiceContract]
public interface IBank
{
[OperationContract]
decimal GetAcccountBalance(string AcctNo);
[OperationContract]
DataContractsNamespace.AccountInfo GetAccountInfo(string AcctNo);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Clients
{
class Program
{
static void Main(string[] args)
{
BankProxy prox = new BankProxy();
Console.WriteLine("Hit enter to invoke the service call. Type exit then enter to close");
while (Console.ReadLine() != "exit")
{
string balance = prox.GetAcccountBalance("1234").ToString("c");
DataContractsNamespace.AccountInfo ai = prox.GetAccountInfo("1234");
Console.WriteLine("{0} {1} your account balance is {2}.", ai.FirstName, ai.LastName, balance);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Hosts
{
public class BankService : ServiceContractsNamespace.IBank
{
public decimal GetAcccountBalance(string AcctNo)
{
return 1.37m;
}
public DataContractsNamespace.AccountInfo GetAccountInfo(string AcctNo)
{
DataContractsNamespace.AccountInfo ai = new DataContractsNamespace.AccountInfo();
ai.FirstName = "Paul";
ai.LastName = "Johansen";
return ai;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace Hosts
{
class Program
{
static void Main(string[] args)
{
ServiceHost servHo = new ServiceHost(typeof(BankService), new Uri("http://localhost:8000/Services"));
servHo.AddServiceEndpoint(typeof(ServiceContractsNamespace.IBank), new BasicHttpBinding(), "BankService");
servHo.Open();
Console.WriteLine("This service is open for business. Hit Enter to close.");
Console.ReadLine();
servHo.Close();
}
}
}
As you can see, AccountInfo - Data contract is shared by both Client and Host.
I need to keep data contract only to Host/Service side.
Clients should only see interfaces of DataContracts (like IAccountInfo).
How should I modify my program to introduce IAccountInfo?
It sounds like you want to return an interface instead of a class. I'm not exactly sure why you are not content to return AccountInfo. However, you should be able to do this but you will need to use a KnownType or perhaps ServiceKnownType to make it work.
Alternately, if you are working in a fully .NET environment you can use the NetDataContractSerializer instead of the DataContractSerializer.
For reference and examples you can check out:
http://nirajrules.wordpress.com/2009/08/26/wcf-serializers-xmlserializer-vs-datacontratserializer-vs-netdatacontractserializer/
http://www.pluralsight.com/community/blogs/aaron/archive/2006/04/21/22284.aspx
http://weblogs.asp.net/avnerk/archive/2006/07/31/WCF-Serialization-part-1_3A00_-Interfaces_2C00_-Base-classes-and-the-NetDataContractFormatSerializer.aspx
http://www.thoughtshapes.com/WCF/ExampleTwo.htm
And what should IBank.GetAccountInfo return to client if you don't want to share AccountInfo? create 2 classes make the first datacontract the second not, and where you want to share use the first one, where not, the second one