How to use comboBox in asmx.cs to create a Web Service? - c#

I have basic knowledge to create a web service using asmx.cs
and consume from any client application.
I want to create a Web Service using asmx.cs in .NET 3.5 using Visual Studio 2010.
For the following program,By default it gives textBox to take input from user.
But I want to use comboBox to take input from the user.
The result will be displayed as xml output.
I want to do a Web Service program where one city from ComboBox will be taken as input
and the temperature will be shown as xml output.
This code gives only textBox as input.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
namespace WebService1
{
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string GetCityByZip(int Zip)
{
return "City Name = XYZ, Temperature = 30 Degree";
}
}
}

I think, what you're talking about is this html to test your web service methods, right?
http://3.bp.blogspot.com/_nuQwSyDoLk8/RvWnnpahW8I/AAAAAAAAAJw/UTFuJmCx5M0/s1600-h/WS3.bmp
This test ui is generated automatically based upon your service's WSDL.
The input types are based on the methods your service exposes. So if there's a method like CityInfo GetCityInfo(string cityName) in your service, there will be a textbox with input type string (as you already noticed). If you're exposing a method like CityInfo GetCityInfo(int cityId) the input type will be an int.
What's not possible, is to put a combobox there, as the service is autogenerated and has no knowledge which cities are selectable.
What you can do, is expose several methods and build a ui yourself (which you should do anyway).
public interface IYourServiceInterface
{
City[] GetCities(); // returns all possible cities
CityInfo GetCityInfo(City city); // returns detail Infos about a concrete city
}

Related

List Vs Datatable in web api response

I'm new in web api and I wrote a code in which I return a datatable in an IHttpActionResult and I want to know what is the difference between return a datatable and a list or dictionary.
this is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApplication2.BLL;
namespace WebApplication2.Controllers
{
public class HomeController : ApiController
{
public IHttpActionResult getpro()
{
var tabla= new Conexion().table();
tabla.TableName = "tablilla";
return Ok(tabla);
}
}
}
I am testing this in post man and is runing well, but I want to know if should I sent a list in the response or another object.
There might not be an apparent difference right now, but as your application grows, you might run into maintainability issues.
The issue is that right now, the signature of your API endpoint (i.e. what data it returns) is hard coupled to your database, so if you change your database, so does the result returned by your endpoint. That's usually a bad thing for anything but the smallest/simplest applications, since it might break consumers of your API.
What you'd do instead, is create models specifically for returning from your API endpoints and then convert (also called map) your datatable to a list of these "view"-models. This way, you can change the backend of your web API without it (immediately) having an impact on your frontend (or other consumers of your API).

"using" of two different libraries with almost identical functions

I'm consuming a SOAP web service. The web service designates a separate service URL for each of its customers. I don't know why they do that. All their functions and parameters are technically the same. But if I want to write a program for the service I have to know for each company is it intended. That means for a company called "apple" i have to use the following using statement:
using DMDelivery.apple;
and for the other called "orange"
using DMDelivery.orange;
But I would like to my program to work for all of them and have the name of the company or the service reference point as a parameter.
Update: If I have to write a separate application for each customer then I would have to keep all of them updated with each other with every small change and that would be one heck of an inefficient job as the number of customers increase.
Can anyone think of a solution? I'll be grateful.
If you have a base contract (interface) for all your services you can use a kind of factory to instantiate your concrete service and only have a reference to your interface in your client code (calling code).
//service interface
public interface IFruitService{
void SomeOperation();
}
//apple service
public class AppleService : IFruitService{
public void SomeOperation(){
//implementation
}
}
Having for example a kind of factory class (you can put your using statements here)
public static class ServiceFactory{
public static IFruitService CreateService(string kind){
if(kind == "apple")
return new AppleService();
else if(kind == "orange")
return new OrangeService();
else
return null;
}
}
And in your calling code (you just add an using statement for the namespace containing your interface):
string fruitKind = //get it from configuration
IFruitService service = ServiceFactory.CreateService( fruitKind );
service.SomeOperation();
You can also use the Dependency Injection principle.
If everything is the same and it's only the endpoint address that is different, maybe you can try changing only that before invoking the web service methods.
MyWebServiceObject ws= new MyWebServiceObject();
ws.Endpoint.Address = new System.ServiceModel.EndpointAddress("http://www.blah.com/apple.asmx");
Use any one client in your implementation. ex. Apple
Write a message inspector and attach this into the out going point
In message inspector replace the name space of the type with appropriate client name space.
EX:
Before Message inspector :MyClinet.Apple.Type
After Message Inspector : MyClient.Orange.Type, if the Provider is Orange.

WebServices & Namespace in C#

I have a web service with the namespace as the following:
namespace MyNS
{
class MyObject
{
//Implementation here
}
}
And I published the webservice and try to consume that webservice from the next C# Website.
I assigned the service name to "MyWS".
When I try to write the code
I have to write,
MyWS.MyObject obj = new MyWS.MyObject();
But I want to write
MyWS.MyNS.MyObject obj = new MyWS.MyNS.MyObject();
The problem is there might by MyObject class under other Namespaces. So, I want to identify my classes by NameSpaces.
What should I do to use Namespace in the coding?
I do not believe the original namespace is exposed as part of the WSDL, which is what the generation process uses to create the client end point.
This means there is no way to control what namespace your web service is used as.
However you can control what namespace your client end point uses. When you add the service reference, the bottom of the first page (Titled Add Service Reference, and containing Discovery controls) is a text box titled "Namespace". If you change that field to MyWS.MyNS when adding the service it should allow you to reference it as such.
The problem is there might by MyObject class under other Namespaces. So, I want to identify my classes by NameSpaces.
The compiler will give you an ambiguous reference error if you try to use conflicting object names. You will have to qualify them in that case.
So, if you want to give it a certain alias, just type the name as you want it.
namespace This.Is.My.Favorite.Namespace
{
public class MyObject()
{
//stuff
}
}
namespace MyNS.MyWS
{
class MyObject
{
//Implementation here
}
}

instantiating an object from a web service vs instantiating an object from a regular class

I have a very basic web service:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
namespace WebService1
{
/// <summary>
/// Summary description for Service1
/// </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 Service1 : System.Web.Services.WebService
{
public int myInt = 0;
[WebMethod]
public int increaseCounter()
{
myInt++;
return myInt;
}
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
}
when I run that project my browser opens showing me the service:
on a different solution: (console application)
I am able to connect to that service by adding the reference:
then click on the add web reference button:
Lastly I type the url of the service I just created:
Now I am able to instantiate an object from the class Service1 from my console application as:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication36
{
class Program
{
static void Main(string[] args)
{
localhost.Service1 service = new localhost.Service1();
// here is the part I don't understand..
// from a regular class you will expect myInt to increase every time you call
// the increseCounter method. Even if I call it twice I always get the same result.
int i;
i=service.increaseCounter();
i=service.increaseCounter();
Console.WriteLine(service.increaseCounter().ToString());
Console.Read();
}
}
}
why does myInt does not increase every time I call the increaseCounter method? every time I call that method it returns 1.
Services created through the older .asmx technology are not singleton instances. This means that each call you make to the server instantiates a new instance of the service each time. Two real solutions, either use static variables (eugh....), or switch to using WCF.
Becaue on the server side the class is created and disposed with EVERY call you make from the client... your client is just a "proxy" and doesn't correspond directly to an instance on the server side...
You can either make myInt static or make the server side service class a Singleton... both options would mean that myIntis shared across ALL client... or you could implement some session management to achieve a client-specific myInt... using WCF for the server side seems IMHO the best solution - it comes with configurable options for singleton, session management etc.
EDIT - as per comments:
With WCF you can have .NET-clients with session management which in turn allows you to have different (client-specific) values for myInt...
webservice instance is destroyed at the end of each method call, so that's why you always get the same result. You need some way to persist that value.

Class constructor (from C# web service) won't auto-implement properties in C# MVC

I'm running two instances of VS2010 on my local machine. One instance is running my Web Service (written in C#). The other instance is running my MVC web app (also C#). The MVC web app has a reference to the web service. I can successfully invoke web service methods from within the MVC app.
In my web service is a PageNavigation class:
// PageNavigation.cs
using System;
using System.Collections.Generic;
using System.Text;
public class PageNavigation
{
public string Page_Number { get; set; }
public string Page_Count { get; set; }
public PageNavigation()
{
Page_Number = "1";
Page_Count = "2";
}
}
By default, this should return an object with auto-implemented properties when I call the class constructor:
WebService.PageNavigation pageNavigation = new WebService.PageNavigation();
This works when constructing a PageNavigation object elsewhere in the web service.
pageNavigation.Page_Number
"1"
pageNavigation.Page_Count
"2"
However, running the same line of code on the MVC isn't giving the same result; the object's properties are all null values.
pageNavigation.Page_Number
null
pageNavigation.Page_Count
null
Is this the expected behavior? Is there a way to populate the properties with default values as intended? If more information is needed please let me know and I will update the question.
The service reference only sees the schema of your object, not business logic; in your case, your service reference just created a shell data type in the MVC application. When you create a service reference, it's actually creating another type with the same property names and types as the type defined in the service.
For your particular scenario (simply providing default property values and not more general business logic), you should be able to apply the [System.ComponentModel.DefaultValue] attribute to your properties in order for the class generator to recognize that these properties should be populated with a default value.
Incidentally, if the service reference were reusing existing types (if you had this type in a common library that was referenced both by the service and the application, for example), then your business logic would be intact.
An alternative would be to implement a factory pattern, whereby you call a function on the web service that instantiates (and optionally populates) the data object, then returns it to the client.
Yes, this is expected behaviour. The MVC site is not actually using your PageNavigation class. It is a simple copy (generated when you add the web service reference) containing of all the properties, but none of the methods, including the constructor.
You could work around this by refactoring your service so the entities are in a separate assembly and then you can reuse this assembly on the client as an option when you generate the proxy.
If you insist on using the same types between client and service, then on the "Advanced" tab of the "Add Service Reference" dialog, you can choose to reuse the types in your server assembly.
I would move that class out of the service and into a class library project referenced by the service and by the client.
And I wouldn't do this for such a small reason as default values. this violates SOA by coupling the service and the client. It will obviously not work for clients which are not running .NET.
What serializer are you using to deserialize the response from the server? Some of them (like the DataContractSerializer for example) do not call the default constructor.
The solution that you should use if you are in fact using DataContractSerializer is to use the OnDeserialized attribute like this:
using System.Runtime.Serialization;
public class PageNavigation
{
public string Page_Number { get; set; }
public string Page_Count { get; set; }
public PageNavigation()
{
Init();
}
[OnDeserialize]
void Init()
{
Page_Number = "1";
Page_Count = "2";
}
}

Categories