Added example.
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using System.Web.Configuration;
|
||||
using OnlineEditorsExampleMVC.Models;
|
||||
|
||||
namespace OnlineEditorsExampleMVC.Helpers
|
||||
{
|
||||
public class DocManagerHelper
|
||||
{
|
||||
public static long MaxFileSize
|
||||
{
|
||||
get
|
||||
{
|
||||
long size;
|
||||
long.TryParse(WebConfigurationManager.AppSettings["filesize-max"], out size);
|
||||
return size > 0 ? size : 5 * 1024 * 1024;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<string> FileExts
|
||||
{
|
||||
get { return ViewedExts.Concat(EditedExts).Concat(ConvertExts).ToList(); }
|
||||
}
|
||||
|
||||
public static List<string> ViewedExts
|
||||
{
|
||||
get { return (WebConfigurationManager.AppSettings["files.docservice.viewed-docs"] ?? "").Split(new char[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); }
|
||||
}
|
||||
|
||||
public static List<string> EditedExts
|
||||
{
|
||||
get { return (WebConfigurationManager.AppSettings["files.docservice.edited-docs"] ?? "").Split(new char[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); }
|
||||
}
|
||||
|
||||
public static List<string> ConvertExts
|
||||
{
|
||||
get { return (WebConfigurationManager.AppSettings["files.docservice.convert-docs"] ?? "").Split(new char[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); }
|
||||
}
|
||||
|
||||
public static string CurUserHostAddress(string userAddress = null)
|
||||
{
|
||||
return Regex.Replace(userAddress ?? HttpContext.Current.Request.UserHostAddress, "[^0-9a-zA-Z.=]", "_");
|
||||
}
|
||||
|
||||
public static string StoragePath(string fileName, string userAddress = null)
|
||||
{
|
||||
var directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
return directory + fileName;
|
||||
}
|
||||
|
||||
public static string GetCorrectName(string fileName)
|
||||
{
|
||||
var baseName = Path.GetFileNameWithoutExtension(fileName);
|
||||
var ext = Path.GetExtension(fileName);
|
||||
var name = baseName + ext;
|
||||
|
||||
for (var i = 1; File.Exists(StoragePath(name)); i++)
|
||||
{
|
||||
name = baseName + " (" + i + ")" + ext;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static string CreateDemo(string fileExt)
|
||||
{
|
||||
var demoName = "sample." + fileExt;
|
||||
|
||||
var fileName = GetCorrectName(demoName);
|
||||
|
||||
File.Copy(HttpRuntime.AppDomainAppPath + "app_data\\" + demoName, StoragePath(fileName));
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public static string GetFileUri(string fileName)
|
||||
{
|
||||
var uri = new UriBuilder(HttpContext.Current.Request.Url)
|
||||
{
|
||||
Path = HttpRuntime.AppDomainAppVirtualPath + "/App_Data/"
|
||||
+ CurUserHostAddress() + "/"
|
||||
+ fileName,
|
||||
Query = ""
|
||||
};
|
||||
|
||||
if (HaveExternalIP())
|
||||
{
|
||||
return uri.ToString();
|
||||
}
|
||||
|
||||
return GetExternalUri(uri.ToString());
|
||||
}
|
||||
|
||||
public static string GetCallback(string fileName)
|
||||
{
|
||||
var callbackUrl = new UriBuilder(HttpContext.Current.Request.Url)
|
||||
{
|
||||
Path =
|
||||
HttpRuntime.AppDomainAppVirtualPath
|
||||
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
|
||||
+ "webeditor.ashx",
|
||||
Query = "type=track"
|
||||
+ "&userAddress=" + HttpUtility.UrlEncode(HttpContext.Current.Request.UserHostAddress)
|
||||
+ "&fileName=" + HttpUtility.UrlEncode(fileName)
|
||||
};
|
||||
return callbackUrl.ToString();
|
||||
}
|
||||
|
||||
private static bool? _haveExternalIP;
|
||||
|
||||
public static bool HaveExternalIP()
|
||||
{
|
||||
if (!_haveExternalIP.HasValue)
|
||||
{
|
||||
string convertUri;
|
||||
try
|
||||
{
|
||||
var uri = new UriBuilder(HttpContext.Current.Request.Url)
|
||||
{
|
||||
Path = HttpRuntime.AppDomainAppVirtualPath + "/App_Data/demo.docx",
|
||||
Query = ""
|
||||
};
|
||||
var fileUri = uri.ToString();
|
||||
|
||||
ServiceConverter.GetConvertedUri(fileUri, "docx", "docx", Guid.NewGuid().ToString(), false, out convertUri);
|
||||
}
|
||||
catch
|
||||
{
|
||||
convertUri = string.Empty;
|
||||
}
|
||||
|
||||
_haveExternalIP = !string.IsNullOrEmpty(convertUri);
|
||||
}
|
||||
|
||||
return _haveExternalIP.Value;
|
||||
}
|
||||
|
||||
public static string GetExternalUri(string localUri)
|
||||
{
|
||||
try
|
||||
{
|
||||
var uri = HttpRuntime.Cache.Get(localUri) as string;
|
||||
if (string.IsNullOrEmpty(uri))
|
||||
{
|
||||
|
||||
var webRequest = WebRequest.Create(localUri);
|
||||
using (var response = webRequest.GetResponse())
|
||||
using (var responseStream = response.GetResponseStream())
|
||||
{
|
||||
var key = ServiceConverter.GenerateRevisionId(localUri);
|
||||
uri = ServiceConverter.GetExternalUri(responseStream, response.ContentLength, response.ContentType, key);
|
||||
}
|
||||
HttpRuntime.Cache.Insert(localUri, uri, null, DateTime.Now.Add(TimeSpan.FromMinutes(2)), Cache.NoSlidingExpiration);
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
return localUri;
|
||||
}
|
||||
|
||||
public static string GetInternalExtension(FileUtility.FileType fileType)
|
||||
{
|
||||
switch (fileType)
|
||||
{
|
||||
case FileUtility.FileType.Text:
|
||||
return ".docx";
|
||||
case FileUtility.FileType.Spreadsheet:
|
||||
return ".xlsx";
|
||||
case FileUtility.FileType.Presentation:
|
||||
return ".pptx";
|
||||
default:
|
||||
return ".docx";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace OnlineEditorsExampleMVC.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class service api conversion
|
||||
/// </summary>
|
||||
public static class ServiceConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Static constructor
|
||||
/// </summary>
|
||||
static ServiceConverter()
|
||||
{
|
||||
DocumentConverterUrl = WebConfigurationManager.AppSettings["files.docservice.url.converter"] ?? "";
|
||||
DocumentStorageUrl = WebConfigurationManager.AppSettings["files.docservice.url.storage"] ?? "";
|
||||
|
||||
Int32.TryParse(WebConfigurationManager.AppSettings["files.docservice.timeout"], out ConvertTimeout);
|
||||
ConvertTimeout = ConvertTimeout > 0 ? ConvertTimeout : 120000;
|
||||
}
|
||||
|
||||
#region private fields
|
||||
|
||||
/// <summary>
|
||||
/// Timeout to request conversion
|
||||
/// </summary>
|
||||
private static readonly int ConvertTimeout;
|
||||
|
||||
/// <summary>
|
||||
/// Url to the service of conversion
|
||||
/// </summary>
|
||||
private static readonly string DocumentConverterUrl;
|
||||
|
||||
/// <summary>
|
||||
/// Url to the service of storage
|
||||
/// </summary>
|
||||
private static readonly string DocumentStorageUrl;
|
||||
|
||||
/// <summary>
|
||||
/// The parameters for the query conversion
|
||||
/// </summary>
|
||||
private const string ConvertParams = "?url={0}&outputtype={1}&filetype={2}&title={3}&key={4}&vkey={5}";
|
||||
|
||||
/// <summary>
|
||||
/// Number of tries request conversion
|
||||
/// </summary>
|
||||
private const int MaxTry = 3;
|
||||
|
||||
#endregion
|
||||
|
||||
#region public method
|
||||
|
||||
/// <summary>
|
||||
/// The method is to convert the file to the required format
|
||||
/// </summary>
|
||||
/// <param name="documentUri">Uri for the document to convert</param>
|
||||
/// <param name="fromExtension">Document extension</param>
|
||||
/// <param name="toExtension">Extension to which to convert</param>
|
||||
/// <param name="documentRevisionId">Key for caching on service</param>
|
||||
/// <param name="isAsync">Perform conversions asynchronously</param>
|
||||
/// <param name="convertedDocumentUri">Uri to the converted document</param>
|
||||
/// <returns>The percentage of completion of conversion</returns>
|
||||
/// <example>
|
||||
/// string convertedDocumentUri;
|
||||
/// GetConvertedUri("http://helpcenter.onlyoffice.com/content/GettingStarted.pdf", ".pdf", ".docx", "http://helpcenter.onlyoffice.com/content/GettingStarted.pdf", false, out convertedDocumentUri);
|
||||
/// </example>
|
||||
/// <exception>
|
||||
/// </exception>
|
||||
public static int GetConvertedUri(string documentUri,
|
||||
string fromExtension,
|
||||
string toExtension,
|
||||
string documentRevisionId,
|
||||
bool isAsync,
|
||||
out string convertedDocumentUri)
|
||||
{
|
||||
convertedDocumentUri = string.Empty;
|
||||
var responceFromConvertService =
|
||||
SendRequestToConvertService(documentUri, fromExtension, toExtension, documentRevisionId, isAsync)
|
||||
.Root;
|
||||
|
||||
var errorElement = responceFromConvertService.Element("Error");
|
||||
if (errorElement != null)
|
||||
ProcessConvertServiceResponceError(Convert.ToInt32(errorElement.Value));
|
||||
|
||||
var isEndConvert = Convert.ToBoolean(responceFromConvertService.Element("EndConvert").Value);
|
||||
var percent = Convert.ToInt32(responceFromConvertService.Element("Percent").Value);
|
||||
|
||||
if (isEndConvert)
|
||||
{
|
||||
convertedDocumentUri = responceFromConvertService.Element("FileUrl").Value;
|
||||
percent = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
percent = percent >= 100 ? 99 : percent;
|
||||
}
|
||||
|
||||
return percent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Placing the document in the storage service
|
||||
/// </summary>
|
||||
/// <param name="fileStream">Stream of document</param>
|
||||
/// <param name="contentLength">Length of stream</param>
|
||||
/// <param name="contentType">Mime type</param>
|
||||
/// <param name="documentRevisionId">Key for caching on service, whose used in editor</param>
|
||||
/// <returns>Uri to document in the storage</returns>
|
||||
public static string GetExternalUri(
|
||||
Stream fileStream,
|
||||
long contentLength,
|
||||
string contentType,
|
||||
string documentRevisionId)
|
||||
{
|
||||
var validateKey = GenerateValidateKey(documentRevisionId, false);
|
||||
|
||||
var urlDocumentService = DocumentStorageUrl + ConvertParams;
|
||||
var urlTostorage = String.Format(urlDocumentService,
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
documentRevisionId,
|
||||
validateKey);
|
||||
|
||||
var request = (HttpWebRequest)WebRequest.Create(urlTostorage);
|
||||
request.Method = "POST";
|
||||
request.ContentType = contentType;
|
||||
request.ContentLength = contentLength;
|
||||
|
||||
const int bufferSize = 2048;
|
||||
var buffer = new byte[bufferSize];
|
||||
int readed;
|
||||
while ((readed = fileStream.Read(buffer, 0, bufferSize)) > 0)
|
||||
{
|
||||
request.GetRequestStream().Write(buffer, 0, readed);
|
||||
}
|
||||
|
||||
using (var response = request.GetResponse())
|
||||
using (var stream = response.GetResponseStream())
|
||||
{
|
||||
if (stream == null) throw new WebException("Could not get an answer");
|
||||
var xDocumentResponse = XDocument.Load(new XmlTextReader(stream));
|
||||
string externalUri;
|
||||
GetResponseUri(xDocumentResponse, out externalUri);
|
||||
return externalUri;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translation key to a supported form.
|
||||
/// </summary>
|
||||
/// <param name="expectedKey">Expected key</param>
|
||||
/// <returns>Supported key</returns>
|
||||
public static string GenerateRevisionId(string expectedKey)
|
||||
{
|
||||
if (expectedKey.Length > 20) expectedKey = expectedKey.GetHashCode().ToString();
|
||||
var key = Regex.Replace(expectedKey, "[^0-9-.a-zA-Z_=]", "_");
|
||||
return key.Substring(key.Length - Math.Min(key.Length, 20));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate validate key for editor by documentId
|
||||
/// </summary>
|
||||
/// <param name="documentRevisionId">Key for caching on service, whose used in editor</param>
|
||||
/// <returns>Validation key</returns>
|
||||
/// <example>LFJ7 or "http://helpcenter.onlyoffice.com/content/GettingStarted.pdf"</example>
|
||||
public static string GenerateValidateKey(string documentRevisionId)
|
||||
{
|
||||
return GenerateValidateKey(documentRevisionId, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private method
|
||||
|
||||
/// <summary>
|
||||
/// Generate validate key for editor by documentId
|
||||
/// </summary>
|
||||
/// <param name="documentRevisionId">Key for caching on service, whose used in editor</param>
|
||||
/// <param name="addHostForValidate">Add host address to the key</param>
|
||||
/// <returns>Validation key</returns>
|
||||
private static string GenerateValidateKey(string documentRevisionId, bool addHostForValidate)
|
||||
{
|
||||
if (string.IsNullOrEmpty(documentRevisionId)) return string.Empty;
|
||||
|
||||
documentRevisionId = GenerateRevisionId(documentRevisionId);
|
||||
|
||||
var keyId = GetKey();
|
||||
var userCount = 0;
|
||||
|
||||
object primaryKey = null;
|
||||
|
||||
if (addHostForValidate)
|
||||
{
|
||||
string userIp = null;
|
||||
try
|
||||
{
|
||||
if (HttpContext.Current != null)
|
||||
{
|
||||
userIp = HttpContext.Current.Request.UserHostAddress;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(userIp))
|
||||
primaryKey = new {expire = DateTime.UtcNow, key = documentRevisionId, key_id = keyId, user_count = userCount, ip = userIp};
|
||||
}
|
||||
|
||||
if (primaryKey == null)
|
||||
primaryKey = new {expire = DateTime.UtcNow, key = documentRevisionId, key_id = keyId, user_count = userCount};
|
||||
|
||||
return Signature.Create(primaryKey, GetSKey());
|
||||
}
|
||||
|
||||
private static object GetKey()
|
||||
{
|
||||
return WebConfigurationManager.AppSettings["files.docservice.tenantid"] ?? "OnlineEditorsExampleMVC";
|
||||
}
|
||||
|
||||
private static string GetSKey()
|
||||
{
|
||||
return WebConfigurationManager.AppSettings["files.docservice.key"] ?? "ONLYOFFICE";
|
||||
;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request for conversion to a service
|
||||
/// </summary>
|
||||
/// <param name="documentUri">Uri for the document to convert</param>
|
||||
/// <param name="fromExtension">Document extension</param>
|
||||
/// <param name="toExtension">Extension to which to convert</param>
|
||||
/// <param name="documentRevisionId">Key for caching on service</param>
|
||||
/// <param name="isAsync">Perform conversions asynchronously</param>
|
||||
/// <returns>Xml document request result of conversion</returns>
|
||||
private static XDocument SendRequestToConvertService(string documentUri, string fromExtension, string toExtension, string documentRevisionId, bool isAsync)
|
||||
{
|
||||
fromExtension = string.IsNullOrEmpty(fromExtension) ? Path.GetExtension(documentUri) : fromExtension;
|
||||
|
||||
var title = Path.GetFileName(documentUri);
|
||||
title = string.IsNullOrEmpty(title) ? Guid.NewGuid().ToString() : title;
|
||||
|
||||
documentRevisionId = string.IsNullOrEmpty(documentRevisionId)
|
||||
? documentUri
|
||||
: documentRevisionId;
|
||||
documentRevisionId = GenerateRevisionId(documentRevisionId);
|
||||
|
||||
var validateKey = GenerateValidateKey(documentRevisionId, false);
|
||||
|
||||
var urlDocumentService = DocumentConverterUrl + ConvertParams;
|
||||
var urlToConverter = String.Format(urlDocumentService,
|
||||
HttpUtility.UrlEncode(documentUri),
|
||||
toExtension.Trim('.'),
|
||||
fromExtension.Trim('.'),
|
||||
title,
|
||||
documentRevisionId,
|
||||
validateKey);
|
||||
|
||||
if (isAsync)
|
||||
urlToConverter += "&async=true";
|
||||
|
||||
var req = (HttpWebRequest) WebRequest.Create(urlToConverter);
|
||||
req.Timeout = ConvertTimeout;
|
||||
|
||||
Stream stream = null;
|
||||
var countTry = 0;
|
||||
while (countTry < MaxTry)
|
||||
{
|
||||
try
|
||||
{
|
||||
countTry++;
|
||||
stream = req.GetResponse().GetResponseStream();
|
||||
break;
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
if (ex.Status != WebExceptionStatus.Timeout)
|
||||
{
|
||||
throw new HttpException((int) HttpStatusCode.BadRequest, "Bad Request", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (countTry == MaxTry)
|
||||
{
|
||||
throw new WebException("Timeout", WebExceptionStatus.Timeout);
|
||||
}
|
||||
|
||||
return XDocument.Load(new XmlTextReader(stream));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate an error code table
|
||||
/// </summary>
|
||||
/// <param name="errorCode">Error code</param>
|
||||
private static void ProcessConvertServiceResponceError(int errorCode)
|
||||
{
|
||||
var errorMessage = string.Empty;
|
||||
const string errorMessageTemplate = "Error occurred in the ConvertService.ashx: {0}";
|
||||
|
||||
switch (errorCode)
|
||||
{
|
||||
case -8:
|
||||
// public const int c_nErrorFileVKey = -8;
|
||||
errorMessage = String.Format(errorMessageTemplate, "Error document VKey");
|
||||
break;
|
||||
case -7:
|
||||
// public const int c_nErrorFileRequest = -7;
|
||||
errorMessage = String.Format(errorMessageTemplate, "Error document request");
|
||||
break;
|
||||
case -6:
|
||||
// public const int c_nErrorDatabase = -6;
|
||||
errorMessage = String.Format(errorMessageTemplate, "Error database");
|
||||
break;
|
||||
case -5:
|
||||
// public const int c_nErrorUnexpectedGuid = -5;
|
||||
errorMessage = String.Format(errorMessageTemplate, "Error unexpected guid");
|
||||
break;
|
||||
case -4:
|
||||
// public const int c_nErrorDownloadError = -4;
|
||||
errorMessage = String.Format(errorMessageTemplate, "Error download error");
|
||||
break;
|
||||
case -3:
|
||||
// public const int c_nErrorConvertationError = -3;
|
||||
errorMessage = String.Format(errorMessageTemplate, "Error convertation error");
|
||||
break;
|
||||
case -2:
|
||||
// public const int c_nErrorConvertationTimeout = -2;
|
||||
errorMessage = String.Format(errorMessageTemplate, "Error convertation timeout");
|
||||
break;
|
||||
case -1:
|
||||
// public const int c_nErrorUnknown = -1;
|
||||
errorMessage = String.Format(errorMessageTemplate, "Error convertation unknown");
|
||||
break;
|
||||
case 0:
|
||||
// public const int c_nErrorNo = 0;
|
||||
break;
|
||||
default:
|
||||
errorMessage = "ErrorCode = " + errorCode;
|
||||
break;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processing document received from the editing service
|
||||
/// </summary>
|
||||
/// <param name="xDocumentResponse">The resulting xml from editing service</param>
|
||||
/// <param name="responseUri">Uri to the converted document</param>
|
||||
/// <returns>The percentage of completion of conversion</returns>
|
||||
private static int GetResponseUri(XDocument xDocumentResponse, out string responseUri)
|
||||
{
|
||||
var responceFromConvertService = xDocumentResponse.Root;
|
||||
if (responceFromConvertService == null) throw new WebException("Invalid answer format");
|
||||
|
||||
var errorElement = responceFromConvertService.Element("Error");
|
||||
if (errorElement != null) ProcessConvertServiceResponceError(Convert.ToInt32(errorElement.Value));
|
||||
|
||||
var endConvert = responceFromConvertService.Element("EndConvert");
|
||||
if (endConvert == null) throw new WebException("Invalid answer format");
|
||||
var isEndConvert = Convert.ToBoolean(endConvert.Value);
|
||||
|
||||
var resultPercent = 0;
|
||||
responseUri = string.Empty;
|
||||
if (isEndConvert)
|
||||
{
|
||||
var fileUrl = responceFromConvertService.Element("FileUrl");
|
||||
if (fileUrl == null) throw new WebException("Invalid answer format");
|
||||
|
||||
responseUri = fileUrl.Value;
|
||||
resultPercent = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
var percent = responceFromConvertService.Element("Percent");
|
||||
if (percent != null)
|
||||
resultPercent = Convert.ToInt32(percent.Value);
|
||||
resultPercent = resultPercent >= 100 ? 99 : resultPercent;
|
||||
}
|
||||
|
||||
return resultPercent;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Class to encode a string
|
||||
/// </summary>
|
||||
internal static class Signature
|
||||
{
|
||||
/// <summary>
|
||||
/// Encoding string from object
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of object</typeparam>
|
||||
/// <param name="obj">Object</param>
|
||||
/// <param name="secret">Secret key for encoding</param>
|
||||
/// <returns>Encoding string</returns>
|
||||
public static string Create<T>(T obj, string secret)
|
||||
{
|
||||
var serializer = new JavaScriptSerializer();
|
||||
var str = serializer.Serialize(obj);
|
||||
var payload = GetHashBase64(str + secret) + "?" + str;
|
||||
return HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(payload));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String in base64 encoding
|
||||
/// </summary>
|
||||
/// <param name="str">String fo encoding</param>
|
||||
/// <returns>Encoding string</returns>
|
||||
private static string GetHashBase64(string str)
|
||||
{
|
||||
return Convert.ToBase64String(SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(str)));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user