Mail z linkiem do zmiany hasła

Mail z linkiem do zmiany hasła
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

Robie w moim panelu logowania zakładke "Przypomnij hasło". Problem pojawia się w linijce:

Kopiuj
user = Membership.GetUser(foundUserName.ToString());

Za każdym razem zwraca NULL mimo że "foundUserName" zawiera prawidłową wartość. Czytałem że ".GetUser" działa tylko dla użytkowników zalogowanych..jak to można obejść? Prosze o pomoc.

Ponizej kod:

Kopiuj
[HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult _Retrieval(RetrievalModel model)
        { 
             if (ModelState.IsValid)
   {
      MembershipUser user;
      using (var context = new EFDbContext())
      {
         var foundUserName = (from u in context.UserProfile
                              where u.eMail == model.eMail
                              select u.UserName).FirstOrDefault();
         if (foundUserName != null)
         {
            user = Membership.GetUser(foundUserName.ToString());
         }
         else
         {
            user = null;
         }
      }
      if (user != null)
      {
         // Generae password token that will be used in the email link to authenticate user
         var token = WebSecurity.GeneratePasswordResetToken(user.UserName);
         // Generate the html link sent via email
         string resetLink = "<a href='"
            + Url.Action("ResetPassword", "Account", new { rt = token }, "http") 
            + "'>Reset Password Link</a>";
 
         // Email stuff
         string subject = "Reset your password for test@tests.com"";
         string body = "You link: " + resetLink;
         string from = "test@tests.com";
 
         MailMessage message = new MailMessage(from, model.eMail);
         message.Subject = subject;
         message.Body = body;
         SmtpClient client = new SmtpClient();
 
         // Attempt to send the email
         try
         {
            client.Send(message);
         }
         catch (Exception e)
         {
            ModelState.AddModelError("", "Issue sending email: " + e.Message);
         }
      }         
      else 
      {
        
         ModelState.AddModelError("", "No user found by that email.");
      }
   }
            return View();
        }
AsYlum
  • Rejestracja:prawie 19 lat
  • Ostatnio:30 dni
  • Postów:29
1

Metoda GetUser() bez parametru zwraca informacje o aktualnie zalogowanym użytkowniku. Ta z parametrem powinna bez problemu zwrócić MembershipUser jeśli taki istnieje.

http://msdn.microsoft.com/pl-pl/library/40w5063z(v=vs.110).aspx

If you use one of the GetUser overloads that does not take a username parameter, GetUser returns the information for the current logged-on membership user. The current logged-on membership user is identified by the Name of the user in the current HttpContext.

Może ten użytkownik nie istnieje w bazie? Na pewno tam jest? :) (edit: wiem, że głupie pytanie).

A wykonanie np.

Kopiuj
user = Membership.GetUser("mojPoprawnyLogin");

też zwraca null?

I czy nie prościej skorzystać z metody

Kopiuj
string foundUserName = Membership.GetUserNameByEmail(model.eMail); 

?


<uninitialized object="object">
edytowany 1x, ostatnio: AsYlum
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
1
AsYlum napisał(a):

Metoda GetUser() bez parametru zwraca informacje o aktualnie zalogowanym użytkowniku. Ta z parametrem powinna bez problemu zwrócić MembershipUser jeśli taki istnieje.

Może ten użytkownik nie istnieje w bazie? Na pewno tam jest? :) (edit: wiem, że głupie pytanie).

I czy nie prościej skorzystać z metody

Kopiuj
string foundUserName = Membership.GetUserNameByEmail(model.eMail); 

?

Nie ma głupich pytań:) Tak, istnieje w bazie. Gdy podaje maila w panelu, zmienna "foundUserName" zwraca poprawnego uzytkownika który jest do niego przypisany.

No tak, siłą rzeczy gdy uzytkownik chce zmienić w tym przypadku hasło to nie może być zalogowany...

Edit: Czyli rozumiem że zamiast kombinowania z linq:

Kopiuj
    var foundUserName = (from u in context.UserProfile
                              where u.eMail == model.eMail
                              select u.UserName).FirstOrDefault(); 

moge zastosować:

Kopiuj
  
string foundUserName = Membership.GetUserNameByEmail(model.eMail);
edytowany 4x, ostatnio: Sebastiano
AsYlum
  • Rejestracja:prawie 19 lat
  • Ostatnio:30 dni
  • Postów:29
0

Tak. Może trochę to kosmetyka, ale wydaje się bardziej czytelne :) Warto się upewnić czy model.eMail w ogóle zawiera poprawny adres email. Jeżeli metoda GetUserNameByEmail nie znajdzie pasującej nazwy użytkownika dla podanego adresu to zwróci null.


<uninitialized object="object">
edytowany 1x, ostatnio: AsYlum
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
1

@AsYlum Przetestowałem i dalej jest problem. Wrzucam w załączniku porównanie dwóch metod. Zapytanie linq zwraca poprawną wartość natomiast powyższy sposób zwraca NULL, lecz na sam koniec i tak dostaje błąd:

Kopiuj
The model item passed into the dictionary is of type 'iAppTest.Models.RetrievalModel', but this dictionary requires a model item of type 'iAppTest.Models.RegisterModel'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type 'iAppTest.Models.RetrievalModel', but this dictionary requires a model item of type 'iAppTest.Models.RegisterModel'.

Edit: Natomiast jesli zrobie w ten sposób to zwraca NULLA mimo że uzytkownik jest w bazie:

Kopiuj
user = Membership.GetUser("testowy");
edytowany 2x, ostatnio: Sebastiano
AsYlum
  • Rejestracja:prawie 19 lat
  • Ostatnio:30 dni
  • Postów:29
1
Sebastiano napisał(a):

@AsYlum Przetestowałem i dalej jest problem. Wrzucam w załączniku porównanie dwóch metod. Zapytanie linq zwraca poprawną wartość natomiast powyższy sposób zwraca NULL, lecz na sam koniec i tak dostaje błąd:

Kopiuj
The model item passed into the dictionary is of type 'iAppTest.Models.RetrievalModel', but this dictionary requires a model item of type 'iAppTest.Models.RegisterModel'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type 'iAppTest.Models.RetrievalModel', but this dictionary requires a model item of type 'iAppTest.Models.RegisterModel'.

Wyjątek występuje przy wywołaniu GetUserNameByEmail(), a nie czasem dalej? Ta metoda spodziewa się jako parametru stringa i ten wyjątek trochę nie pasuje :)

Sebastiano napisał(a):

Edit: Natomiast jesli zrobie w ten sposób to zwraca NULLA mimo że uzytkownik jest w bazie:

Kopiuj
user = Membership.GetUser("testowy");

Skoro Membership.GetUser("testowy") nie zwraca obiektu użytkownika dla poprawnego loginu to obstawiam problem z konfiguracją albo komunikacją membership providera z bazą.


<uninitialized object="object">
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

Debbugowałem raz jeszcze krok po kroku całą metode. Przepływ wszystkich danych jest ok tylko problem pojawia sie na sam koniec przy:

Kopiuj
return view(model);

Nie ma pasuje mu ten model ale nie wiem czemu, i chyba dlatego też mail nie chce się wysłac;/

edytowany 3x, ostatnio: Sebastiano
AsYlum
  • Rejestracja:prawie 19 lat
  • Ostatnio:30 dni
  • Postów:29
1

No to prawidłowo podejrzewałem :) A co masz w widoku? Nie jest czasem tak, że masz strongly typed view i tam na górze deklarację modelu z jakiego ma korzystać? Z wyjątku wychodzi, że podajesz do widoku model typu RetrievalModel, a widok spodziewa się RegisterModel .


<uninitialized object="object">
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

Dokładnie tak to wygląda:) tylko że w kontrolerze zwracam "RetrievalModel" i w widoku mam "RetrievalModel" bo trzeba się jakoś dostać do "m.eMail" i wyrzuca błąd że potrzebuje "RegisterModel". Jak dam "RegisterModel" to krzyczy o "LoginModel" i tak w kółko...:)
w efekcie nie wiem czym to jest spowodowane.

edytowany 2x, ostatnio: Sebastiano
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
1

Ok. działa:) Cały problem leżał w tym że do złego modelu sie odwoływałem. Ma być w kontrolerze na końcu:

Kopiuj
return View();

bez zwracania modelu. Całość ładnie działa i mail się wysyła na chwile obecna do katalogu lokalnego.

Mam teraz pytanie. Jak poprawnie należy skonfigurować web.config w momencie wdrożenia na serwer(aby mail wysyłał sie faktycznie na poczte)?

Obecnie jest tak:

Kopiuj
<system.net>
    <mailSettings>
      <smtp deliveryMethod = "SpecifiedPickupDirectory" >
        <specifiedPickupDirectory  pickupDirectoryLocation = "P:\Moje\AppPanel\kod\email" />
      </smtp>
    </mailSettings>
  </system.net>
AsYlum
  • Rejestracja:prawie 19 lat
  • Ostatnio:30 dni
  • Postów:29
1

Powinno to wyglądać mniej więcej tak:

Kopiuj
<system.net>
    <mailSettings>
      <smtp deliveryMethod="network" deliveryFormat="International" from="from_addres@example.com">
		<network defaultCredentials="false" host="mailserver.example.com" enableSsl="true" port="587" userName="myUser" password="myPassword" />        
      </smtp>
    </mailSettings>
  </system.net>

Oczywiście musisz sobie dostosować ssl, port itd. do wymagań serwera.

Pomocne linki:

defaultCredentials: http://msdn.microsoft.com/en-us/library/system.net.credentialcache.defaultnetworkcredentials.aspx
deliveryFormat, deliveryMethod: http://msdn.microsoft.com/en-us/library/ms164240%28v=vs.110%29.aspx


<uninitialized object="object">
Sebastiano
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 4 lata
  • Postów:488
0

O to mi właśnie chodziło. Dziękuje za pomoc;)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.