locked
Web Services RRS feed

  • Întrebare

  • Hello,

    I never used web services, so here is my question:

    I have an web application that basically is CRUD based. For some reasons a partner of my customer, prefer not to use the application, but to integrate it's relevant functionality in it's internal applications. Here comes te limitation. For security and business reasons my customer can't expose direct data and /or  explicit specification.  What I need to provide for the partner is: a way of indetification (let say that is enough to query against a user table for username, password and role with a true/false response. If true, can go further), a way for query in a table for a certain string (let say a serial number, also in a true/false maner. If true, can go further.) After this, he must save an order in a detail table for the previous, only the relevant informations. The last thing that must be available is to have the data of a database view designed for him .

    So, as a I say, I can't allow the partner to phisically connect to the database. So I think that maybe a way is to use webservice(s) for allowing all these. I am wrong or it's the correct approach, and if so, what can be relevant resources for learning to accomplish that (I meaning web services for reading and writing in database)?

     

    Best regards,

     

    Laurentiu

     

    duminică, 5 decembrie 2010 13:43

Răspunsuri

  • Buna Laurentiu,

    Aici poti pune intrebari si in romana.

    Am sa incerc sa-ti raspund la scenariul tau atingand 2 probleme mai mari. Evident ca sunt multe de discutat, dar pentru inceput iti voi recomanda cateva lucruri de citit:

    Ai zis ca ai nevoie de o modalitate prin care sa faci cat mai eficient accesul (scriere, citire) la baza de date. Sa tii cont ca la acest punct nu vorbim de contextul in care aceste operatii se fac prin intermediul serviciilor Web (care dpdv arhitectural este o decizie buna).
    Aici iti recomand sa treci prin .NET Framework 4.0 Training Kit si sa te uiti peste ADO.NET Entity Framework si toate modalitatile prin care poti expune datele. Gasesti aici acest Training Kit: http://msdn.microsoft.com/en-us/VS2010TrainingCourse.

    A doua problema descrisa este faptul ca esti intr-un mediu in care trebuie sa autentifici si autorizezi utilizatorii. Aici trebuie sa vezi "teoria": http://msdn.microsoft.com/en-us/library/bb386582.aspx. Cei de la IDesign chiar au niste exemple foarte concrete ce acopera diverse scenarii: http://www.idesign.net/idesign/DesktopDefault.aspx?tabindex=5&tabid=11.

    Iti recomand sa urmaresti www.microsoft.ro/evenimente. Aici publicam evenimente unde discutam despre asemene scenarii, fie in evenimente in persoana, fie online.

    Vezi ce rezolvi cu aceste materiale si ar trebui sa revii cu niste probleme punctuale, in cazul in care nu iese ceva.

    • Propus ca răspuns de cardasim luni, 21 februarie 2011 13:21
    • Anulare propunere ca răspuns de cardasim luni, 21 februarie 2011 13:22
    • Marcat ca răspuns de Denis Chiurtu luni, 21 februarie 2011 13:46
    luni, 21 februarie 2011 12:58
  • Eu as alege intre urmatoarele doua solutii:

    - servicii web realizate cu WCF, SOAP sau REST in fucntie de client (http://msdn.microsoft.com/en-us/netframework/aa663324);

    - sau WCF Data Services (implemenatarea MS pentru ODATA: http://msdn.microsoft.com/en-us/data/bb931106)

    In ambele solutii exista suport out-of-the-box pentru orice aspect al securitatii aplicatiei.

    • Marcat ca răspuns de Denis Chiurtu luni, 21 februarie 2011 13:46
    luni, 21 februarie 2011 13:30

Toate mesajele

  • Buna Laurentiu,

    Aici poti pune intrebari si in romana.

    Am sa incerc sa-ti raspund la scenariul tau atingand 2 probleme mai mari. Evident ca sunt multe de discutat, dar pentru inceput iti voi recomanda cateva lucruri de citit:

    Ai zis ca ai nevoie de o modalitate prin care sa faci cat mai eficient accesul (scriere, citire) la baza de date. Sa tii cont ca la acest punct nu vorbim de contextul in care aceste operatii se fac prin intermediul serviciilor Web (care dpdv arhitectural este o decizie buna).
    Aici iti recomand sa treci prin .NET Framework 4.0 Training Kit si sa te uiti peste ADO.NET Entity Framework si toate modalitatile prin care poti expune datele. Gasesti aici acest Training Kit: http://msdn.microsoft.com/en-us/VS2010TrainingCourse.

    A doua problema descrisa este faptul ca esti intr-un mediu in care trebuie sa autentifici si autorizezi utilizatorii. Aici trebuie sa vezi "teoria": http://msdn.microsoft.com/en-us/library/bb386582.aspx. Cei de la IDesign chiar au niste exemple foarte concrete ce acopera diverse scenarii: http://www.idesign.net/idesign/DesktopDefault.aspx?tabindex=5&tabid=11.

    Iti recomand sa urmaresti www.microsoft.ro/evenimente. Aici publicam evenimente unde discutam despre asemene scenarii, fie in evenimente in persoana, fie online.

    Vezi ce rezolvi cu aceste materiale si ar trebui sa revii cu niste probleme punctuale, in cazul in care nu iese ceva.

    • Propus ca răspuns de cardasim luni, 21 februarie 2011 13:21
    • Anulare propunere ca răspuns de cardasim luni, 21 februarie 2011 13:22
    • Marcat ca răspuns de Denis Chiurtu luni, 21 februarie 2011 13:46
    luni, 21 februarie 2011 12:58
  • Eu as alege intre urmatoarele doua solutii:

    - servicii web realizate cu WCF, SOAP sau REST in fucntie de client (http://msdn.microsoft.com/en-us/netframework/aa663324);

    - sau WCF Data Services (implemenatarea MS pentru ODATA: http://msdn.microsoft.com/en-us/data/bb931106)

    In ambele solutii exista suport out-of-the-box pentru orice aspect al securitatii aplicatiei.

    • Marcat ca răspuns de Denis Chiurtu luni, 21 februarie 2011 13:46
    luni, 21 februarie 2011 13:30
  • Salut,

     

    Intampin dificultati la metodele serviciului care au un parametru (sau mai multi).

    De exemplu GetUsername sau GetUserInfo care fac select cu parametrul username respectiv password:

    Codul aproximativ este:

        [WebMethod(Description = "Aflam daca username-ul si parola exista in baza de date")]
        public int GetUser(string Username, string Parola)
        {
          List<Useri> v_useri = new List<Useri>();
          //
          Esti_Logat = 0;
          SqlDatabase sqlDatabase = new SqlDatabase(ConfigurationManager.ConnectionStrings["ssBConnexionString"].ConnectionString);
          string sql = "pappseretideCauta_Useri";
          SqlCommand sqlCommand = sqlDatabase.GetStoredProcCommand(sql) as SqlCommand;
          try
          {
          //
          sqlDatabase.AddInParameter(sqlCommand, "@p_username", SqlDbType.VarChar, Username);
          sqlDatabase.AddInParameter(sqlCommand, "@p_parola", SqlDbType.VarChar, Parola);
          sqlDatabase.ExecuteNonQuery(sqlCommand);
          pappseretideCauta_UseriTableAdapter ta = new pappseretideCauta_UseriTableAdapter();
          v_useri = Array.ConvertAll<SeretideDataSet.pappseretideCauta_UseriRow, Useri>(ta.GetData(Username, Parola).ToArray(), new Converter<SeretideDataSet.pappseretideCauta_UseriRow, Useri>(r => new Useri() { username = r.username, parola = r.parola })).ToList();
          if (v_useri.Count == 1)
          {
            Esti_Logat = 1;
          }
          else
          {
            Esti_Logat = 0;
          }
          }
          catch (Exception err)
          {
            ssBWebService.Logger.ToEventLog(err); //Trebuie vazut de ce nu merge asta
            throw new Exception("Am intampinat o eroare la cautarea userului: " + err.Message);
          }
          //return v_useri;
          return Esti_Logat;
        }
        [WebMethod(Description = "Aflam detaliile userului logat")]
        public List<Useri> GetUserInfo(string Username, string Parola)
        {
          List<Useri> v_useri = new List<Useri>();
          //
          SqlDatabase sqlDatabase = new SqlDatabase(ConfigurationManager.ConnectionStrings["ssBConnexionString"].ConnectionString);
          string sql = "pappseretideCauta_Useri";
          SqlCommand sqlCommand = sqlDatabase.GetStoredProcCommand(sql) as SqlCommand;
          try
          {
            //
            if (Esti_Logat == 1)
            {
              sqlDatabase.AddInParameter(sqlCommand, "@p_username", SqlDbType.VarChar, Username);
              sqlDatabase.AddInParameter(sqlCommand, "@p_parola", SqlDbType.VarChar, Parola);
              sqlDatabase.ExecuteNonQuery(sqlCommand);
              pappseretideCauta_UseriTableAdapter ta = new pappseretideCauta_UseriTableAdapter();
              v_useri = Array.ConvertAll<SeretideDataSet.pappseretideCauta_UseriRow, Useri>(ta.GetData(Username, Parola).ToArray(), new Converter<SeretideDataSet.pappseretideCauta_UseriRow, Useri>(r => new Useri() { username = r.username, parola = r.parola })).ToList();
            }
          }
          catch (Exception err)
          {
            ssBWebService.Logger.ToEventLog(err); //Trebuie vazut de ce nu merge asta
            throw new Exception("Am intampinat o eroare la cautarea userului: " + err.Message);
          }
          return v_useri;
        }
    
    

    Fie ca fac deploy pe staging, fie ca lanasez din VS, primesc un HTTP 500 si nu stiu mai departe sa vad unde crapa.

    Procedura SQL din spate e aproximativ:

    -- Returns a specific record from the [dbo].[useri_seretide] table.
    CREATE PROCEDURE [dbo].[pappseretideCauta_Useri]
        -- @pk_id_user smallint,
        @p_username nchar(32),
        @p_parola nchar(32)
        
    AS
    DECLARE
      @l_count int
    
      
    BEGIN
    
      -- Get the rowcount first and make sure 
      -- only one row is returned
      SELECT @l_count = count(*) 
      FROM [dbo].[useri_seretide]
      WHERE [username] = @p_username and [parola] = @p_parola
    
      IF @l_count = 0
        RAISERROR ('The record no longer exists.', 16, 1)
      IF @l_count > 1
        RAISERROR ('duplicate object instances.', 16, 1)
      IF @l_count = 1
      -- Get the row from the query. Checksum value will be
      -- returned along the row data to support concurrency.
      SELECT 
        [id_user],
        [username],
        [parola],
        [nume_farma],
        [CUI],
        [denumire_completa],
        [rol_utilizator],
        CAST(BINARY_CHECKSUM([id_user],[username],[parola],[nume],[prenume],[detalii],[adresa],[localitatea],[judetul],[lantul],[data_op],[operat_de],[email],[telefon],[head_lant],[prima_vizita],[nume_farma],[CUI],[rol_utilizator],[denumire_completa],[adresa_completa]) AS nvarchar(4000)) AS IS_CHECKSUM_COLUMN_12345
      FROM [dbo].[useri_seretide]
      WHERE [username] =@p_username and [parola] =@p_parola
    END
    


    Orice alta metoda a serviciului care nu presupune nici un parametru merge.

    Probabil o eroare similara primesc si daca incerc metoda care vrea sa scrie in baza de date (tot cu parametri).

    duminică, 3 iulie 2011 19:58
  • Strict in privinta autentificarii, precizez ca mi se pare multumitor sa fac un query pe tabela de useri care sa-mi intoarca un recordcount de 1 sau respectiv 0. Asa cum am spus la inceput exista si o aplicatie web (de fapt sunt deja vreo 10 similare ca arhitectura si implementare), care continua sa fie exploatata si nu am motive sa schimb nimic aici. Doar ca anumiti partenri ai procesului de busines prefera sa implementeze functionalitatile ce-i privesc in aplicatiile lor de casa (ceea ce este ok, deoarce operatoarele lor faceau deja un flux de operatii de doua ori).


    In alta ordine de idei, nu am inteles cum se pot genera mesaje ce pot fi "prinse" de aplicatiile client ce consuma serviciul (ma refer la mesaje pur si simplu, nu la tratarea exceptiilor), de exemplu "Am salvat cu succes" sau "Nu am gasit inregistrarea"?
    • Editat de net4u marți, 5 iulie 2011 22:42 Precizari
    duminică, 3 iulie 2011 20:16