Change Webservice address at runtime - C#

Asked

Viewed 1,306 times

2

I am developing an application that should connect to several Web services according to the user’s location.

For example:

If the user is in the city "To" it will connect to the web service: 192.168.1.1:8010 if he goes to town "B", will connect to 192.168.1.1:8020, in the city "C" 192.168.1.1:8030, and so on.

The address is always the same, what changes is the door.

Simple thing right?! Yeah, but I can’t make it work at runtime at all!

When I change the parameter URL of the web service at runtime the server only returns null, back to the original value the communication is restored. The same thing if the change is made before the compilation, ie, compile for city "To", works in the city "To", town hall "B", works in the city "B".

The application is being developed originally for Windows CE using VS2008 and CF3.5, however even in VS2013 with . Net Framework 4.0 the "problem" repeats.

Someone’s been through it?

I created a new application just to test the server exchange, follow the code:

WebReference.WSR testeWS = new WebReference.WSR();

private void btn_Troca_URL_Click(object sender, EventArgs e)
{
    if (URL_01)
    {
        testeWS.Url = "http://192.168.1.1:8010/WSR.apw";
        URL_01 = false;
    }
    else
    {
        testeWS.Url = "http://192.168.1.1:8020/WSR.apw";
        URL_01 = true;
    }
}

In this case the original (compiled) URL is "http://192.168.1.1:8010/WSR.apw" and for that URL everything works normally, when I click the button and switch to the URL "http://192.168.1.1:8020/WSR.apw", I only have null as an answer. By clicking again and returning to the original URL, everything works again.

If code is compiled to the URL "http://192.168.1.1:8020/WSR.apw" the "problem" is reversed.

Remembering that the "URL Behavior" property is set as Dynamic.

  • Put the snippet of code that connects to the web service currently on top of it to suggest how to do.

  • Code included above.

  • I know it’s not one of the best practices, but you’ve thought about referencing all the web services and instantiating and using the right just?

  • In the webservice properties, one of the properties there should be like Dynamic... Take a look there! Select the WS reference and press F4

  • We gave up making this business work this way and unified the webservices, passing the cities as a parameter. It’s not best practice, but at least we can achieve the goal.

1 answer

1

  1. I recommend not adding the reference (Web Service) to your project. So you will have more control in the code on how to consume this web service.

  2. Utilize Webrequest or a library like Restsharp:

Using Restsharp

//MEU EndPoint
var endPointRM = "{minha url WS}"


var client = new RestClient();
var request = new RestRequest(endPointRM, Method.POST);
request.AddParameter("matricula", matricula);
var usuario = client.Execute<UsuarioRM>(request).Data;

if (usuario != null)
    return new Dictionary<string, object> { { "Nome", usuario.Nome.Trim() }, { "Email", usuario.Email.Trim() } };
return null;

Using Webrequest

var response = GetResponseWS(matricula.ToString());
if (response ==  null)
    return null;
var usr = ConvertFromStream(response.GetResponseStream());

if (usr != null)
    return new Dictionary<string, object> { { "Nome", usr.Nome.Trim() }, { "Email", usr.Email.Trim() } };
return null;

And the auxiliary methods:

private HttpWebResponse GetResponseWS(string matricula)
{
    byte[] buffer = Encoding.ASCII.GetBytes(GetSoapEnvelope(matricula));
    //Initialization, webrequest
    HttpWebRequest WebReq =
    (HttpWebRequest)WebRequest.Create(endPointRM);

    //Set the method/action type
    WebReq.Method = "POST";

    //We use form contentType
    WebReq.ContentType = "text/xml; charset=utf-8";

    //The length of the buffer
    WebReq.ContentLength = buffer.Length;

    //We open a stream for writing the post  data
    Stream MyPostData = WebReq.GetRequestStream();

    //Now we write, and after wards, we close. Closing is always important!
    MyPostData.Write(buffer, 0, buffer.Length);
    MyPostData.Close();

    //Get the response handle, we have no true response yet!
    WebResponse resp;
    try
    {
        resp = WebReq.GetResponse();
        return (HttpWebResponse)resp;
    }
    catch (WebException wex)
    {
        Elmah.ErrorSignal.FromCurrentContext().Raise(wex);
        return null;
    }
    catch (Exception ex)
    {
        Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
        return null;
    }
}

private string GetSoapEnvelope(string matricula)
{
    return string.Format(@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<ConsultarInformacoesFuncionarioRmPorMatriculaPorColigada xmlns=""http://www.aec.com.br/"">
<matricula>{0}</matricula>
<codColigada>{1}</codColigada>
<token>{2}</token>
</ConsultarInformacoesFuncionarioRmPorMatriculaPorColigada>
</soap:Body>
</soap:Envelope>", matricula, 3, ConfigurationManager.AppSettings["tokenWS"]);
}

private UsuarioWS ConvertFromStream(Stream stream)
{
    var ds = new DataSet();
    ds.ReadXml(new StreamReader(stream), XmlReadMode.ReadSchema);

    return new UsuarioWS
    {
        Nome = ds.Tables[0].Rows[0]["NOME"].ToString()
        ,
        Email = ds.Tables[0].Rows[0]["EMAIL"].ToString()
    };
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.