My project is to write a web service and a web form that consumes it. It should have two text boxes and a button. The user enters an text speak acronym in the first text box and presses the button. The web service compares the textbox1 entry against a dictionary file, and displays the resulting full word in the second text box. This is the code I have so far and I am really struggling to get it to work, any help would be appreciated. At this point I have 'Type or namespace definition, or end of file expected' error. Here are the two files i have.
Default.aspx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
private Dictionary<string, string> _dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
protected void Page_Load(object sender, EventArgs e)
{
using (var reader = new StreamReader(File.OpenRead(#"C:/dictionary.csv")))
{
while (!reader.EndOfStream)
{
string[] tokens = reader.ReadLine().Split(';');
_dictionary[tokens[0]] = tokens[1];
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
localhost.Service obj = new localhost.Service();
TextBox1.Text = (obj.Translate());
}
}
Service.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.IO;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class Service : System.Web.Services.WebService
{
public Service () {
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public string Translate(string input)
{
string output;
if(_dictionary.TryGetValue(input, out output))
return output;
// Obviously you might not want to throw an exception in this basis example,
// you might just go return "ERROR". Up to you, but those requirements are
// beyond the scope of the question! :)
throw new Exception("Sinatra doesn't know this ditty");
}
}
}
Not sure if the question is still unanswered. But here are my suggestions.
In the web service file i.e. say Service1.cs you are not declaring the _dictionary object. So you will be moving the dictionary object declaration and initialization in the constructor of the service.
Some thing like this below.
public WebService1()
{
using (var reader = new StreamReader(File.OpenRead(#"C:/dictionary.csv")))
{
while (!reader.EndOfStream)
{
string[] tokens = reader.ReadLine().Split(',');
_dictionary[tokens[0]] = tokens[1];
}
}
}
Also in the split method I would assume you wanted to use the comma instead of the semicolon(that was used in your sample).
And then in the consumption of the service, you would do some thing like this below. I was not sure what you were trying to do using the localhost object in your sample.
ServiceReference1.WebService1SoapClient obj = new WebService1SoapClient();
TextBox2.Text = obj.Translate(TextBox1.Text);
Hope this helps.
-Davood.
Related
I am really new in JSON, and I am trying to create a web service(.asmx) in c# that will return the JSON object with key and value. I am creating this web service for one of my android app that why its must to return the JSON object with key and its value. Below is my code of web sevice:
using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Json;
using System.Web.Services;
using System.Runtime.Serialization.Json;
using System.Web.Script.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.IO;
using System.Web.Script.Services;
using System.Collections.Generic;
namespace WebServiceExample
{
/// <summary>
/// Summary description for AddTwoNumbers
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
//[System.Web.Script.Services.ScriptService]
public class AddTwoNumbers : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string Add(int a, int b)
{
// 1st way to return Key and Value
JsonObject jso = new JsonObject();
JsonValue jv1 = 1;
JsonValue jv2 = 2;
jso.Add("Key-1", jv1.ToString());
jso.Add("BoolValue", jv2.ToString());
JavaScriptSerializer js = new JavaScriptSerializer();
string strJSON = js.Serialize(jso);
return strJSON;
}
}
}
With the above code I am getting the following output:
http://d.pr/i/NWxp
Please click on the above link to see my output.
As you can see I am getting the key but not the value. I am stuck.
Please help. Thanks
EDIT : If I am doing in a wrong way, so please suggest me the right way to add keys and values in JSON object. I searched a lot on google but unable to understand properly.
ANY QUICK HELP PLEASE
UPDATE :
public string GetPeople()
{
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("Key-1", "value-1");
dict.Add("Key-2", "value-2");
dict.Add("Key-3", "value-3");
JavaScriptSerializer js = new JavaScriptSerializer();
string strJSON = js.Serialize(dict);
return strJSON;
}
I have a few questions regarding WCF:
- Can a program act as both client and server ?
- What's wrong with my code :
The service:
[ServiceContract]
public interface IShout
{
[OperationContract]
String Broadcast(String message);
}
The implementation:
public class eveShout : IShout
{
public String Broadcast(String message)
{
return message + " reply";
}
}
I start the service in the form contructor:
ServiceHost s = new ServiceHost(typeof(IShout));
s.AddServiceEndpoint(typeof(IShout), new BasicHttpBinding(), "http://localhost:9189");
s.Open();
The, When I click a button on another form, I want to send a message and get a reply back.
I use the following code:
ChannelFactory<IShout> channel = new ChannelFactory<IShout>(new BasicHttpBinding(), "http://localhost:9189");
IShout shout = channel.CreateChannel();
String reply = shout.Broadcast("Test");
Note: all the code is in the same namespace.
Note: I first start the "server" (open) then the app continues.
when i run the code, the server is created. I use netstat -a to see if the port is open. when I run the command, i get 9189 is in listening state. but the code stops at the command reply = shout("test"). and I get anexception that says
The request channel timeout while waiting for a reply after 00:00:59...
Yes, you can have an app act as both client and server.
I see a couple of things that may need correcting. First, try adding OperationContract.
[ServiceContract]
public interface IShout
{
[OperationContract]
String Broadcast(String message);
}
Then, take the type of the class, not the interface.
ServiceHost s = new ServiceHost(typeof(eveShout));
s.AddServiceEndpoint(typeof(IShout), new BasicHttpBinding(), "http://localhost:9189");
s.Open();
Make sure you you have permission to access the namespace (s.Open() should throw an exception if it does not).
net http add urlacl url=http://+:9189/ user=...
See if these suggestions help.
(oh yeh, and make Broadcast public in your class)
A quick example WindowsFormsApplication looks like this...
// form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ChannelFactory<IShout> channel = new ChannelFactory<IShout>(new BasicHttpBinding(), "http://localhost:9189");
IShout shout = channel.CreateChannel();
String reply = shout.Broadcast("Test");
}
}
}
// and Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.ServiceModel;
namespace WindowsFormsApplication1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
ServiceHost s = new ServiceHost(typeof(eveShout));
s.AddServiceEndpoint(typeof(IShout), new BasicHttpBinding(), "http://localhost:9189");
s.Open();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
public class eveShout : IShout
{
public String Broadcast(String message)
{
return message + " reply";
}
}
[ServiceContract]
public interface IShout
{
[OperationContract]
String Broadcast(String message);
}
}
See if you can get something as simple as this working. That will at least prove to you that it can be done and that the problem is somewhere else.
Enable WCF debugging.
The easiest way to do this is with WCF Service Configuration Editor. Open the utility and then browse to open your application's configuration file. From the diagnostics section simply click 'enable tracing'. The default tracing will be fine.
Once you run your application, the framework will dump a log file to a location specified in your configuration file. Double click to open it and read through the red events (these are the ones that have exceptions or unexpected outcome). It's very helpful and should help you identify where the problem is occurring.
I’m pretty new to programming, so bear with me if my question isn’t specific enough. Right now I’m trying to make a simple Client Logon to my server. So the server App knows which users are connected. When a client connects I want an event to fire on the server that update the userlist. But it doesn’t and I can’t figure out why. Hope you can help.
In the codes I have removed how the users should be displayed in the serverApp. Right now I just need the event to work.
In my Service Library:
INetworkService contract:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace NetworkLib
{
[ServiceContract]
public interface INetworkService
{
[OperationContract]
void Logon(UserInfo userInfo);
[OperationContract]
void Logout();
}
}
NetworkService Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace NetworkLib
{
public class NetworkService : INetworkService
{
public event EventHandler UserListChanged;
public void Logon(UserInfo userInfo)
{
OnUserListChanged();
}
public void Logout()
{
OnUserListChanged();
}
private void OnUserListChanged()
{
var handler = UserListChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
}
UserInfo Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace NetworkLib
{
[DataContract]
public class UserInfo
{
[DataMember]
public string Name;
}
}
In my ServerApp (WPF):
using System.ServiceModel;
using NetworkLib;
namespace ServerApp
{
public partial class MainWindow : Window
{
NetworkService networkService;
public MainWindow()
{
InitializeComponent();
ServiceHost host = new ServiceHost(typeof(NetworkService));
host.Open();
networkService = new NetworkService();
networkService.UserListChanged += networkService_UserListChanged;
}
private void networkService_UserListChanged(object sender, EventArgs e)
{
MessageBox.Show("It Works!");
}
}
}
In my ClientApp (WPF): (Have made a Service Reference to the Server)
namespace ClientApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
ServiceReference.NetworkServiceClient proxy = new ServiceReference.NetworkServiceClient();
ServiceReference.UserInfo userInfo = new ServiceReference.UserInfo();
userInfo.Name = "Test";
proxy.Logon(userInfo);
}
}
}
You subscribe to event of other NetworkService instance than ServiceHost instantiates. In your case every time you make request to server, new NetworkService instance is created. Place the following attribute above NetworkService class:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
Then subscribe to event:
var serviceInstance = (NetworkService)host.SingletonInstance;
serviceInstance.UserListChanged += networkService_UserListChanged;
When creating your ServiceHost, you should provide NetworkService instance instead of typeof(NetworkService)
ServiceHost host = new ServiceHost(networkService);
You need to initialize it first, of course.
I didnt look in great detail but overall your code looks ok. It is sometimes useful in this situation to run 2 instances of VisualStudio - one for server in debug and one for client in debug. If you put a break point in client button1_Click code in VS thats debugging client, and a break point in NetworkServices.Logout in VS thats debugging server you will be able to step from client to server code and see easily whats going wrong where.
Why do you need an event model here? Why not just handle your "event" directly in NetworkService.Logout(). Does pushing this off to an event and then having to wire that event (which as ilya.dofofeev correctly points out is not on the same object) provide any real benefit?
I have the following code, that uses session but i have an error in the line :
if (Session["ShoppingCart"] == null)
the error is cS0103: The name 'Session' does not exist in the current context what is the problem ?
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Web.SessionState;
/// <summary>
/// Summary description for ShoppingCart
/// </summary>
public class ShoppingCart
{
List<CartItem> list;
public ShoppingCart()
{
if (Session["ShoppingCart"] == null)
list = new List<CartItem>();
else
list = (List<CartItem>)Session["ShoppingCart"];
}
}
Use
if (HttpContext.Current == null ||
HttpContext.Current.Session == null ||
HttpContext.Current.Session["ShoppingCart"] == null)
instead of
if (Session["ShoppingCart"] == null)
The issue is that your class does not inherit from Page. you need to Change
public class ShoppingCart
to
public class ShoppingCart : Page
and it will work
You either need to convert your class to a Page by inheriting from Page, or have the Session passed in, or use HttpContext.Current.Session.
If you want to use session directly then just simply add following namespace
using system.web.mvc
In my case only try-catch block fix problem, like this:
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
/// Using from Try-Catch to handle "Session state is not available in this context." error.
try
{
//must incorporate error handling because this applies to a much wider range of pages
//let the system do the fallback to invariant
if (Session["_culture"] != null)
{
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(Session["_culture"].ToString());
//it's safer to make sure you are feeding it a specific culture and avoid exceptions
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(Session["_culture"].ToString());
}
}
catch (Exception ex)
{}
}
I am reading Designing Evolvable Web APIs with ASP.NET. In one of the exercises, the book has me edit a Controller using Visual Studio. This is being done in ASP.NET using C#. The template I used was the standard ASP.NET web application API.
I have edited the controller to the way the book shows (although it does not seem to give very specific directions). Here is what my controller looks like.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OAuth;
using WebApplication4.Models;
using WebApplication4.Providers;
using WebApplication4.Results;
namespace WebApplication4.Controllers
{
public class GreetingController : ApiController
{
public string GetGreeting() {
return "Hello World!";
}
}
public static List<Greeting> _greetings = new List<Greeting>();
public HttpResponseMessage PostGreeting(Greeting greeting)
{
_greetings.Add(greeting);
var greetingLocation = new Uri(this.Request.RequestUri, "greeting/" + greeting.Name);
var response = this.Request.CreateResponse(HttpStatusCodeResult.Created);
response.Headers.Location = greetingLocation;
return response;
}
}
I get errors on:
_greetings: A namespace cannot directly contain members such as fields or methods
PostGreeting: A namespace cannot directly contain members such as fields or methods,
_greetings : does not exist in the current context
Request : <invalid-global-code> does not contain a definition for 'request',
Created: HttpStatusCodeREsult does not contain a definition for 'Created'
As the error is trying to tell you, your fields and methods must be inside the class.
Check your braces.
Your _greetings field needs to be part of the class, as well as the PostGreeting method, it seems you just closed "}" of the class a bit early.
MOve the "}" before the _greetings field to the end of the file, like:
namespace WebApplication4.Controllers
{
public class GreetingController : ApiController
{
public string GetGreeting() {
return "Hello World!";
}
public static List<Greeting> _greetings = new List<Greeting>();
public HttpResponseMessage PostGreeting(Greeting greeting)
{
_greetings.Add(greeting);
var greetingLocation = new Uri(this.Request.RequestUri, "greeting/" + greeting.Name);
var response = this.Request.CreateResponse(HttpStatusCodeResult.Created);
response.Headers.Location = greetingLocation;
return response;
}
}
}