Email Features #5
14
QtCNETAPI/Dtos/User/UserPasswordResetDto.cs
Normal file
14
QtCNETAPI/Dtos/User/UserPasswordResetDto.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Dtos.User
|
||||||
|
{
|
||||||
|
public class UserPasswordResetDto
|
||||||
|
{
|
||||||
|
public string Token { get; set; } = string.Empty;
|
||||||
|
public string Password { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
@ -280,6 +280,72 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
return serviceResponse;
|
return serviceResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<bool>> ResendVerificationEmail(string email)
|
||||||
|
{
|
||||||
|
var serviceResponse = new ServiceResponse<bool>();
|
||||||
|
|
||||||
|
var restRequest = new RestRequest($"auth/resend-verification-email")
|
||||||
|
.AddQueryParameter("email", email);
|
||||||
|
var response = await _client.PostAsync<ServiceResponse<bool>>(restRequest);
|
||||||
|
|
||||||
|
if (response != null)
|
||||||
|
{
|
||||||
|
serviceResponse.Success = true;
|
||||||
|
serviceResponse.Data = response.Data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serviceResponse.Success = false;
|
||||||
|
serviceResponse.Message = "API never responded.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<bool>> SendPasswordResetEmail(string email)
|
||||||
|
{
|
||||||
|
var serviceResponse = new ServiceResponse<bool>();
|
||||||
|
|
||||||
|
var restRequest = new RestRequest($"auth/request-password-reset")
|
||||||
|
.AddQueryParameter("email", email);
|
||||||
|
var response = await _client.PostAsync<ServiceResponse<bool>>(restRequest);
|
||||||
|
|
||||||
|
if (response != null)
|
||||||
|
{
|
||||||
|
serviceResponse.Success = true;
|
||||||
|
serviceResponse.Data = response.Data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serviceResponse.Success = false;
|
||||||
|
serviceResponse.Message = "API never responded.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<bool>> ResetPassword(UserPasswordResetDto request)
|
||||||
|
{
|
||||||
|
var serviceResponse = new ServiceResponse<bool>();
|
||||||
|
|
||||||
|
var restRequest = new RestRequest($"auth/reset-password")
|
||||||
|
.AddJsonBody(request);
|
||||||
|
var response = await _client.PostAsync<ServiceResponse<bool>>(restRequest);
|
||||||
|
|
||||||
|
if (response != null)
|
||||||
|
{
|
||||||
|
serviceResponse.Success = true;
|
||||||
|
serviceResponse.Data = response.Data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serviceResponse.Success = false;
|
||||||
|
serviceResponse.Message = "API never responded.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<User> SetCurrentUser()
|
public async Task<User> SetCurrentUser()
|
||||||
{
|
{
|
||||||
var userRequest = new RestRequest("users/user-authorized")
|
var userRequest = new RestRequest("users/user-authorized")
|
||||||
|
@ -24,6 +24,9 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
public Task<ServiceResponse<List<UserInformationDto>>> GetAllUsersAsync();
|
public Task<ServiceResponse<List<UserInformationDto>>> GetAllUsersAsync();
|
||||||
public Task<ServiceResponse<User>> DeleteUserById(string id);
|
public Task<ServiceResponse<User>> DeleteUserById(string id);
|
||||||
public Task<ServiceResponse<User>> LoginAsync(UserLoginDto userLoginDto);
|
public Task<ServiceResponse<User>> LoginAsync(UserLoginDto userLoginDto);
|
||||||
|
public Task<ServiceResponse<bool>> ResendVerificationEmail(string email);
|
||||||
|
public Task<ServiceResponse<bool>> SendPasswordResetEmail(string email);
|
||||||
|
public Task<ServiceResponse<bool>> ResetPassword(UserPasswordResetDto request);
|
||||||
public Task<ServiceResponse<User>> RefreshLogin(string refreshToken);
|
public Task<ServiceResponse<User>> RefreshLogin(string refreshToken);
|
||||||
public Task<ServiceResponse<string>> RefreshSessionIfInvalid();
|
public Task<ServiceResponse<string>> RefreshSessionIfInvalid();
|
||||||
public Task<User> SetCurrentUser();
|
public Task<User> SetCurrentUser();
|
||||||
|
64
qtc-net-client-2/Forms/Login.Designer.cs
generated
64
qtc-net-client-2/Forms/Login.Designer.cs
generated
@ -1,6 +1,6 @@
|
|||||||
namespace qtc_net_client_2.Forms
|
namespace qtc_net_client_2.Forms
|
||||||
{
|
{
|
||||||
partial class Login
|
partial class llblForgotPassword
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required designer variable.
|
/// Required designer variable.
|
||||||
@ -28,15 +28,17 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Login));
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(llblForgotPassword));
|
||||||
pbLoginBanner = new PictureBox();
|
pbLoginBanner = new PictureBox();
|
||||||
tbEmail = new TextBox();
|
tbEmail = new TextBox();
|
||||||
lblEmail = new Label();
|
lblEmail = new Label();
|
||||||
label1 = new Label();
|
lblPassword = new Label();
|
||||||
tbPassword = new TextBox();
|
tbPassword = new TextBox();
|
||||||
btnLogin = new Button();
|
btnLogin = new Button();
|
||||||
llblRegister = new LinkLabel();
|
llblRegister = new LinkLabel();
|
||||||
cbRememberMe = new CheckBox();
|
cbRememberMe = new CheckBox();
|
||||||
|
llblResendEmail = new LinkLabel();
|
||||||
|
llblForgotPasswor = new LinkLabel();
|
||||||
((System.ComponentModel.ISupportInitialize)pbLoginBanner).BeginInit();
|
((System.ComponentModel.ISupportInitialize)pbLoginBanner).BeginInit();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
@ -68,16 +70,16 @@
|
|||||||
lblEmail.TabIndex = 2;
|
lblEmail.TabIndex = 2;
|
||||||
lblEmail.Text = "Email";
|
lblEmail.Text = "Email";
|
||||||
//
|
//
|
||||||
// label1
|
// lblPassword
|
||||||
//
|
//
|
||||||
label1.AutoSize = true;
|
lblPassword.AutoSize = true;
|
||||||
label1.Font = new Font("Segoe UI Light", 9F);
|
lblPassword.Font = new Font("Segoe UI Light", 9F);
|
||||||
label1.ForeColor = SystemColors.ControlLight;
|
lblPassword.ForeColor = SystemColors.ControlLight;
|
||||||
label1.Location = new Point(11, 138);
|
lblPassword.Location = new Point(11, 138);
|
||||||
label1.Name = "label1";
|
lblPassword.Name = "lblPassword";
|
||||||
label1.Size = new Size(55, 15);
|
lblPassword.Size = new Size(55, 15);
|
||||||
label1.TabIndex = 4;
|
lblPassword.TabIndex = 4;
|
||||||
label1.Text = "Password";
|
lblPassword.Text = "Password";
|
||||||
//
|
//
|
||||||
// tbPassword
|
// tbPassword
|
||||||
//
|
//
|
||||||
@ -122,16 +124,44 @@
|
|||||||
cbRememberMe.Text = "Remember Me For 7 Days";
|
cbRememberMe.Text = "Remember Me For 7 Days";
|
||||||
cbRememberMe.UseVisualStyleBackColor = true;
|
cbRememberMe.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// frmLogin
|
// llblResendEmail
|
||||||
|
//
|
||||||
|
llblResendEmail.AutoSize = true;
|
||||||
|
llblResendEmail.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
llblResendEmail.LinkColor = SystemColors.ControlLight;
|
||||||
|
llblResendEmail.Location = new Point(369, 164);
|
||||||
|
llblResendEmail.Name = "llblResendEmail";
|
||||||
|
llblResendEmail.Size = new Size(129, 15);
|
||||||
|
llblResendEmail.TabIndex = 8;
|
||||||
|
llblResendEmail.TabStop = true;
|
||||||
|
llblResendEmail.Text = "Resend Verification Email";
|
||||||
|
llblResendEmail.LinkClicked += llblResendEmail_LinkClicked;
|
||||||
|
//
|
||||||
|
// llblForgotPasswor
|
||||||
|
//
|
||||||
|
llblForgotPasswor.AutoSize = true;
|
||||||
|
llblForgotPasswor.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
llblForgotPasswor.LinkColor = SystemColors.ControlLight;
|
||||||
|
llblForgotPasswor.Location = new Point(401, 181);
|
||||||
|
llblForgotPasswor.Name = "llblForgotPasswor";
|
||||||
|
llblForgotPasswor.Size = new Size(98, 15);
|
||||||
|
llblForgotPasswor.TabIndex = 9;
|
||||||
|
llblForgotPasswor.TabStop = true;
|
||||||
|
llblForgotPasswor.Text = "Forgot Password?";
|
||||||
|
llblForgotPasswor.LinkClicked += llblForgotPasswor_LinkClicked;
|
||||||
|
//
|
||||||
|
// llblForgotPassword
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
AutoScaleMode = AutoScaleMode.Font;
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
BackColor = Color.DodgerBlue;
|
BackColor = Color.DodgerBlue;
|
||||||
ClientSize = new Size(515, 203);
|
ClientSize = new Size(515, 203);
|
||||||
|
Controls.Add(llblForgotPasswor);
|
||||||
|
Controls.Add(llblResendEmail);
|
||||||
Controls.Add(cbRememberMe);
|
Controls.Add(cbRememberMe);
|
||||||
Controls.Add(llblRegister);
|
Controls.Add(llblRegister);
|
||||||
Controls.Add(btnLogin);
|
Controls.Add(btnLogin);
|
||||||
Controls.Add(label1);
|
Controls.Add(lblPassword);
|
||||||
Controls.Add(tbPassword);
|
Controls.Add(tbPassword);
|
||||||
Controls.Add(lblEmail);
|
Controls.Add(lblEmail);
|
||||||
Controls.Add(tbEmail);
|
Controls.Add(tbEmail);
|
||||||
@ -139,7 +169,7 @@
|
|||||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||||
MaximizeBox = false;
|
MaximizeBox = false;
|
||||||
Name = "frmLogin";
|
Name = "llblForgotPassword";
|
||||||
StartPosition = FormStartPosition.CenterParent;
|
StartPosition = FormStartPosition.CenterParent;
|
||||||
Text = "QtC.NET Client - Login";
|
Text = "QtC.NET Client - Login";
|
||||||
Load += frmLogin_Load;
|
Load += frmLogin_Load;
|
||||||
@ -153,10 +183,12 @@
|
|||||||
private PictureBox pbLoginBanner;
|
private PictureBox pbLoginBanner;
|
||||||
private TextBox tbEmail;
|
private TextBox tbEmail;
|
||||||
private Label lblEmail;
|
private Label lblEmail;
|
||||||
private Label label1;
|
private Label lblPassword;
|
||||||
private TextBox tbPassword;
|
private TextBox tbPassword;
|
||||||
private Button btnLogin;
|
private Button btnLogin;
|
||||||
private LinkLabel llblRegister;
|
private LinkLabel llblRegister;
|
||||||
private CheckBox cbRememberMe;
|
private CheckBox cbRememberMe;
|
||||||
|
private LinkLabel llblResendEmail;
|
||||||
|
private LinkLabel llblForgotPasswor;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,10 +12,10 @@ using System.Windows.Forms;
|
|||||||
|
|
||||||
namespace qtc_net_client_2.Forms
|
namespace qtc_net_client_2.Forms
|
||||||
{
|
{
|
||||||
public partial class Login : Form
|
public partial class llblForgotPassword : Form
|
||||||
{
|
{
|
||||||
private IApiService _apiService;
|
private IApiService _apiService;
|
||||||
public Login(IApiService apiService)
|
public llblForgotPassword(IApiService apiService)
|
||||||
{
|
{
|
||||||
_apiService = apiService;
|
_apiService = apiService;
|
||||||
|
|
||||||
@ -68,6 +68,24 @@ namespace qtc_net_client_2.Forms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void llblRegister_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
|
{
|
||||||
|
Register frmRegister = new Register(_apiService);
|
||||||
|
frmRegister.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void llblResendEmail_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
|
{
|
||||||
|
ResendVerificationEmail resendVerificationEmail = new ResendVerificationEmail(_apiService);
|
||||||
|
resendVerificationEmail.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void llblForgotPasswor_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
|
{
|
||||||
|
ResetPassword resetPassword = new ResetPassword(_apiService);
|
||||||
|
resetPassword.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
private void ToggleControls(bool enable, bool clearText)
|
private void ToggleControls(bool enable, bool clearText)
|
||||||
{
|
{
|
||||||
tbEmail.Enabled = enable;
|
tbEmail.Enabled = enable;
|
||||||
@ -81,11 +99,5 @@ namespace qtc_net_client_2.Forms
|
|||||||
tbPassword.Text = string.Empty;
|
tbPassword.Text = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void llblRegister_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
|
||||||
{
|
|
||||||
Register frmRegister = new Register(_apiService);
|
|
||||||
frmRegister.ShowDialog();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ namespace qtc_net_client_2
|
|||||||
if (_apiService.CurrentUser == null)
|
if (_apiService.CurrentUser == null)
|
||||||
{
|
{
|
||||||
// not logged in, load the login form
|
// not logged in, load the login form
|
||||||
Login frmLogin = new Login(_apiService);
|
llblForgotPassword frmLogin = new llblForgotPassword(_apiService);
|
||||||
var result = frmLogin.ShowDialog();
|
var result = frmLogin.ShowDialog();
|
||||||
|
|
||||||
if (result == DialogResult.OK)
|
if (result == DialogResult.OK)
|
||||||
@ -60,7 +60,7 @@ namespace qtc_net_client_2
|
|||||||
private async void llblSignIn_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
private async void llblSignIn_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
{
|
{
|
||||||
// just reshow the login dialog lol
|
// just reshow the login dialog lol
|
||||||
Login frmLogin = new Login(_apiService);
|
llblForgotPassword frmLogin = new llblForgotPassword(_apiService);
|
||||||
var result = frmLogin.ShowDialog();
|
var result = frmLogin.ShowDialog();
|
||||||
|
|
||||||
if (result == DialogResult.OK)
|
if (result == DialogResult.OK)
|
||||||
|
104
qtc-net-client-2/Forms/ResendVerificationEmail.Designer.cs
generated
Normal file
104
qtc-net-client-2/Forms/ResendVerificationEmail.Designer.cs
generated
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
partial class ResendVerificationEmail
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
pbLoginBanner = new PictureBox();
|
||||||
|
tbEmail = new TextBox();
|
||||||
|
lblHeader = new Label();
|
||||||
|
btnSend = new Button();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbLoginBanner).BeginInit();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// pbLoginBanner
|
||||||
|
//
|
||||||
|
pbLoginBanner.Image = Properties.Resources.LoginBanner;
|
||||||
|
pbLoginBanner.Location = new Point(-4, 0);
|
||||||
|
pbLoginBanner.Name = "pbLoginBanner";
|
||||||
|
pbLoginBanner.Size = new Size(521, 99);
|
||||||
|
pbLoginBanner.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
pbLoginBanner.TabIndex = 1;
|
||||||
|
pbLoginBanner.TabStop = false;
|
||||||
|
//
|
||||||
|
// tbEmail
|
||||||
|
//
|
||||||
|
tbEmail.Location = new Point(50, 124);
|
||||||
|
tbEmail.Name = "tbEmail";
|
||||||
|
tbEmail.Size = new Size(424, 23);
|
||||||
|
tbEmail.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// lblHeader
|
||||||
|
//
|
||||||
|
lblHeader.AutoSize = true;
|
||||||
|
lblHeader.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblHeader.ForeColor = SystemColors.ControlLight;
|
||||||
|
lblHeader.Location = new Point(54, 106);
|
||||||
|
lblHeader.Name = "lblHeader";
|
||||||
|
lblHeader.Size = new Size(412, 15);
|
||||||
|
lblHeader.TabIndex = 5;
|
||||||
|
lblHeader.Text = "Please Enter Your Email, If An Account Exists With This Email, We'll Send You A Link";
|
||||||
|
//
|
||||||
|
// btnSend
|
||||||
|
//
|
||||||
|
btnSend.Location = new Point(224, 153);
|
||||||
|
btnSend.Name = "btnSend";
|
||||||
|
btnSend.Size = new Size(75, 23);
|
||||||
|
btnSend.TabIndex = 6;
|
||||||
|
btnSend.Text = "Send";
|
||||||
|
btnSend.UseVisualStyleBackColor = true;
|
||||||
|
btnSend.Click += btnSend_Click;
|
||||||
|
//
|
||||||
|
// ResendVerificationEmail
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
BackColor = Color.DodgerBlue;
|
||||||
|
ClientSize = new Size(515, 187);
|
||||||
|
Controls.Add(btnSend);
|
||||||
|
Controls.Add(lblHeader);
|
||||||
|
Controls.Add(tbEmail);
|
||||||
|
Controls.Add(pbLoginBanner);
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
Name = "ResendVerificationEmail";
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
Text = "QtC.NET Client - Resend Verification Email";
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbLoginBanner).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private PictureBox pbLoginBanner;
|
||||||
|
private TextBox tbEmail;
|
||||||
|
private Label lblHeader;
|
||||||
|
private Button btnSend;
|
||||||
|
}
|
||||||
|
}
|
43
qtc-net-client-2/Forms/ResendVerificationEmail.cs
Normal file
43
qtc-net-client-2/Forms/ResendVerificationEmail.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using QtCNETAPI.Services.ApiService;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
public partial class ResendVerificationEmail : Form
|
||||||
|
{
|
||||||
|
private IApiService _apiService;
|
||||||
|
public ResendVerificationEmail(IApiService apiService)
|
||||||
|
{
|
||||||
|
_apiService = apiService;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnSend_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(!string.IsNullOrEmpty(tbEmail.Text))
|
||||||
|
{
|
||||||
|
tbEmail.Enabled = false;
|
||||||
|
btnSend.Enabled = false;
|
||||||
|
|
||||||
|
var result = await _apiService.ResendVerificationEmail(tbEmail.Text);
|
||||||
|
if(result != null && result.Success && result.Data)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Got It! You should receive an email shortly.\nIf you do not receive an email, check your spam.", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
Close();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Sorry, This Server Doesn't Have Email Features Enabled Or Something Went Wrong.\nIf you cannot login, you may need to contact the server admin.", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
qtc-net-client-2/Forms/ResendVerificationEmail.resx
Normal file
120
qtc-net-client-2/Forms/ResendVerificationEmail.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
221
qtc-net-client-2/Forms/ResetPassword.Designer.cs
generated
Normal file
221
qtc-net-client-2/Forms/ResetPassword.Designer.cs
generated
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
partial class ResetPassword
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
pEmailBox = new Panel();
|
||||||
|
btnSend = new Button();
|
||||||
|
lblHeader = new Label();
|
||||||
|
tbEmail = new TextBox();
|
||||||
|
pResetPasswordBox = new Panel();
|
||||||
|
btnResetPassword = new Button();
|
||||||
|
tbConfirmPassword = new TextBox();
|
||||||
|
lblConfirmPassword = new Label();
|
||||||
|
tbNewPassword = new TextBox();
|
||||||
|
lblNewPassword = new Label();
|
||||||
|
tbToken = new TextBox();
|
||||||
|
lblToken = new Label();
|
||||||
|
pbLoginBanner = new PictureBox();
|
||||||
|
pEmailBox.SuspendLayout();
|
||||||
|
pResetPasswordBox.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbLoginBanner).BeginInit();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// pEmailBox
|
||||||
|
//
|
||||||
|
pEmailBox.Anchor = AnchorStyles.Bottom;
|
||||||
|
pEmailBox.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
pEmailBox.Controls.Add(btnSend);
|
||||||
|
pEmailBox.Controls.Add(lblHeader);
|
||||||
|
pEmailBox.Controls.Add(tbEmail);
|
||||||
|
pEmailBox.Location = new Point(101, 125);
|
||||||
|
pEmailBox.Name = "pEmailBox";
|
||||||
|
pEmailBox.Size = new Size(458, 94);
|
||||||
|
pEmailBox.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// btnSend
|
||||||
|
//
|
||||||
|
btnSend.Location = new Point(193, 59);
|
||||||
|
btnSend.Name = "btnSend";
|
||||||
|
btnSend.Size = new Size(75, 23);
|
||||||
|
btnSend.TabIndex = 9;
|
||||||
|
btnSend.Text = "Send";
|
||||||
|
btnSend.UseVisualStyleBackColor = true;
|
||||||
|
btnSend.Click += btnSend_Click;
|
||||||
|
//
|
||||||
|
// lblHeader
|
||||||
|
//
|
||||||
|
lblHeader.AutoSize = true;
|
||||||
|
lblHeader.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblHeader.ForeColor = SystemColors.ControlLight;
|
||||||
|
lblHeader.Location = new Point(23, 12);
|
||||||
|
lblHeader.Name = "lblHeader";
|
||||||
|
lblHeader.Size = new Size(412, 15);
|
||||||
|
lblHeader.TabIndex = 8;
|
||||||
|
lblHeader.Text = "Please Enter Your Email, If An Account Exists With This Email, We'll Send You A Link";
|
||||||
|
//
|
||||||
|
// tbEmail
|
||||||
|
//
|
||||||
|
tbEmail.Location = new Point(19, 30);
|
||||||
|
tbEmail.Name = "tbEmail";
|
||||||
|
tbEmail.Size = new Size(424, 23);
|
||||||
|
tbEmail.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// pResetPasswordBox
|
||||||
|
//
|
||||||
|
pResetPasswordBox.Anchor = AnchorStyles.Bottom;
|
||||||
|
pResetPasswordBox.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
pResetPasswordBox.Controls.Add(btnResetPassword);
|
||||||
|
pResetPasswordBox.Controls.Add(tbConfirmPassword);
|
||||||
|
pResetPasswordBox.Controls.Add(lblConfirmPassword);
|
||||||
|
pResetPasswordBox.Controls.Add(tbNewPassword);
|
||||||
|
pResetPasswordBox.Controls.Add(lblNewPassword);
|
||||||
|
pResetPasswordBox.Controls.Add(tbToken);
|
||||||
|
pResetPasswordBox.Controls.Add(lblToken);
|
||||||
|
pResetPasswordBox.Location = new Point(17, 106);
|
||||||
|
pResetPasswordBox.Name = "pResetPasswordBox";
|
||||||
|
pResetPasswordBox.Size = new Size(596, 138);
|
||||||
|
pResetPasswordBox.TabIndex = 1;
|
||||||
|
pResetPasswordBox.Visible = false;
|
||||||
|
//
|
||||||
|
// btnResetPassword
|
||||||
|
//
|
||||||
|
btnResetPassword.Location = new Point(270, 102);
|
||||||
|
btnResetPassword.Name = "btnResetPassword";
|
||||||
|
btnResetPassword.Size = new Size(100, 23);
|
||||||
|
btnResetPassword.TabIndex = 15;
|
||||||
|
btnResetPassword.Text = "Reset Password";
|
||||||
|
btnResetPassword.UseVisualStyleBackColor = true;
|
||||||
|
btnResetPassword.Click += btnResetPassword_Click;
|
||||||
|
//
|
||||||
|
// tbConfirmPassword
|
||||||
|
//
|
||||||
|
tbConfirmPassword.Location = new Point(123, 73);
|
||||||
|
tbConfirmPassword.Name = "tbConfirmPassword";
|
||||||
|
tbConfirmPassword.PasswordChar = '*';
|
||||||
|
tbConfirmPassword.Size = new Size(424, 23);
|
||||||
|
tbConfirmPassword.TabIndex = 14;
|
||||||
|
//
|
||||||
|
// lblConfirmPassword
|
||||||
|
//
|
||||||
|
lblConfirmPassword.AutoSize = true;
|
||||||
|
lblConfirmPassword.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblConfirmPassword.ForeColor = SystemColors.ControlLight;
|
||||||
|
lblConfirmPassword.Location = new Point(20, 76);
|
||||||
|
lblConfirmPassword.Name = "lblConfirmPassword";
|
||||||
|
lblConfirmPassword.Size = new Size(97, 15);
|
||||||
|
lblConfirmPassword.TabIndex = 13;
|
||||||
|
lblConfirmPassword.Text = "Confirm Password";
|
||||||
|
//
|
||||||
|
// tbNewPassword
|
||||||
|
//
|
||||||
|
tbNewPassword.Location = new Point(123, 44);
|
||||||
|
tbNewPassword.Name = "tbNewPassword";
|
||||||
|
tbNewPassword.PasswordChar = '*';
|
||||||
|
tbNewPassword.Size = new Size(424, 23);
|
||||||
|
tbNewPassword.TabIndex = 12;
|
||||||
|
//
|
||||||
|
// lblNewPassword
|
||||||
|
//
|
||||||
|
lblNewPassword.AutoSize = true;
|
||||||
|
lblNewPassword.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblNewPassword.ForeColor = SystemColors.ControlLight;
|
||||||
|
lblNewPassword.Location = new Point(36, 47);
|
||||||
|
lblNewPassword.Name = "lblNewPassword";
|
||||||
|
lblNewPassword.Size = new Size(81, 15);
|
||||||
|
lblNewPassword.TabIndex = 11;
|
||||||
|
lblNewPassword.Text = "New Password";
|
||||||
|
//
|
||||||
|
// tbToken
|
||||||
|
//
|
||||||
|
tbToken.Location = new Point(123, 15);
|
||||||
|
tbToken.Name = "tbToken";
|
||||||
|
tbToken.Size = new Size(424, 23);
|
||||||
|
tbToken.TabIndex = 10;
|
||||||
|
//
|
||||||
|
// lblToken
|
||||||
|
//
|
||||||
|
lblToken.AutoSize = true;
|
||||||
|
lblToken.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblToken.ForeColor = SystemColors.ControlLight;
|
||||||
|
lblToken.Location = new Point(82, 18);
|
||||||
|
lblToken.Name = "lblToken";
|
||||||
|
lblToken.Size = new Size(35, 15);
|
||||||
|
lblToken.TabIndex = 9;
|
||||||
|
lblToken.Text = "Token";
|
||||||
|
//
|
||||||
|
// pbLoginBanner
|
||||||
|
//
|
||||||
|
pbLoginBanner.Image = Properties.Resources.LoginBanner;
|
||||||
|
pbLoginBanner.Location = new Point(-3, -1);
|
||||||
|
pbLoginBanner.Name = "pbLoginBanner";
|
||||||
|
pbLoginBanner.Size = new Size(521, 99);
|
||||||
|
pbLoginBanner.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
pbLoginBanner.TabIndex = 2;
|
||||||
|
pbLoginBanner.TabStop = false;
|
||||||
|
//
|
||||||
|
// ResetPassword
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
BackColor = Color.DodgerBlue;
|
||||||
|
ClientSize = new Size(622, 256);
|
||||||
|
Controls.Add(pEmailBox);
|
||||||
|
Controls.Add(pResetPasswordBox);
|
||||||
|
Controls.Add(pbLoginBanner);
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
Name = "ResetPassword";
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
Text = "QtC.NET Client - Reset Password";
|
||||||
|
pEmailBox.ResumeLayout(false);
|
||||||
|
pEmailBox.PerformLayout();
|
||||||
|
pResetPasswordBox.ResumeLayout(false);
|
||||||
|
pResetPasswordBox.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbLoginBanner).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Panel pEmailBox;
|
||||||
|
private Button btnSend;
|
||||||
|
private Label lblHeader;
|
||||||
|
private TextBox tbEmail;
|
||||||
|
private Panel pResetPasswordBox;
|
||||||
|
private TextBox tbConfirmPassword;
|
||||||
|
private Label lblConfirmPassword;
|
||||||
|
private TextBox tbNewPassword;
|
||||||
|
private Label lblNewPassword;
|
||||||
|
private TextBox tbToken;
|
||||||
|
private Label lblToken;
|
||||||
|
private Button btnResetPassword;
|
||||||
|
private PictureBox pbLoginBanner;
|
||||||
|
}
|
||||||
|
}
|
68
qtc-net-client-2/Forms/ResetPassword.cs
Normal file
68
qtc-net-client-2/Forms/ResetPassword.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using QtCNETAPI.Services.ApiService;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
public partial class ResetPassword : Form
|
||||||
|
{
|
||||||
|
private IApiService _apiService;
|
||||||
|
public ResetPassword(IApiService apiService)
|
||||||
|
{
|
||||||
|
_apiService = apiService;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnSend_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(tbEmail.Text))
|
||||||
|
{
|
||||||
|
tbEmail.Enabled = false;
|
||||||
|
btnSend.Enabled = false;
|
||||||
|
|
||||||
|
var result = await _apiService.SendPasswordResetEmail(tbEmail.Text);
|
||||||
|
if (result != null && result.Success && result.Data)
|
||||||
|
{
|
||||||
|
pEmailBox.Visible = false;
|
||||||
|
pResetPasswordBox.Visible = true;
|
||||||
|
|
||||||
|
MessageBox.Show("Got It! You should receive an email shortly.\nIf you do not receive an email, check your spam.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Sorry, This Server Doesn't Have Email Features Enabled Or Something Went Wrong.\nIf you cannot login, you may need to contact the server admin.", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnResetPassword_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(!string.IsNullOrEmpty(tbToken.Text) && !string.IsNullOrEmpty(tbNewPassword.Text) && !string.IsNullOrEmpty(tbConfirmPassword.Text))
|
||||||
|
{
|
||||||
|
tbToken.Enabled = false;
|
||||||
|
tbNewPassword.Enabled = false;
|
||||||
|
tbConfirmPassword.Enabled = false;
|
||||||
|
btnResetPassword.Enabled = false;
|
||||||
|
|
||||||
|
var result = await _apiService.ResetPassword(new QtCNETAPI.Dtos.User.UserPasswordResetDto { Token = tbToken.Text, Password = tbNewPassword.Text });
|
||||||
|
if(result != null && result.Success && result.Data)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Your Password Has Been Reset. You may now login with the new password.", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
Close();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
MessageBox.Show(result?.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
qtc-net-client-2/Forms/ResetPassword.resx
Normal file
120
qtc-net-client-2/Forms/ResetPassword.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
Loading…
x
Reference in New Issue
Block a user