I want to display scatter points in surface plot. Is this feasible in lightning chart?
Thanks,
Yes, it's possible.
Please see ExampleSurfaceMouseEditing in the LC WPF Demo App.
It shows scatter point in each data value of Surface, and shows how to modify the surface geometry Y value by dragging a point with mouse.
using System;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Controls;
using Arction.Wpf.Charting;
using Arction.Wpf.Charting.Series3D;
using Arction.Wpf.Charting.Views.View3D;
namespace DemoAppWpf
{
/// <summary>
/// 3D surface data modifying by mouse. Illustrates MovePoint feature of View3D.
/// </summary>
public partial class ExampleSurfaceMouseEdit : Example
{
/// <summary>
/// LightningChart component.
/// </summary>
LightningChartUltimate _chart;
/// <summary>
/// 3D surface.
/// </summary>
SurfaceGridSeries3D _surface;
/// <summary>
/// Surface verteces.
/// </summary>
PointLineSeries3D _points;
/// <summary>
/// Mouse state for editing the surface.
/// </summary>
bool _editing = false;
/// <summary>
/// Index of editable vertice.
/// </summary>
int _editingPointIndex;
/// <summary>
/// Surface vertices size.
/// </summary>
const float NormalPointSize = 1f;
/// <summary>
/// Size for selected surface vertices.
/// </summary>
const float LargePointSize = 2f;
/// <summary>
/// Surface vertices color.
/// </summary>
static Color NormalPointColor = Colors.Gray;
/// <summary>
/// Color for selected surface vertices.
/// </summary>
static Color HighlightedPointColor = Colors.Yellow;
public ExampleSurfaceMouseEdit()
{
InitializeComponent();
CreateChart();
}
/// <summary>
/// Create chart.
/// </summary>
private void CreateChart()
{
_chart = new LightningChartUltimate();
// Disable rendering, strongly recommended before updating chart properties.
_chart.BeginUpdate();
_chart.ChartName = "Surface mouse edit chart";
_chart.Title.Text = "Move mouse over surface, and press mouse button down to start moving a point";
_chart.ActiveView = ActiveView.View3D;
View3D view = _chart.View3D;
// Disable rotation from left button, so it can be used for adjusting points.
view.ZoomPanOptions.LeftMouseButtonAction = MouseButtonAction3D.None;
view.ZoomPanOptions.RightMouseButtonAction = MouseButtonAction3D.Rotate;
view.Camera.RotationX += 20;
// Create Surface.
_surface = new SurfaceGridSeries3D(view, Axis3DBinding.Primary, Axis3DBinding.Primary, Axis3DBinding.Primary);
_surface.ContourLineType = ContourLineType3D.None;
_surface.Fill = SurfaceFillStyle.PalettedByY;
_surface.SetRangesXZ(10, 90, 10, 90);
_surface.MouseInteraction = false;
_surface.WireframeType = SurfaceWireframeType3D.WireframePalettedByY;
view.SurfaceGridSeries3D.Add(_surface);
// Create series of poits to interract with surface.
_points = new PointLineSeries3D(_chart.View3D, Axis3DBinding.Primary, Axis3DBinding.Primary, Axis3DBinding.Primary);
_points.ShowInLegendBox = false;
_points.PointStyle.Shape3D = PointShape3D.Sphere;
_points.PointStyle.Size3D.SetValues(1, 1, 1);
_points.Material.DiffuseColor = Color.FromArgb(255, 120, 120, 120);
_points.MouseInteraction = true;
_points.MouseHighlight = MouseOverHighlight.None;
_points.LineVisible = false;
_points.IndividualPointColors = true;
_points.IndividualPointSizes = true;
view.PointLineSeries3D.Add(_points);
SurfacePoint[,] surfaceData;
SeriesPoint3D[] pointsData;
// Set data for surface and points
CreateData(out surfaceData, out pointsData, _surface.RangeMinX, _surface.RangeMaxX, _surface.RangeMinZ, _surface.RangeMaxZ);
_surface.Data = surfaceData;
_points.Points = pointsData;
// Registrate mouse events.
_chart.PreviewMouseLeftButtonDown += _chart_MouseDown;
_chart.PreviewMouseLeftButtonUp += _chart_MouseUp;
_chart.MouseMove += _chart_MouseMove;
// Allow chart rendering.
_chart.EndUpdate();
(Content as Grid).Children.Add(_chart);
base.ChartsCreated(_chart);
}
private void _chart_MouseDown(object sender, MouseButtonEventArgs e)
{
if (_editingPointIndex >= 0)
_editing = true;
}
private void _chart_MouseUp(object sender, MouseButtonEventArgs e)
{
_editing = false;
ResetPointsToNormalState();
_editingPointIndex = -1;
}
private void _chart_MouseMove(object sender, MouseEventArgs e)
{
// Right mouse button is set for Rotation; if it is pressed no further execution of the code here is required.
if (e.RightButton == MouseButtonState.Pressed)
return;
var position = e.GetPosition(_chart);
if (_editing)
{
_chart.BeginUpdate();
PointDouble3D startPoint = new PointDouble3D(_points.Points[_editingPointIndex].X, _points.Points[_editingPointIndex].Y, _points.Points[_editingPointIndex].Z);
// Move the point in Y dimension
var movedPoint = _chart.View3D.MovePoint(Axis3DBinding.Primary, new PointDouble3D(startPoint.X, startPoint.Y, startPoint.Z),
new PointFloatXY((float)position.X, (float)position.Y), MovementDimension.Y);
_points.Points[_editingPointIndex].X = movedPoint.X;
_points.Points[_editingPointIndex].Y = movedPoint.Y;
_points.Points[_editingPointIndex].Z = movedPoint.Z;
_points.InvalidateData();
_surface.Data[_editingPointIndex / _surface.SizeZ, _editingPointIndex % _surface.SizeZ].Y = movedPoint.Y;
_surface.InvalidateData();
_chart.EndUpdate();
}
else
{
int pointIndex = -1;
bool overLine = false;
bool overPoint = false;
if (_points.IsMouseOver((int)position.X, (int)position.Y, out pointIndex, out overLine, out overPoint, true))
{
_chart.BeginUpdate();
if (pointIndex != _editingPointIndex && _editingPointIndex >= 0)
ResetPointsToNormalState();
_editingPointIndex = pointIndex;
_points.Points[pointIndex].SizeFactor = LargePointSize;
_points.Points[pointIndex].Color = HighlightedPointColor;
_points.InvalidateData();
_chart.EndUpdate();
}
else
{
ResetPointsToNormalState();
}
}
}
/// <summary>
/// Reset points to normal state
/// </summary>
void ResetPointsToNormalState()
{
if (_editingPointIndex >= 0)
{
int pointCount = _points.Points.Length;
for (int i = 0; i < pointCount; i++)
{
_points.Points[i].SizeFactor = NormalPointSize;
_points.Points[i].Color = NormalPointColor;
}
_points.InvalidateData();
}
}
/// <summary>
/// Create data array for surface.
/// <param name="pointsData">Points</param>
/// <param name="surfaceData">Surface data</param>
/// <param name="xMax">X Max</param>
/// <param name="xMin">X Min</param>
/// <param name="zMax">Z Max</param>
/// <param name="zMin">Z Min</param>
/// </summary>
void CreateData(out SurfacePoint[,] surfaceData, out SeriesPoint3D[] pointsData, double xMin, double xMax, double zMin, double zMax)
{
int xCount = 50;
int zCount = 30;
surfaceData = new SurfacePoint[xCount, zCount];
pointsData = new SeriesPoint3D[xCount * zCount];
double xStep = (xMax - xMin) / (double)(xCount - 1);
double zStep = (zMax - zMin) / (double)(zCount - 1);
double y;
for (int xIndex = 0; xIndex < xCount; xIndex++)
{
for (int zIndex = 0; zIndex < zCount; zIndex++)
{
y = 30 + 20.0 * Math.Sin(0.01 * (double)(xIndex * zIndex) + 0.2);
if ((xIndex + 5) % 20 == 0)
y += 20;
if ((zIndex + 5) % 20 == 0)
y += 30;
surfaceData[xIndex, zIndex].Y = y;
pointsData[xIndex * zCount + zIndex] = new SeriesPoint3D(xMin + (double)xIndex * xStep, y, zMin + (double)zIndex * zStep, NormalPointColor, NormalPointSize);
}
}
}
public override void Dispose()
{
// Don't forget to clear chart grid child list.
(Content as Grid).Children.Clear();
if (_chart != null)
{
_chart.Dispose();
_chart = null;
}
// Disposing of unmanaged resources done.
base.DisposedOf();
}
}
}
Related
Firstly I've seen few issues raised on "Padding is invalid and can not be removed". I looked all of them and my issue is quiet different.
I am using a code below where I can encrypt the data from PS script and decrypt from .NET application.
However, when I try to encrypt the text on .NET/PS script and try to decrypt on site below it doesn't work.
https://aesencryption.net/
When I try to decrypted the encrypted data from this site on to PS or .NET code (using same key) I keep getting this error:
"Padding is invalid and cannot be removed."
I used 256 bit key and key is exactly same.
/// <summary>
/// AES wrapper implementation by Yovav Gad using the AesManaged algorithm.
/// <para>http://en.wikipedia.org/wiki/Advanced_Encryption_Standard</para>
/// </summary>
public sealed class AesWrapper
{
/// <summary>
/// Create a SymmetricAlgorithm using AesManaged
/// </summary>
/// <param name="key">Byte array representing the key values, please note,
/// for better performance, use Convert.FromBase64String() outside of this method.</param>
/// <param name="blockSize">BlockSize, default is 128</param>
/// <param name="paddingMode">PaddingMode, default is PaddingMode.PKCS7</param>
/// <param name="cipherMode">CipherMode, default is CipherMode.CBC</param>
/// <returns></returns>
private static SymmetricAlgorithm CreateCrypto(
byte[] key,
int blockSize = 128,
PaddingMode paddingMode = PaddingMode.PKCS7,
CipherMode cipherMode = CipherMode.CBC
)
{
SymmetricAlgorithm crypto = new AesManaged
{
Key = key,
Mode = cipherMode,
Padding = paddingMode,
BlockSize = blockSize
};
crypto.IV = new byte[crypto.IV.Length];
return (crypto);
}
/// <summary>
/// Decrypt an encrypted string using a specific key.
/// </summary>
/// <param name="str">String to decrypt</param>
/// <param name="key">Byte array representing the key values, please note,
/// for better performance, use Convert.FromBase64String() outside of this method.</param>
/// <param name="blockSize">BlockSize, default is 128</param>
/// <param name="paddingMode">PaddingMode, default is PaddingMode.Zeros</param>
/// <param name="cipherMode">CipherMode, default is CipherMode.CBC</param>
/// <returns></returns>
[DebuggerStepThrough()]
public static string Decrypt(
string str,
byte[] key,
int blockSize = 128,
PaddingMode paddingMode = PaddingMode.PKCS7,
CipherMode cipherMode = CipherMode.CBC
)
{
if (str == null || str.Length < 1 ||
key == null || key.Length < 1)
{
return null;
}
var result = string.Empty;
using (var crypto = CreateCrypto(key, blockSize, paddingMode, cipherMode))
{
var strCombined = Convert.FromBase64String(str);
var iv = new byte[crypto.BlockSize / 8];
var cipherText = new byte[strCombined.Length - iv.Length];
Array.Copy(strCombined, iv, iv.Length);
Array.Copy(strCombined, iv.Length, cipherText, 0, cipherText.Length);
crypto.IV = iv;
ICryptoTransform decryptor = crypto.CreateDecryptor(key, iv);
using (var msDecrypt = new MemoryStream(cipherText))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
result = srDecrypt.ReadToEnd();
}
}
}
if (paddingMode == PaddingMode.PKCS7)
{
// This is required when using PaddingMode.Zeros for values shorted than the block size.
// Note: using .TrimEnd('\0') to remove nulls and not .TrimEnd("\0") to allow the string values.
result = result.TrimEnd('\0');
}
return (result);
}
}
/// <summary>
/// Encrypt a string using a specific key.
/// </summary>
/// <param name="str">String to encrypt</param>
/// <param name="key">Byte array representing the key values, please note,
/// for better performance, use Convert.FromBase64String() outside of this method.</param>
/// <param name="blockSize">BlockSize, default is 128</param>
/// <param name="paddingMode">PaddingMode, default is PaddingMode.Zeros</param>
/// <param name="cipherMode">CipherMode, default is CipherMode.CBC</param>
/// <returns></returns>
[DebuggerStepThrough()]
public static string Encrypt(
string str,
byte[] key,
int blockSize = 128,
PaddingMode paddingMode = PaddingMode.PKCS7,
CipherMode cipherMode = CipherMode.CBC
)
{
if (str == null || str.Length < 1 ||
key == null || key.Length < 1)
{
return null;
}
byte[] encryptedData;
using (SymmetricAlgorithm crypto = CreateCrypto(key, blockSize, paddingMode, cipherMode))
{
byte[] data;
crypto.GenerateIV();
var iv = crypto.IV;
var encryptor = crypto.CreateEncryptor(key, iv);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(str);
}
data = ms.ToArray();
}
}
// Combine the iv (salt) and the encrypted data
encryptedData = new byte[iv.Length + data.Length];
Array.Copy(iv, 0, encryptedData, 0, iv.Length);
Array.Copy(data, 0, encryptedData, iv.Length, data.Length);
}
return Convert.ToBase64String(encryptedData);
}
}
void Main()
{
var keyString = "8CBaNtMYwAuu2K/xleoRfgPkURaLK82QidlIyg+nFY4=";
var keyBytes = Convert.FromBase64String(keyString);
var plainText = "aes test";
var testEncrypted = AesWrapper.Encrypt(plainText, keyBytes);
Console.WriteLine(testEncrypted);
var testDecrypted = AesWrapper.Decrypt("gM+oae1MZlj42b9UtCw2dw==", keyBytes);
Console.WriteLine(testDecrypted);
var testReEncrypted = AesWrapper.Encrypt(testEncrypted, keyBytes);
}
PS Script
function Create-AesManagedObject($key, $IV) {
$aesManaged = New-Object "System.Security.Cryptography.AesManaged"
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
if ($IV) {
if ($IV.getType().Name -eq "String") {
$aesManaged.IV = [System.Convert]::FromBase64String($IV)
}
else {
$aesManaged.IV = $IV
}
}
if ($key) {
if ($key.getType().Name -eq "String") {
$aesManaged.Key = [System.Convert]::FromBase64String($key)
}
else {
$aesManaged.Key = $key
}
}
$aesManaged
}
function Create-AesKey() {
$aesManaged = Create-AesManagedObject
$aesManaged.GenerateKey()
[System.Convert]::ToBase64String($aesManaged.Key)
}
function Encrypt-String($key, $unencryptedString) {
$bytes = [System.Text.Encoding]::UTF8.GetBytes($unencryptedString)
$aesManaged = Create-AesManagedObject $key
$encryptor = $aesManaged.CreateEncryptor()
$encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length);
[byte[]] $fullData = $aesManaged.IV + $encryptedData
$aesManaged.Dispose()
[System.Convert]::ToBase64String($fullData)
}
function Decrypt-String($key, $encryptedStringWithIV) {
$bytes = [System.Convert]::FromBase64String($encryptedStringWithIV)
$IV = $bytes[0..15]
$aesManaged = Create-AesManagedObject $key $IV
$decryptor = $aesManaged.CreateDecryptor();
$unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16);
$aesManaged.Dispose()
[System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)
}
cls
<#
# This will generate a new valid AES 256 key if needed:
# $key = Create-AesKey
#>
<#
# This is the hard coded key
#>
$key = Create-AesKey
#$key = "8CBaNtMYwAuu2K/xleoRfgPkURaLK82Q"
Write-Host "key = $key"
$unencryptedString = "dil pun"
Write-Host "unencryptedString = $unencryptedString"
$encryptedString = Encrypt-String $key $unencryptedString
Write-Host "encryptedString = $encryptedString "
$backToPlainText = Decrypt-String $key $encryptedString
Write-Host "backToPlainText = $backToPlainText"
<#
# To run this PowerShell script:
#
# In Windows PowerShell:
# .\PowerShell_AES_Encryption_Example.ps1
# C:\Test\PowerShell_AES_Encryption_Example.ps1
#
# In Command Prompt:
# powershell -noexit "& ""C:\Test\PowerShell_AES_Encryption_Example.ps1"""
#>
Any idea why this code can not decrypt the data that's been encrypted by https://aesencryption.net/ using same key and vice versa?
And what exactly does both party need to match ? E.g key size, key value, Padding and mode.
Does IV, based etc needs to match?
Thanks.
And what exactly does both party need to match
For AES everything you have to use the exact same values for encryption and decryption:
key (print it as hex key and compare it)
IV (16 bytes of random data for encryption, and for decryption use the same bytes as used for encryption). The common way is to prepend the IV to the encrypted data and read it before performing the actual decryption.
Crypto mode (here CBC)
Padding
I can save a picture in iOS and Android but I can't find a way to save an image in UWP. Any ideas?
Thank you in advance.
I can't find a way to save an image in UWP
No, we can't extract the image data from an Xamarin ImageSource object.
There is StreamImagesourceHandler class implementation in UWP, see here
public sealed class StreamImageSourceHandler : IImageSourceHandler
{
public async Task<Windows.UI.Xaml.Media.ImageSource> LoadImageAsync(ImageSource imagesource, CancellationToken cancellationToken = new CancellationToken())
{
BitmapImage bitmapimage = null;
//Omitted
return bitmapimage;
}
}
So we need to extract data from BitmapImage.
Actually the BitmapImage class is inherited from ImageSource class, while we can't extract the image data from ImageSource, for the reason, please see these two questions:
Convert ImageSource to WriteableBitmap in Metro Windows 8
How save BitmapImage WinRT
The solution here is to use different way for Windows Runtime(W/WP8.1 & UWP) app, extracting image data from System.IO.Stream class is supported in UWP.
We can use DependencyService to access native platform features, firstly, create an interface in PCL:
public interface ISaveImage
{
void SavePictureToDisk(ImageSource imgSrc, string Id, bool OverwriteIfExist = false);
void SavePictureToDiskWINRT(System.IO.Stream imgStream, string Id, bool OverwriteIfExist = false);
}
In the code behind of Xamarin page:
var memoryStream = new MemoryStream(Convert.FromBase64String("iVBOxxxxxxxxxxMVEX/uQOAuwPzUxxxxxxxxxxxx="));
ImageSource imgsource = ImageSource.FromStream(() => memoryStream);
if (Device.OS == TargetPlatform.Windows|| Device.OS == TargetPlatform.WinPhone)
DependencyService.Get<ISaveImage>().SavePictureToDiskWINRT(memoryStream, "1");
else
DependencyService.Get<ISaveImage>().SavePictureToDisk(imgsource, "1");
Implement the interface in UWP platform:
using Xamarin.Forms;
using WorkingWithImages.WinUniversal;
using System.IO;
using System;
using Windows.Storage.Streams;
[assembly: Xamarin.Forms.Dependency(typeof(SaveImageImplementation))]
namespace WorkingWithImages.WinUniversal
{
public class SaveImageImplementation : ISaveImage
{
public SaveImageImplementation() { }
public void SavePictureToDisk(ImageSource imgSrc, string Id, bool OverwriteIfExist = false)
{
throw new NotImplementedException();
}
public async void SavePictureToDiskWINRT(Stream imgStream, string Id, bool OverwriteIfExist = false)
{
var inStream = imgStream.AsRandomAccessStream();
var fileBytes = new byte[inStream.Size];
using (DataReader reader = new DataReader(inStream))
{
await reader.LoadAsync((uint)inStream.Size);
reader.ReadBytes(fileBytes);
}
var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(Id+".jpg", Windows.Storage.CreationCollisionOption.ReplaceExisting);
using (var fs = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
var outStream = fs.GetOutputStreamAt(0);
var dataWriter = new DataWriter(outStream);
dataWriter.WriteBytes(fileBytes);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
await outStream.FlushAsync();
outStream.Dispose();
fs.Dispose();
}
}
}
}
Please check my completed demo in here
About UWP File storage guidance, please see Create, write, and read a file
maybe someone needs a solution for iOS and Android (below). Meanwhile I'm waiting an idea for UWP.
iOS
/// <summary>
/// Saves the picture to disk.
/// </summary>
/// <returns>The picture to disk.</returns>
/// <param name="imgSrc">Image source.</param>
/// <param name="id">Identifier.</param>
/// <param name="overwriteIfExist">if set to <c>true</c> overwrite if exist.</param>
/// <returns>The picture to disk.</returns>
public async void SaveImage(ImageSource imgSrc, string id, bool overwriteIfExist = false)
{
var renderer = new StreamImagesourceHandler();
var photo = await renderer.LoadImageAsync(imgSrc);
string jpgFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), id + ".jpg");
if (File.Exists(jpgFilename))
{
File.Delete(jpgFilename);
}
NSData imgData = photo.AsJPEG();
NSError err;
if (imgData.Save(jpgFilename, false, out err))
{
Console.WriteLine("saved as " + jpgFilename);
}
else
{
Console.WriteLine("NOT saved as " + jpgFilename
+ " because" + err.LocalizedDescription);
}
}
Good to know, when iOS saves an image as jpg, the image header says png.
Android
/// <summary>
/// Saves the picture to disk.
/// </summary>
/// <param name="imgSrc">Image source.</param>
/// <param name="id">The image identifier.</param>
/// <param name="overwriteIfExist">if set to <c>true</c> overwrite if exist.</param>
/// <returns>The picture to disk.</returns>
public async void SaveImage(ImageSource imgSrc, string id,
bool overwriteIfExist = false)
{
var renderer = new StreamImagesourceHandler();
var photo = await renderer.LoadImageAsync(imgSrc, Forms.Context);
string jpgFilename = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), id + ".jpg");
if (File.Exists(jpgFilename))
{
File.Delete(jpgFilename);
}
using (FileStream fs = new FileStream(jpgFilename, FileMode.OpenOrCreate))
{
photo.Compress(Bitmap.CompressFormat.Jpeg, 100, fs);
}
}
How can I get channel messages from telegram channels with TLSharp?
The following links haven't helped me:
How can I get messages from a Telegram channel with the Telegram API
How to obtain all messages from my channel in telegram?
You can use this code
public async Task GatherChannelHistory(string channelName, int offset = 0, int maxId = -1, int limit = 50)
{
_resultMessages.Clear();
await _client.ConnectAsync();
var dialogs = (TLDialogsSlice)await _client.GetUserDialogsAsync();
var chat = dialogs.Chats.ToList()
.OfType<TLChannel>()
.FirstOrDefault(c => c.Title == channelName);
if (chat.AccessHash != null)
{
var tlAbsMessages =
await _client.GetHistoryAsync(
new TLInputPeerChannel {ChannelId= chat.Id, AccessHash = chat.AccessHash.Value}, offset,
maxId, limit);
var tlChannelMessages = (TLChannelMessages) tlAbsMessages;
for (var index = 0; index < tlChannelMessages.Messages.Count-1; index++)
{
var tlAbsMessage = tlChannelMessages.Messages.ToList()[index];
var message = (TLMessage) tlAbsMessage;
//Now you have the message and you can do what you need with it
//the code below is an example of messages classification
if (message.media == null)
{
_resultMessages.Add(new ChannelMessage()
{
Id = message.id,
ChannelId = chat.id,
Content = message.message,
Type = EnChannelMessage.Message,
Views = message.views,
});
}
else
{
switch (message.media.GetType().ToString())
{
case "TeleSharp.TL.TLMessageMediaPhoto":
var tLMessageMediaPhoto = (TLMessageMediaPhoto)message.media;
_resultMessages.Add(new ChannelMessage()
{
Id = message.id,
ChannelId = chat.id,
Content = tLMessageMediaPhoto.caption,
Type = EnChannelMessage.MediaPhoto,
Views = message.views ?? 0,
});
break;
case "TeleSharp.TL.TLMessageMediaDocument":
var tLMessageMediaDocument = (TLMessageMediaDocument)message.media;
_resultMessages.Add(new ChannelMessage()
{
Id = message.id,
ChannelId = chat.id,
Content = tLMessageMediaDocument.caption,
Type = EnChannelMessage.MediaDocument,
Views = message.views ?? 0,
});
break;
case "TeleSharp.TL.TLMessageMediaWebPage":
var tLMessageMediaWebPage = (TLMessageMediaWebPage)message.media;
string url = string.Empty;
if (tLMessageMediaWebPage.webpage.GetType().ToString() != "TeleSharp.TL.TLWebPageEmpty")
{
var webPage = (TLWebPage) tLMessageMediaWebPage.webpage;
url = webPage.url;
}
_resultMessages.Add(new ChannelMessage
{
Id = message.id,
ChannelId = chat.id,
Content = message.message + #" : " + url,
Type = EnChannelMessage.WebPage,
Views = message.views ?? 0,
});
break;
}
}
}
}
}
To get channel messages you simply need to be receiving channel updates.
As at TL-schema-52 you could request:
channels.getDialogs#a9d3d249 offset:int limit:int = messages.Dialogs;
however this has been dropped in TL-schema-53.
I'm guessing you can try one of the other channel.* functions,
I have not tried yet on TL-schema-53
What version of the TL-schema is your TLSharp using?
You could simply implement the relevant functions if they are not yet implemented in your TLSharp version
Not sure if this works 100% without missing any messages, but this is what I have used in one of my projects:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TeleSharp.TL;
using TeleSharp.TL.Channels;
using TeleSharp.TL.Messages;
using TLSharp.Core;
using TLSharp.Core.Utils;
namespace NewsArchive.Telegram
{
/// <summary>
/// Created to be used as a workaround of ref/out since they cannot be used in an async method => GetMessagesInternal
/// </summary>
public class RequestOffset
{
/// <summary>
/// Value of the offset
/// </summary>
public int Id { get; set; }
}
public class TelegramNewsClient
{
#region Properties
private TelegramClient _client;
private int _apiId;
private string _apiHash;
private static readonly int RESULT_MAX = 100;
#endregion
/// <summary>
/// Ctor
/// </summary>
/// <param name="apiId"></param>
/// <param name="apiHash"></param>
public TelegramNewsClient(int apiId, string apiHash)
{
_apiId = apiId;
_apiHash = apiHash;
_client = new TelegramClient(_apiId, _apiHash);
_client.ConnectAsync().Wait();
}
/// <summary>
/// Authenticates the user with the phone number
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
public async Task Authenticate(string phone)
{
var hash = await _client.SendCodeRequestAsync(phone);
var code = "<code_from_telegram>"; // you can change code in debugger
var user = await _client.MakeAuthAsync(phone, hash, code);
}
/// <summary>
/// Gets all messages from a channel
/// </summary>
/// <param name="channelName"></param>
/// <returns></returns>
public async Task<IEnumerable<TLMessage>> GetChannelMessages(string channelName)
{
var messages = new List<TLMessage>();
var channel = await GetChannel(channelName);
if(channel == null)
throw new Exception($"The channel {channelName} was not found!");
var offset = new RequestOffset(){Id = 1};
var internalMessages = new List<TLMessage>();
internalMessages = await GetMessagesInternal(channel.Id, channel.AccessHash.Value, offset);
messages = messages.Concat(internalMessages)
.OrderBy(m => m.Id)
.ToList();
while (internalMessages.Count > 0)
{
/*When you reach the last message, the API will keep returning the same last message over and over again,
that's why we stop making requests and return the result*/
if ((internalMessages.Count == 1 && internalMessages.First().Id == messages.Max(m => m.Id)))
break;
internalMessages = await GetMessagesInternal(channel.Id, channel.AccessHash.Value, offset);
messages = messages.Concat(internalMessages)
.OrderBy(m =>m.Id)
.ToList();
/*if you make too many requests you will be locked out of the API*/
await Task.Delay(TimeSpan.FromSeconds(1));
}
return messages;
}
private async Task<List<TLMessage>> GetMessagesInternal(int channelId, long accessHash, RequestOffset offset)
{
/*Refer to https://core.telegram.org/api/offsets for more info on how to use the offsets.
Here we basically get the last RESULT_MAX (100 in this case) messages newer than the offset.Id aka offsetId*/
var history = await _client.GetHistoryAsync(new TLInputPeerChannel
{
ChannelId = channelId,
AccessHash = accessHash
}, offset.Id, 0, -RESULT_MAX, RESULT_MAX, 0, 0) as TLChannelMessages;
/*Some messages are service messages with no useful content, and if cast to TLMessage it will throw an exception*/
var messages = history.Messages
.Where(m => m is TLMessage)
.Cast<TLMessage>()
.ToList();
/*Get the ID of the last message so it can be used in the next API call*/
offset.Id = messages.Max(m => m.Id);
return messages;
}
private async Task<TLChannel> GetChannel(string channelName)
{
var offset = new RequestOffset() { Id = RESULT_MAX };
var channels = (await _client.GetUserDialogsAsync(0, offset.Id, null, RESULT_MAX) as TLDialogs)
?.Chats
?.Cast<TLChannel>()
?.ToList();
var channel = channels?.FirstOrDefault(c => c.Username.Equals(channelName, StringComparison.OrdinalIgnoreCase));
offset.Id += RESULT_MAX - 1;
while (channels.Count > 0 && channel == null)
{
channels = (await _client.GetUserDialogsAsync(0, offset.Id, null, RESULT_MAX) as TLDialogs)
?.Chats
?.Cast<TLChannel>()
?.ToList();
channel = channels?.FirstOrDefault(c => c.Username.Equals(channelName, StringComparison.OrdinalIgnoreCase));
offset.Id += RESULT_MAX - 1;
/*if you make too many requests you will be locked out of the API*/
await Task.Delay(TimeSpan.FromSeconds(1));
}
return channel;
}
}
}
I found a nice code to down size image on server, to avoid bad image rendering by different browser. This code is for MVC application.
I have no experience in C# would like to know what do I need to change to make this code work in webforms.
<img src="#Url.Action("ResizeImage", "Controller", new { urlImage = "<url_image>", width = 35 })" />
public ActionResult ResizeImage(string imageUrl, int width)
{
WebImage wImage = new WebImage(imageUrl);
wImage = WebImageExtension.Resize(wImage, width);
return File(wImage.GetBytes(), "image/png");
}
public static class WebImageExtension
{
private static readonly IDictionary<string, ImageFormat> TransparencyFormats =
new Dictionary<string, ImageFormat>(StringComparer.OrdinalIgnoreCase) { { "png", ImageFormat.Png }, { "gif", ImageFormat.Gif } };
public static WebImage Resize(this WebImage image, int width)
{
double aspectRatio = (double)image.Width / image.Height;
var height = Convert.ToInt32(width / aspectRatio);
ImageFormat format;
if (!TransparencyFormats.TryGetValue(image.ImageFormat.ToLower(), out format))
{
return image.Resize(width, height);
}
using (Image resizedImage = new Bitmap(width, height))
{
using (var source = new Bitmap(new MemoryStream(image.GetBytes())))
{
using (Graphics g = Graphics.FromImage(resizedImage))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(source, 0, 0, width, height);
}
}
using (var ms = new MemoryStream())
{
resizedImage.Save(ms, format);
return new WebImage(ms.ToArray());
}
}
}
}
UPDATE:
I use this code to resize images
public static void ResizeImageFreeSize(string OriginalFile, string NewFile, int MinWidth, int MinHeight, string FileExtension)
{
var NewHeight = MinHeight;
var NewWidth = MinWidth;
// var OriginalImage = System.Drawing.Image.FromFile(OriginalFile); // THis statlement alon with generate error as file is locked so -->GDI+ keeps a lock on files from which an image was contructed. To avoid the lock, construct the image from a MemorySteam:
MemoryStream ms = new MemoryStream(File.ReadAllBytes(OriginalFile));
var OriginalImage = System.Drawing.Image.FromStream(ms);
if (OriginalImage.Width < MinWidth || OriginalImage.Height < MinHeight)
throw new Exception(String.Format("Invalid Image Dimensions, please upload an image with minmum dimensions of {0}x{1}px", MinWidth.ToString(), MinHeight.ToString()));
// If the image dimensions are the same then make the new dimensions the largest of the two mins.
if (OriginalImage.Height == OriginalImage.Width)
NewWidth = NewHeight = (MinWidth > MinHeight) ? MinWidth : MinHeight;
else
{
if (MinWidth > MinHeight)
NewHeight = (int)(OriginalImage.Height * ((float)MinWidth / (float)OriginalImage.Width));
else
NewWidth = (int)(OriginalImage.Width * ((float)MinHeight / (float)OriginalImage.Height));
}
// Just resample the Original Image into a new Bitmap
var ResizedBitmap = new System.Drawing.Bitmap(OriginalImage, NewWidth, NewHeight);
// Saves the new bitmap in the same format as it's source image
FileExtension = FileExtension.ToLower().Replace(".", "");
ImageFormat Format = null;
switch (FileExtension)
{
case "jpg":
Format = ImageFormat.Jpeg;
Encoder quality = Encoder.Quality;
var ratio = new EncoderParameter(quality, 100L);
var codecParams = new EncoderParameters(1);
codecParams.Param[0] = ratio;
// NewImage.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams);
ResizedBitmap.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams);
break;
case "gif":
Format = ImageFormat.Gif;
ResizedBitmap.Save(NewFile, Format);
break;
case "png":
Format = ImageFormat.Png;
ResizedBitmap.Save(NewFile, Format);
break;
default:
Format = ImageFormat.Png;
ResizedBitmap.Save(NewFile, Format);
break;
}
// ResizedBitmap.Save(NewFile, Format);
// Clear handle to original file so that we can overwrite it if necessary
OriginalImage.Dispose();
ResizedBitmap.Dispose();
}
You can have a HttpHandler for this in C#,
namespace CMSN.Software.Tutorials.HowToDynamicallyResizeImages
{
public class DynamicImage : IHttpHandler
{
/// <summary>
/// Default cache duration
/// </summary>
private static readonly TimeSpan CacheDuration = TimeSpan.FromDays(30);
/// <summary>
/// Gets a value indicating whether another request can use the
/// <see cref="T:System.Web.IHttpHandler"/> instance.
/// </summary>
/// <returns>
/// true if the <see cref="T:System.Web.IHttpHandler"/> instance is reusable; otherwise, false.
/// </returns>
public bool IsReusable
{
get
{
return false;
}
}
/// <summary>
/// Enables processing of HTTP Web requests by a custom HttpHandler that implements the
/// <see cref="T:System.Web.IHttpHandler"/> interface.
/// </summary>
/// <param name="context">An <see cref="T:System.Web.HttpContext"/> object that provides references to the
/// intrinsic server objects (for example, Request, Response, Session, and Server)
/// used to service HTTP requests.
/// </param>
public void ProcessRequest(HttpContext context)
{
string cacheKeyName = context.Request.Url.PathAndQuery;
string imagePath = context.Server.MapPath(context.Request.Url.LocalPath);
string imageExtention = Path.GetExtension(imagePath);
string contentType = string.Empty;
byte[] imageFileContent;
ImageFormat imageFormat = null;
switch (imageExtention)
{
case ".png":
imageFormat = ImageFormat.Png;
contentType = "image/png";
break;
case ".jpg":
case ".jpeg":
case ".jpe":
imageFormat = ImageFormat.Jpeg;
contentType = "image/jpeg";
break;
case ".bmp":
imageFormat = ImageFormat.Bmp;
contentType = "image/bmp";
break;
case ".gif":
imageFormat = ImageFormat.Gif;
contentType = "image/gif";
break;
default:
break;
}
context.Response.ContentType = contentType;
if (context.Cache[CacheKey(cacheKeyName)] != null)
{
imageFileContent = context.Cache[CacheKey(cacheKeyName)] as byte[];
}
else
{
int imageWidth = 0;
int imageHeight = 0;
if (!string.IsNullOrEmpty(context.Request["w"]))
{
if (!int.TryParse(context.Request["w"], out imageWidth))
{
imageWidth = 0;
}
}
if (!string.IsNullOrEmpty(context.Request["h"]))
{
if (!int.TryParse(context.Request["h"], out imageHeight))
{
imageHeight = 0;
}
}
Image originalImage;
if (File.Exists(imagePath))
{
originalImage = Image.FromFile(imagePath);
}
else
{
originalImage = new Bitmap(100, 100);
}
if (imageWidth > 0 || imageHeight > 0)
{
if (imageHeight == 0 && imageWidth > 0)
{
imageHeight = originalImage.Height * imageWidth / originalImage.Width;
}
if (imageWidth == 0 && imageHeight > 0)
{
imageWidth = originalImage.Width * imageHeight / originalImage.Height;
}
}
else
{
imageHeight = originalImage.Height;
imageWidth = originalImage.Width;
}
using (Bitmap newImage = new Bitmap(originalImage, imageWidth, imageHeight))
{
Graphics generatedImage = Graphics.FromImage(newImage);
generatedImage.InterpolationMode = InterpolationMode.HighQualityBicubic;
generatedImage.SmoothingMode = SmoothingMode.AntiAlias;
generatedImage.CompositingQuality = CompositingQuality.HighQuality;
generatedImage.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);
// make a memory stream to work with the image bytes
using (MemoryStream imageStream = new MemoryStream())
{
// put the image into the memory stream
newImage.Save(imageStream, imageFormat);
// make byte array the same size as the image
byte[] imageContent = new byte[imageStream.Length];
// rewind the memory stream
imageStream.Position = 0;
// load the byte array with the image
imageStream.Read(imageContent, 0, (int)imageStream.Length);
// return byte array to caller with image type
imageFileContent = imageContent;
using (CacheDependency dependency = new CacheDependency(imagePath))
{
context.Cache.Insert(
CacheKey(cacheKeyName),
imageContent,
dependency,
System.Web.Caching.Cache.NoAbsoluteExpiration,
CacheDuration);
}
}
}
originalImage.Dispose();
}
SetResponseCache(context.Response, new string[1] { imagePath });
context.Response.BinaryWrite(imageFileContent);
}
/// <summary>
/// Generate unique Cache key.
/// </summary>
/// <param name="key">The cache key.</param>
/// <returns>Generated unique Cache key</returns>
protected static string CacheKey(string key)
{
return "DynamicImage." + key;
}
/// <summary>
/// Sets the response cache.
/// </summary>
/// <param name="response">The response.</param>
/// <param name="files">The files.</param>
protected static void SetResponseCache(HttpResponse response, string[] files)
{
response.AddFileDependencies(files);
HttpCachePolicy browserCache = response.Cache;
DateTime modifiedTime = DateTime.Now;
browserCache.SetCacheability(HttpCacheability.ServerAndPrivate);
browserCache.VaryByParams["w"] = true;
browserCache.VaryByParams["h"] = true;
browserCache.VaryByParams["v"] = true;
browserCache.SetOmitVaryStar(true);
browserCache.SetExpires(modifiedTime.AddDays(7));
browserCache.SetValidUntilExpires(true);
browserCache.SetLastModified(modifiedTime);
browserCache.SetETagFromFileDependencies();
browserCache.SetLastModifiedFromFileDependencies();
}
}
}
Web.config
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpHandlers>
<add verb="*" path="*.png,*.jpg,*.jpeg,*.gif,*.bmp" type="CMSN.Software.Tutorials.HowToDynamicallyResizeImages.DynamicImage,HowToDynamicallyResizeImages"/>
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<add verb="*" path="*.png,*.jpg,*.jpeg,*.gif,*.bmp" name="DynamicImage" type="CMSN.Software.Tutorials.HowToDynamicallyResizeImages.DynamicImage,HowToDynamicallyResizeImages"/>
</handlers>
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
</configuration>
Usage,
http://localhost/Images/xxxxxxxx.png?w=300&h=149
If you want to see the complete guide for this, please follow the following URL.
http://tutorials.cmsnsoftware.com/2011/09/how-to-dynamically-resize-images.html
I need to see the contents of the viewstate of an asp.net page. I looked for a viewstate decoder, found Fridz Onion's ViewState Decoder but it asks for the url of a page to get its viewstate. Since my viewstate is formed after a postback and comes as a result of an operation in an update panel, I cannot provide a url. I need to copy & paste the viewstate string and see what's inside. Is there a tool or a website exist that can help viewing the contents of viewstate?
Here's an online ViewState decoder:
http://ignatu.co.uk/ViewStateDecoder.aspx
Edit: Unfortunatey, the above link is dead - here's another ViewState decoder (from the comments):
http://viewstatedecoder.azurewebsites.net/
Use Fiddler and grab the view state in the response and paste it into the bottom left text box then decode.
Here is the source code for a ViewState visualizer from Scott Mitchell's article on ViewState (25 pages)
using System;
using System.Collections;
using System.Text;
using System.IO;
using System.Web.UI;
namespace ViewStateArticle.ExtendedPageClasses
{
/// <summary>
/// Parses the view state, constructing a viaully-accessible object graph.
/// </summary>
public class ViewStateParser
{
// private member variables
private TextWriter tw;
private string indentString = " ";
#region Constructor
/// <summary>
/// Creates a new ViewStateParser instance, specifying the TextWriter to emit the output to.
/// </summary>
public ViewStateParser(TextWriter writer)
{
tw = writer;
}
#endregion
#region Methods
#region ParseViewStateGraph Methods
/// <summary>
/// Emits a readable version of the view state to the TextWriter passed into the object's constructor.
/// </summary>
/// <param name="viewState">The view state object to start parsing at.</param>
public virtual void ParseViewStateGraph(object viewState)
{
ParseViewStateGraph(viewState, 0, string.Empty);
}
/// <summary>
/// Emits a readable version of the view state to the TextWriter passed into the object's constructor.
/// </summary>
/// <param name="viewStateAsString">A base-64 encoded representation of the view state to parse.</param>
public virtual void ParseViewStateGraph(string viewStateAsString)
{
// First, deserialize the string into a Triplet
LosFormatter los = new LosFormatter();
object viewState = los.Deserialize(viewStateAsString);
ParseViewStateGraph(viewState, 0, string.Empty);
}
/// <summary>
/// Recursively parses the view state.
/// </summary>
/// <param name="node">The current view state node.</param>
/// <param name="depth">The "depth" of the view state tree.</param>
/// <param name="label">A label to display in the emitted output next to the current node.</param>
protected virtual void ParseViewStateGraph(object node, int depth, string label)
{
tw.Write(System.Environment.NewLine);
if (node == null)
{
tw.Write(String.Concat(Indent(depth), label, "NODE IS NULL"));
}
else if (node is Triplet)
{
tw.Write(String.Concat(Indent(depth), label, "TRIPLET"));
ParseViewStateGraph(((Triplet) node).First, depth+1, "First: ");
ParseViewStateGraph(((Triplet) node).Second, depth+1, "Second: ");
ParseViewStateGraph(((Triplet) node).Third, depth+1, "Third: ");
}
else if (node is Pair)
{
tw.Write(String.Concat(Indent(depth), label, "PAIR"));
ParseViewStateGraph(((Pair) node).First, depth+1, "First: ");
ParseViewStateGraph(((Pair) node).Second, depth+1, "Second: ");
}
else if (node is ArrayList)
{
tw.Write(String.Concat(Indent(depth), label, "ARRAYLIST"));
// display array values
for (int i = 0; i < ((ArrayList) node).Count; i++)
ParseViewStateGraph(((ArrayList) node)[i], depth+1, String.Format("({0}) ", i));
}
else if (node.GetType().IsArray)
{
tw.Write(String.Concat(Indent(depth), label, "ARRAY "));
tw.Write(String.Concat("(", node.GetType().ToString(), ")"));
IEnumerator e = ((Array) node).GetEnumerator();
int count = 0;
while (e.MoveNext())
ParseViewStateGraph(e.Current, depth+1, String.Format("({0}) ", count++));
}
else if (node.GetType().IsPrimitive || node is string)
{
tw.Write(String.Concat(Indent(depth), label));
tw.Write(node.ToString() + " (" + node.GetType().ToString() + ")");
}
else
{
tw.Write(String.Concat(Indent(depth), label, "OTHER - "));
tw.Write(node.GetType().ToString());
}
}
#endregion
/// <summary>
/// Returns a string containing the <see cref="IndentString"/> property value a specified number of times.
/// </summary>
/// <param name="depth">The number of times to repeat the <see cref="IndentString"/> property.</param>
/// <returns>A string containing the <see cref="IndentString"/> property value a specified number of times.</returns>
protected virtual string Indent(int depth)
{
StringBuilder sb = new StringBuilder(IndentString.Length * depth);
for (int i = 0; i < depth; i++)
sb.Append(IndentString);
return sb.ToString();
}
#endregion
#region Properties
/// <summary>
/// Specifies the indentation to use for each level when displaying the object graph.
/// </summary>
/// <value>A string value; the default is three blank spaces.</value>
public string IndentString
{
get
{
return indentString;
}
set
{
indentString = value;
}
}
#endregion
}
}
And here's a simple page to read the viewstate from a textbox and graph it using the above code
private void btnParse_Click(object sender, System.EventArgs e)
{
// parse the viewState
StringWriter writer = new StringWriter();
ViewStateParser p = new ViewStateParser(writer);
p.ParseViewStateGraph(txtViewState.Text);
ltlViewState.Text = writer.ToString();
}
As another person just mentioned, it's a base64 encoded string. In the past, I've used this website to decode it:
http://www.motobit.com/util/base64-decoder-encoder.asp
JavaScript-ViewState-Parser:
http://mutantzombie.github.com/JavaScript-ViewState-Parser/
https://github.com/mutantzombie/JavaScript-ViewState-Parser/
The parser should work with most non-encrypted ViewStates. It doesn’t
handle the serialization format used by .NET version 1 because that
version is sorely outdated and therefore too unlikely to be
encountered in any real situation.
http://deadliestwebattacks.com/2011/05/29/javascript-viewstate-parser/
Parsing .NET ViewState
A Spirited Peek into ViewState, Part I:
http://deadliestwebattacks.com/2011/05/13/a-spirited-peek-into-viewstate-part-i/
A Spirited Peek into ViewState, Part II:
http://deadliestwebattacks.com/2011/05/25/a-spirited-peek-into-viewstate-part-ii/
Here's another decoder that works well as of 2014: http://viewstatedecoder.azurewebsites.net/
This worked on an input on which the Ignatu decoder failed with "The serialized data is invalid" (although it leaves the BinaryFormatter-serialized data undecoded, showing only its length).
This is somewhat "native" .NET way of converting ViewState from string into StateBag
Code is below:
public static StateBag LoadViewState(string viewState)
{
System.Web.UI.Page converterPage = new System.Web.UI.Page();
HiddenFieldPageStatePersister persister = new HiddenFieldPageStatePersister(new Page());
Type utilClass = typeof(System.Web.UI.BaseParser).Assembly.GetType("System.Web.UI.Util");
if (utilClass != null && persister != null)
{
MethodInfo method = utilClass.GetMethod("DeserializeWithAssert", BindingFlags.NonPublic | BindingFlags.Static);
if (method != null)
{
PropertyInfo formatterProperty = persister.GetType().GetProperty("StateFormatter", BindingFlags.NonPublic | BindingFlags.Instance);
if (formatterProperty != null)
{
IStateFormatter formatter = (IStateFormatter)formatterProperty.GetValue(persister, null);
if (formatter != null)
{
FieldInfo pageField = formatter.GetType().GetField("_page", BindingFlags.NonPublic | BindingFlags.Instance);
if (pageField != null)
{
pageField.SetValue(formatter, null);
try
{
Pair pair = (Pair)method.Invoke(null, new object[] { formatter, viewState });
if (pair != null)
{
MethodInfo loadViewState = converterPage.GetType().GetMethod("LoadViewStateRecursive", BindingFlags.Instance | BindingFlags.NonPublic);
if (loadViewState != null)
{
FieldInfo postback = converterPage.GetType().GetField("_isCrossPagePostBack", BindingFlags.NonPublic | BindingFlags.Instance);
if (postback != null)
{
postback.SetValue(converterPage, true);
}
FieldInfo namevalue = converterPage.GetType().GetField("_requestValueCollection", BindingFlags.NonPublic | BindingFlags.Instance);
if (namevalue != null)
{
namevalue.SetValue(converterPage, new NameValueCollection());
}
loadViewState.Invoke(converterPage, new object[] { ((Pair)((Pair)pair.First).Second) });
FieldInfo viewStateField = typeof(Control).GetField("_viewState", BindingFlags.NonPublic | BindingFlags.Instance);
if (viewStateField != null)
{
return (StateBag)viewStateField.GetValue(converterPage);
}
}
}
}
catch (Exception ex)
{
if (ex != null)
{
}
}
}
}
}
}
}
return null;
}
You can ignore the URL field and simply paste the viewstate into the Viewstate string box.
It does look like you have an old version; the serialisation methods changed in ASP.NET 2.0, so grab the 2.0 version
Best way in python is use this link.
A small Python 3.5+ library for decoding ASP.NET viewstate.
First install that: pip install viewstate
>>> from viewstate import ViewState
>>> base64_encoded_viewstate = '/wEPBQVhYmNkZQ9nAgE='
>>> vs = ViewState(base64_encoded_viewstate)
>>> vs.decode()
('abcde', (True, 1))
Online Viewstate Viewer made by Lachlan Keown:
http://lachlankeown.blogspot.com/2008/05/online-viewstate-viewer-decoder.html
Normally, ViewState should be decryptable if you have the machine-key, right? After all, ASP.net needs to decrypt it, and that is certainly not a black box.