I am working on a project for school and I need to create a WCF service that I can use in my original solution.
I created the service by going to File -> New Project -> WCF Service Application (add to solution) and then I added the service reference by right clicking References under Assignment8 solution and new reference. Then I discovered services in the solution and added the Product service.
I am currently getting the error:
'Assignment8.Product.ProductClient' does not contain a definition for 'UpdateProduct' and no extension method 'UpdateProduct' accepting a first argument of type 'Assignment8.Product.ProductClient' could be found (are you missing a using directive or an assembly reference?)
The error occurs in UpdateProduct.aspx.cs on the line with the if statement in the Button1_Click method. What am I doing wrong?
Here are my files:
IProduct.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace ProductService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IProduct
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
[OperationContract]
Boolean UpdateProduct(int productID, string productName, string productDescription, decimal productPrice, decimal productCost);
// TODO: Add your service operations here
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
}
Product.svc
<%# ServiceHost Language="C#" Debug="true" Service="ProductService.Product" CodeBehind="Product.svc.cs" %>
Product.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace ProductService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class Product : IProduct
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
public bool UpdateProduct(int productID, string productName, string productDescription, decimal productPrice, decimal productCost)
{
return false;
}
}
}
UpdateProduct.aspx.cs
protected void Button1_Click(object sender, EventArgs e)
{
using (Product.ProductClient orderproxy = new Product.ProductClient())
{
if(orderproxy.UpdateProduct(Request.QueryString["ID"], txtProductName.Text, txtProductName.Text, txtProductDescription.Text, Convert.ToDecimal(txtProductPrice.Text), Convert.ToDecimal(txtProductCost.Text))){
Response.Redirect("~/ProductList.aspx");
} else {
lblStatus.Text = "The product could not be updated.";
}
}
}
Your function definition of UpdateProduct takes only 5 arguments but in your call you are passing 6 arguments
Related
I created a WCF service that retrieves data from a database and displays the information.
First question: When I submit the app to the store, does the WCF service get bundled with app, how does that work?
Second question: I noticed when the service is running, IIS is also running on my system, so what happens if a user doesn't have IIS or what happens when it runs on a windows phone.
Lastly, I noticed when IIS isn't running and I open the app, the app crashes, why does it do so, shouldn't it be able to start the service?
Please I am not an expert on this, and this is my first time using a WCF service, so be patient with me and give as much detail as possible.
Thanks.
WCF service:
namespace CustomerService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class Service1 : IService1
{
SqlConnection sqlCon = new SqlConnection("Data Source=MOD;Initial Catalog=DB2;User ID=sa;Password=*********");
public Customer getCustomer()
{
try
{
sqlCon.Open();
string strSql = "SELECT * FROM Table_1";
DataSet ds = new DataSet();
SqlDataAdapter sqlDa = new SqlDataAdapter(strSql, sqlCon);
sqlDa.Fill(ds);
Customer objCus = new Customer();
objCus.Age = (int)ds.Tables[0].Rows[0][0];
objCus.Name = ds.Tables[0].Rows[0][1].ToString();
return objCus;
}
catch
{
return null;
}
finally
{
sqlCon.Close();
}
}
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
}
namespace CustomerService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
[OperationContract]
Customer getCustomer();
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
[DataContract]
public class Customer
{
int age;
string name;
[DataMember]
public int Age
{
get { return age; }
set { age = value; }
}
[DataMember]
public string Name
{
get { return name; }
set { name = value; }
}
}
}
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
ServiceReference1.Service1Client obj = new ServiceReference1.Service1Client();
public MainPage()
{
this.InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
ServiceReference1.Customer g = await obj.getCustomerAsync();
ageTB.Text = g.Age.ToString();
nameTB.Text = g.Name;
}
}
WCF Services are meant to be backend services. This means that it is not shipped with the app, but it is hosted somewhere else.
So:
Question1: No, it is not bundled to the app, you have to take care about the hosting
Question2: Visual Studio starts an IIS for you, but in production it should be hosted on a server. A Windows Phone app typically connects to it via the internet. One hosting option would be Azure…
Question3: If the service is not available the app should deal with it… (For example a try catch in the Button_Click event handler would do the work..)
I am essentially trying to call a C# form from a vbscript. I have been able to get the interoperability to work on non-forms. The following works:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using InteropTestingForm;
[assembly:System.CLSCompliant(true)]
[assembly: ComVisible(true)]
[assembly:Guid("a22f4018-8f32-4c02-a748-6701fb617aa3")]
namespace InteropTesting
{
[Guid("a22f4018-8f32-4c02-a748-6701fb617aa3")]
public class TestReply
{
public string salutation;
public string name;
public string time;
}
[Guid("a22f4018-8f32-4c02-a748-6701fb617aa4")]
public class TestObj
{
public TestObj() { }
public TestReply SayHello(string addressee)
{
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(Form1());
return SayHello(addressee, "hello");
}
public TestReply SayHello(string addressee, string greeting)
{
string x = String.Format("{0}, {1}!", greeting, addressee);
Console.WriteLine("{0}", x);
TestReply r = new TestReply
{
salutation = greeting,
name = addressee,
time = System.DateTime.Now.ToString("u")
};
return r;
}
}
}
As can be seen in my SayHello() function, I want to run another form, possibly in the same namespace. I am not sure how to accomplish this. I keep getting the following error: "The type or namespace name Form1() could not be found (are you missing a using directive or an assembly reference)? when I try to run the following command from a Visual Studio command prompt:
csc.exe /t:library /debug+ /keyfile:InteropTesting.snk /out:InteropTesting.dll TestObj.cs
In my BLL class I'm trying to make an instance of the DAL class. But thos shows an error on following line:
DAL obj = new DAL();
What am I doing wrong? Although I have kept a reference of the DAL class in BLL. This is the error-message:
'DAL' is a 'namespace' but is used like a 'type
Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace BLL
{
public class Class1
{
public void Insert(string fname, string lname, string alias, int contact, string address, string company, string bdate, string email)
{
DAL obj = new DAL();
try
{
obj.Insert( fname, lname,alias, contact,address,company,bdate,email);
}
catch (Exception ex)
{
throw ex;
}
}
}
}
You don't have a class BLL, you have a namespace named BLL. The class you have in this namespace is Class1. Probably you're making the same mistake with DAL, meaning it is also a namespace and not a class. Here's how it should look:
DAL:
namespace DAL
{
public class Database
{
public void Insert(string name, string alias, ...)
{
//Logic here
}
}
}
BLL:
using DAL;
namespace BLL
{
public class Repository
{
public void Insert(string name, string alias, ...)
{
Database _obj = new Database();
//Logic here
}
}
}
I am trying to use the method of binding located here but having no luck
https://github.com/ninject/ninject.extensions.factory/wiki/Factory-interface
https://github.com/ninject/ninject.extensions.factory/wiki/Factory-interface%3A-Referencing-Named-Bindings
Keep in mind I am not trying to do it this way:https://gist.github.com/akimboyko/4593576
Rather I am trying to use the convention GetMercedes() to mean
I am basically trying to achieve this:https://gist.github.com/akimboyko/4593576 with conventions specified in the above examples.
using Ninject;
using Ninject.Extensions.Factory;
using Ninject.Modules;
using Ninject.Parameters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Test.NinjectFactory
{
public class Program
{
public static void Main()
{
using (var kernel = new StandardKernel(new CarModule()))
{
var factory = kernel.Get<ICarFactory>();
var mercedes =factory.GetMercedes();
int i = 1;
}
}
public interface ICar
{
void Drive();
}
public class Mercedes : ICar
{
readonly ICarFactory carFactory;
public Mercedes(ICarFactory carFactory)
{
this.carFactory = carFactory;
}
public void Drive()
{
var Mercedes = this.carFactory.GetMercedes();
}
}
public interface ICarFactory
{
ICar GetMercedes();
}
public class CarModule : NinjectModule
{
public override void Load()
{
//https://github.com/ninject/ninject.extensions.factory/wiki/Factory-interface%3A-Referencing-Named-Bindings
Kernel.Bind<ICarFactory>().ToFactory();
Bind<ICar>().To<Mercedes>().NamedLikeFactoryMethod<ICarFactory>(x => x.GetMercedes());//doesnt work for me
}
}
}
}
I'm posting this as an answer because it is most likely the cause.
The factory extensions use prefixed Get methods as a standard. You'll run into issues by calling any of your factory methods with prefixed Get and using NamedLikeFactoryMethod. For example, GetFord, GetMercedes, GetNissan. You'll notice that, in the example at the link you provided, the function is called CreateMercedes.
Change your function name to CreateMercedes or anything that doesn't start with Get and it should be fine.
I found the anwswer here:
https://gist.github.com/akimboyko/5338320
It seems you need a function to take care of the binding
public class BaseTypeBindingGenerator<InterfaceType> : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
if (type != null && !type.IsAbstract && type.IsClass && typeof(InterfaceType).IsAssignableFrom(type))
{
string.Format("Binds '{0}' to '{1}' as '{2}", type, type.Name, typeof(InterfaceType)).Dump();
yield return bindingRoot.Bind(typeof(InterfaceType))
.To(type)
.Named(type.Name) as IBindingWhenInNamedWithOrOnSyntax<object>;
}
}
}
This is my first WCF Server:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace Myns.MBClient
{
[ServiceContract]
public interface IManagementConsole
{
[OperationContract]
ConsoleData GetData(int strategyId);
}
[ServiceContract]
public class ConsoleData
{
private int currentIndicator;
[OperationContract]
public double GetCurrentIndicator()
{
return currentIndicator;
}
public void SetCurrentIndicator(int currentIndicator)
{
this.currentIndicator = currentIndicator;
}
}
class ManagementConsole : IManagementConsole
{
public ConsoleData GetData(int strategyId)
{
ConsoleData data = new ConsoleData();
data.SetCurrentIndicator(33);
return data;
}
}
}
In client I just call pipeProxy.GetData(0).GetCurrentIndicator()
Why program prints 0 while it supposed to print 33?
Client code (which I think has no problems):
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using Commons;
using myns.MBClient;
namespace myns.MBClientConsole
{
class Program
{
static void Main(string[] args)
{
ChannelFactory<IManagementConsole> pipeFactory =
new ChannelFactory<IManagementConsole>(
new NetNamedPipeBinding(),
new EndpointAddress(
"net.pipe://localhost/PipeMBClientManagementConsole"));
IManagementConsole pipeProxy =
pipeFactory.CreateChannel();
while (true)
{
string str = Console.ReadLine();
Console.WriteLine("pipe: " +
pipeProxy.GetData(0).GetCurrentIndicator());
}
}
}
}
If you create your own complex type to use with WCF you have to add a DataContract attribute instead of a ServiceContract, and you should use fields/properties that are decorated with DataMember. And do yourself a favor and use plain DTOs (DataTransferObjects - Objects with only fields/properties but no behavior):
[DataContract]
public class ConsoleData
{
[DataMember]
public int CurrentIndicator {get;set;}
}
You can find more on this here