Using MultipartContent - IOException: Unable to read data from the transport connection - c#

I receive this error when send post form-data to another api, with HttpClient :
I have this parameters on another api controller:
public class IntegracaoArquivosDigitaisDto
{
/// <summary>
/// IdInteral do arquivo digital
/// </summary>
/// <example>1</example>
public int IdInternalArquivoDigital { get; set; }
/// <summary>
/// Chave do Módulo
/// </summary>
/// <example>
/// RecursosHumanos
/// </example>
public string ChaveModulo { get; set; }
/// <summary>
/// Versão do Módulo
/// </summary>
/// <example>
/// 1.6
/// </example>
public int? Versao { get; set; }
/// <summary>
/// Versão dos Dados enviados para processamento
/// </summary>
/// <example>
/// c8283005-68f5-41bf-aea6-29496068656c
/// </example>
public Guid IdProcessamento { get; set; }
/// <summary>
/// Colunas chaves
/// </summary>
public List<PayloadDTO> ColunasChaves { get; set; }
/// <summary>
/// Tipo de operação - I,A,E
/// </summary>
/// <example>1</example>
public string TipoOperacao { get; set; }
/// <summary>
/// Id arquivo Digital
/// </summary>
/// <example>1</example>
public string IdArquivoDigital { get; set; }
/// <summary>
/// Nome Arquivo
/// </summary>
/// <example>teste.pdf</example>
public string NomeArquivoDigital { get; set; }
/// <summary>
/// Arquivo
/// </summary>
public IFormFile Arquivo { get; set; }
}
public class PayloadDTO
{
/// <summary>
/// Nome do campo
/// </summary>
/// <example>
/// Cidade
/// </example>
public string Campo { get; set; }
/// <summary>
/// Valor representativo do campo
/// </summary>
/// <example>José da Silva</example>
public string Valor { get; set; }
/// <summary>
/// Tipo do dado
/// </summary>
/// <example>int</example>
public string Tipo { get; set; }
}
And I this is controller :
[HttpPost]
public async Task<IActionResult> Teste([FromForm] IntegracaoArquivosDigitaisDto dto)
{
var json = JsonSerializer.Serialize(dto, new JsonSerializerOptions
{
WriteIndented = true,
});
return Ok(json);
}
I try using StringContent, Json , FormUrlEncodedContent And MultipartFormDataContent, but not working.
What is the correct way to make a post form-data using httpClient, with these parameters?
This is my implementation tests :
[HttpGet]
public async Task<IActionResult> Get()
{
string url = "http://localhost:5001/teste";
using (MultipartFormDataContent formDataContent = new MultipartFormDataContent())
{
var obj = new
{
IdInternalArquivoDigital = 3,
ChaveModulo = "RecursosHumanos",
Versao = 3,
IdProcessamento = Guid.NewGuid(),
ColunasChaves = new List<PayloadDTO>{
new PayloadDTO{
Campo="CdCategoria",
Tipo= "int",
Valor= "32",
},
new PayloadDTO{
Campo="Id",
Tipo= "int",
Valor= "3",
},
new PayloadDTO{
Campo="Nome",
Tipo= "strig",
Valor= "Samuel",
},
},
TipoOperacao = "I",
IdArquivoDigital = Guid.NewGuid().ToString(),
NomeArquivoDigital = "a7x.jg",
};
var json = JsonSerializer.Serialize(obj, new JsonSerializerOptions { WriteIndented = true, });
//json content
// var jsonContent = new StringContent(json);
// jsonContent.Headers.ContentType = new MediaTypeHeaderValue("application/json")
// {
// CharSet = "utf-8"
// };
// Dictionary<string, string> dic = new Dictionary<string, string>();
// dic.Add(nameof(IntegracaoArquivosDigitaisDto.Versao), obj.Versao.ToString());
// dic.Add(nameof(IntegracaoArquivosDigitaisDto.IdArquivoDigital), obj.IdArquivoDigital.ToString());
// dic.Add(nameof(IntegracaoArquivosDigitaisDto.IdInternalArquivoDigital), obj.IdInternalArquivoDigital.ToString());
// dic.Add(nameof(IntegracaoArquivosDigitaisDto.IdProcessamento), obj.IdProcessamento.ToString());
// dic.Add(nameof(IntegracaoArquivosDigitaisDto.ChaveModulo), obj.ChaveModulo);
// dic.Add(nameof(IntegracaoArquivosDigitaisDto.NomeArquivoDigital), obj.NomeArquivoDigital);
// dic.Add(nameof(IntegracaoArquivosDigitaisDto.TipoOperacao), obj.TipoOperacao);
// formDataContent.Add(new FormUrlEncodedContent(dic), "dto");
// formDataContent.Add(new StringContent(obj.Versao.ToString()), nameof(IntegracaoArquivosDigitaisDto.Versao));
// formDataContent.Add(new StringContent(obj.IdArquivoDigital.ToString()), nameof(IntegracaoArquivosDigitaisDto.IdArquivoDigital));
// formDataContent.Add(new StringContent(obj.IdInternalArquivoDigital.ToString()), nameof(IntegracaoArquivosDigitaisDto.IdInternalArquivoDigital));
// formDataContent.Add(new StringContent(obj.IdProcessamento.ToString()), nameof(IntegracaoArquivosDigitaisDto.IdProcessamento));
// formDataContent.Add(new StringContent(obj.NomeArquivoDigital), nameof(IntegracaoArquivosDigitaisDto.NomeArquivoDigital));
// formDataContent.Add(new StringContent(obj.TipoOperacao), nameof(IntegracaoArquivosDigitaisDto.TipoOperacao));
// formDataContent.Add(new StringContent(obj.ColunasChaves.ToString()), nameof(IntegracaoArquivosDigitaisDto.ColunasChaves));
// formDataContent.Add(new StringContent(obj.ChaveModulo), nameof(IntegracaoArquivosDigitaisDto.ChaveModulo));
formDataContent.Add(new MultipartFormDataContent(obj.ChaveModulo), nameof(IntegracaoArquivosDigitaisDto.ChaveModulo));
string caminhoArquivo = #"C:\Users\samue\OneDrive\Imagens\a7x.jpg";
using (var fileStream = new FileStream(caminhoArquivo, FileMode.Open))
{
try
{
using (MemoryStream ms = new MemoryStream())
{
await fileStream.CopyToAsync(ms);
var bytes = ms.ToArray();
var fileContent = new ByteArrayContent(bytes);
//file content
// fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
// {
// FileName = "a7x.jpg"
// .Replace("(", string.Empty)
// .Replace(")", string.Empty)
// .Replace(" ", string.Empty),
// Name = "arquivo",
// };
formDataContent.Add(fileContent, nameof(IntegracaoArquivosDigitaisDto.Arquivo), "a7x.jpg");
_client.Timeout = TimeSpan.FromMinutes(2);
var res = await _client.PostAsync(url, formDataContent);
res.EnsureSuccessStatusCode();
}
}
catch (System.Exception ex) when (ex is HttpRequestException || ex is OperationCanceledException)
{
throw;
}
}
}
return Ok();
}

Related

System.InvalidOperationException : <LicenseBase xmlns=''> was not expected

I try to serialize and deserialize the class License.
The serialization work well but when I try to deserialize the file
I get the error message above.
This is the base class:
[Serializable]
public abstract class LicenseBase
{
/// <summary>
/// Initializes a new instance of the <see cref="LicenseBase"/> class.
/// </summary>
protected LicenseBase()
{
ApplicationName = string.Empty;
UniqueId = string.Empty;
}
/// <summary>
/// Application name this license is used for
/// </summary>
[Browsable(false)]
public string ApplicationName { get; set; }
/// <summary>
/// Unique hardware id this license will work on
/// </summary>
[Browsable(false)]
public string UniqueId { get; set; }
}
And this the derived:
public class License : LicenseBase
{
[Browsable(false)]
public bool Test { get; set; }
}
This is the method to serialize the class:
public void WriteLicense<T>(T license) where T : LicenseBase
{
if (license is null)
{
throw new ArgumentNullException(nameof(license));
}
//Serialize license object into XML
XmlDocument licenseObject = new XmlDocument();
using (StringWriter writer = new StringWriter())
{
XmlSerializer serializer = new XmlSerializer(typeof(LicenseBase), new[]
{
license.GetType(), typeof(License)
});
serializer.Serialize(writer, license);
licenseObject.LoadXml(writer.ToString());
}
//Sign the XML
SignXml(licenseObject);
//Convert the signed XML into BASE64 string
string writeToFile = Convert.ToBase64String(Encoding.UTF8.GetBytes(licenseObject.OuterXml));
File.WriteAllText(LICENSE_FILENAME, writeToFile);
}
This is the code to read the class:
public T ReadLicense<T>() where T : LicenseBase
{
T license;
if (!File.Exists(LICENSE_FILENAME))
{
alarmManager.ReportAlarm(licenseFileMissingAlarm, true, true);
return null;
}
string licenseFileData = File.ReadAllText(LICENSE_FILENAME);
XmlDocument xmlDoc = new XmlDocument { PreserveWhitespace = true };
xmlDoc.LoadXml(Encoding.UTF8.GetString(Convert.FromBase64String(licenseFileData)));
// Verify the signature of the signed XML.
if (VerifyXml(xmlDoc, PrivateKey))
{
XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
if (xmlDoc.DocumentElement != null)
{
_ = xmlDoc.DocumentElement.RemoveChild(nodeList[0]);
}
string licenseContent = xmlDoc.OuterXml;
//Deserialize license
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader reader = new StringReader(licenseContent))
{
license = (T)serializer.Deserialize(reader);
}
}
else
{
license = null;
}
return license;
}
The content of licenseContent is
<?xml version="1.0" encoding="UTF-8"?>
<LicenseBase xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="License">
<ApplicationName>Test</ApplicationName>
<UniqueId>c4aed5a8-8d22-47b0-bda4-700ac906bfd5</UniqueId>
<Test>true</Test>
</LicenseBase>
I solve the problem this was the failure;
XmlSerializer serializer = new XmlSerializer(typeof(LicenseBase), new[]
{
license.GetType(), typeof(License)
});
And this the solution:
XmlSerializer serializer = new XmlSerializer(license.GetType(), new[]
{
license.GetType()
});
After this changes everything work fine.

Using Reflection to create extensible charts for a website

I’m trying to implement a website where new charts can be added by just dropping a DLL into folder. At the time of writing it is not clear what charts are going to be needed and this provides a simple way of deploying new charts without having to redeploy the website in its entirety. I’m using Google Charts to provide the Google functionality and each chart will be displayed
Each type of chart inherits from the following Interface
public enum ChartType
{
BAR,
COLUMN,
PIE,
TABLE
}
public class DataColumn
{
public String ColumnType { get; set; }
public String ColumnValue { get; set; }
}
public interface IChart
{
/// <summary>
/// Dictionary of Columns, Each column is defined as a type and title
/// </summary>
List<DataColumn> Columns { get; set; }
/// <summary>
/// ChartType, What type of Chart; possible values BAR, COLUMN, PIE, TABLE
/// </summary>
ChartType ChartType { get; }
/// <summary>
/// Data - data for the chart
/// </summary>
String Data { get; }
/// <summary>
/// Name of the chart, must be unique used to identify each chart stub
/// </summary>
String Name { get; }
/// <summary>
/// Title - the title that will be displayed above the chart
/// </summary>
String Title { get; }
/// <summary>
/// What position will the legend of there is one.
/// </summary>
String LegendPosition { get; }
}
The following uses the above interface
public class ReferralDownloadCount : IChart, IDisposable
{
List<ChartDemo.DataColumn> columns = null;
public ReferralDownloadCount()
{
columns = new List<ChartDemo.DataColumn>()
{
new ChartDemo.DataColumn() { ColumnType = "String" , ColumnValue = "Date" },
new ChartDemo.DataColumn() { ColumnType = "Number" , ColumnValue = "Referral Count"}
};
}
/// <summary>
/// Returns the chart data
/// </summary>
public String Data
{
get
{
String sql = String.Empty;
String jsonResult = String.Empty;
DataSet ds = null;
DataTable dt = null;
List<ReferralCountData> results = null;
JsonSerializer serializer = null;
try
{
sql = "Select * From[Portal].[ReferralCount] Where DATEDIFF(d, [Download Date], Convert(Date, GETDATE())) < 8 Order By[Download Date] Asc";
ds = DataToolbox.Execute(new SqlConnection(Properties.Settings.Default.DataConnection), sql, CommandType.Text);
if (ds.Tables.Count > 0)
{
dt = ds.Tables[0]; // we really are only expecting one table
results = new List<ReferralCountData>();
serializer = new JsonSerializer();
serializer.Converters.Add(new JavaScriptDateTimeConverter());
foreach ( DataRow dr in dt.Rows)
{
using (ReferralCountData rcd = new ReferralCountData()
{
Label = ((System.DateTime)dr.ItemArray[0]).ToString("dd/MM/yyyy"),
Value = Convert.ToInt32(dr["Referral Count"])
})
{
results.Add(rcd);
}
}
jsonResult = JsonConvert.SerializeObject(results);
}
}
catch ( System.Exception ex)
{
throw ex;
}
finally
{
}
return jsonResult;
}
}
public List<ChartDemo.DataColumn> Columns {
get
{
return columns;
}
set
{
columns = value;
}
}
public ChartType ChartType => ChartType.COLUMN;
public string Name => "REFERRALCOUNT";
public string Title => "Referral Download Count";
public string LegendPosition => "None";
public void Dispose()
{
}
}
The site traverses a directory containing DLLs, and searches for any classes such as the one above to create Charts
Classes which have inherited from IChart are then extracted as each DLL is checked by GetChartPlugins
static List<IChart> GetChartPlugins(List<Assembly> assemblies)
{
List<Type> availableTypes = new List<Type>();
List<Type> alertList = null;
try
{
foreach (Assembly currentAssembly in assemblies)
availableTypes.AddRange(currentAssembly.GetTypes());
alertList = availableTypes.FindAll(delegate (Type t)
{
List<Type> interfaceTypes = new List<Type>(t.GetInterfaces());
return interfaceTypes.Contains(typeof(IChart));
});
}
catch (ReflectionTypeLoadException ex)
{
StringBuilder sb = new StringBuilder();
foreach (Exception exSub in ex.LoaderExceptions)
{
sb.AppendLine(exSub.Message);
FileNotFoundException exFileNotFound = exSub as FileNotFoundException;
if (exFileNotFound != null)
{
if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
{
sb.AppendLine("Fusion Log:");
sb.AppendLine(exFileNotFound.FusionLog);
}
}
sb.AppendLine();
}
string errorMessage = sb.ToString();
}
catch ( System.Exception ex)
{
throw ex;
}
finally
{
}
// convert the list of Objects to an instantiated list of ICalculators
return alertList.ConvertAll<IChart>(delegate (Type t) { return Activator.CreateInstance(t) as IChart; });
}
However when this runs the attempt to Call currentAssembly.GetTypes() falls over throwing a ReflectionTypeLoadException
Which eventually becomes;
Method 'get_Columns' in type 'ReferralManagementCharts.ReferralDownloadCount' from assembly 'ReferralManagementCharts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
Can anyone see why since the Columns property of ReferralDownlodCount
public List<ChartDemo.DataColumn> Columns {
get
{
return columns;
}
set
{
columns = value;
}
}
Does have a get.

Create default config for each tenant in C#

I have basic CRUD for a class ConfigSystem.
I have also two methods in the basic ConfigSystem Service.
public Type Get<Type>(string key, string userId)
{
//get config system
var configEntry = this.repository.GetSingleAsync(cs => cs.Key == key && cs.UserId == userId).Await();
if (configEntry == null)
{
configEntry = this.repository.GetSingleAsync(cs => cs.Key == key).Await();
}
if (typeof(Type).Name == configEntry.Type)
{
return JsonConvert.DeserializeObject<Type>(configEntry.Value);
//invalid config type exception
}
else
{
throw new InvalidCastException($"Cannot get the type of this particular key! ");
}
}
public async Task Set<T>(string key, string userId, T value)
{
CheckKey(key, userId);
// find key and then update its value
var configEntry = await this.repository.GetSingleAsync(cs => cs.Key == key && cs.UserId == userId);
//configEntry.Key = key;
if (configEntry == null)
{
configEntry = await this.repository.GetSingleAsync(cs => cs.Key == key);
}
configEntry.Type = value.GetType().Name;
configEntry.Value = JsonConvert.SerializeObject(value);
await this.repository.UpdateAsync(configEntry);
}
I have a static file Config:
public static Dictionary<string, object> ConfigurationList = new Dictionary<string, object>()
{
{"Currency", Enums.Currency.Lev },
{"Measure", Enums.Unit.LinearMetre },
{"DailyDraftLimit", 6},
{"DeleteDraftPeriod", 5},
{"NotificationStartTime", new TimeSpan(03, 00, 00) }, //give exact time 3AM.},
//TODO: Exclude weekends
{"NotificationPeriod", 24},//24 hours
{"PaymentNotificationPeriod", 24},
{"PaymentReceivers", null}, //what do I put here? if I dont have the ids/ -> we put null if we are not sure about the info or the info is not static!
{"VisitsNotificationPeriod", 24},
{"VisitsInternalReceivers", null},
{"VisitsExternalReceivers", null},
{"TermsNotificationPeriod", 24},
{"TermsReceivers", null }
}
and this is my ConfigSystem class:
public class ConfigSystem : AuditEntity<long>
{
/// <summary>
/// Gets or sets the key.
/// </summary>
public string Key { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
public string Type { get; set; }
/// <summary>
/// Gets or sets the value.
/// </summary>
public string Value { get; set; }
/// <summary>
/// Gets or sets the user identifier.
/// </summary>
public string UserId { get; set; }
}
This is my method in the Startup.
private void CreateDefaultConfig(ApplicationDbContext context, IServiceScope serviceScope)
{
var defaultConfig = DefaultTenantConfig.ConfigurationList;
if (context.ConfigSystems.Count() == 0)
{
var configSystemService = serviceScope.ServiceProvider.GetRequiredService<IConfigSystemService>();
//foreach (var entry in defaultConfig)
//{
// var entityToSaveInDb = configSystemService.CreateAsync()
//}
//create for each record a config system entry in the database
}
//check if in the context of the database there are no configs
}
I have no idea what to do with the object, but I had to keep it in object because I had different type of entries. I need to create them for each tenant and it is a default config if they are not created in the database.

How to add RestSharp Response to API Controller?

I've created an ASP.NET Core API solution that uses RestSharp to send data to a third party API and return results back to my API and database. On my API, I want to return the results of the RestSharp call as part of my controller class so that my DNN site can consume the RestSharp Responses. How do I return the responses obtained from the third party API in my controller class?
My RestSharp logic is as follows:
/// <summary>
/// Executes a particular http request to a resource.
/// </summary>
/// <typeparam name="T">The response type.</typeparam>
/// <param name="request">The REST request.</param>
/// <param name="baseUrl">The base URL.</param>
/// <returns>Returns a response of the type parameter.</returns>
private static T Execute<T>(IRestRequest request, string baseUrl) where T : class, new()
{
baseUrl = "https://xmltest.propay.com/api/propayapi/PropayMerchantService.svc/";
var client = new RestClient(baseUrl);
var response = client.Execute<T>(request);
if (response.ErrorException != null)
{
Console.WriteLine(
"Error: Exception: {0}, Headers: {1}, Content: {2}, Status Code: {3}",
response.ErrorException,
response.Headers,
response.Content,
response.StatusCode);
}
return response.Data;
}
public static ProPayResponse MerchantSignUpForProPay()
{
var baseUrl = "https://xmltest.propay.com/api/propayapi/PropayMerchantService.svc/";
var request = BuildMerchantTestData();
var restRequest = CreateRestRequest("/Signup", Method.PUT);
restRequest.AddJsonBody(request);
return Execute<ProPayResponse>(restRequest, baseUrl);
}
/// <summary>
/// Builds the merchant request data.
/// </summary>
/// <returns>The request data.</returns>
private static SignUpRequest BuildMerchantTestData()
{
var onboarding = new Onboarding();
var signUpRequest = new SignUpRequest();
var userid = "userId";
var email = userid + "#test.com";
using (SOBOContext context = new SOBOContext())
{
var signupRequest = new SignUpRequest
{
SignupAccountData = new SignupAccountData
{
ExternalId = "12345",
Tier = onboarding.AverageTicket.ToString(),
CurrencyCode = "USD",
PhonePIN = onboarding.PhonePin,
UserId = onboarding.UserName
},
Address =
new Address
{
Address1 = onboarding.Address1Line1,
Address2 = onboarding.Address1Line1,
ApartmentNumber = " ",
City = onboarding.Address1City,
State = onboarding.Address1State,
Country = onboarding.Address1Country,
Zip = onboarding.Address1ZipCode
},
BusinessAddress =
new Address
{
Address1 = onboarding.BusinessAddressLine1,
Address2 = onboarding.BusinessAddressLine2,
ApartmentNumber = " ",
City = onboarding.BusinessCity,
State = onboarding.BusinessState,
Country = onboarding.BusinessCountry,
Zip = onboarding.BusinessZipCode
},
MailAddress = new Address { Address1 = onboarding.OwnerAddress, City = onboarding.OwnerCity, State = onboarding.OwnerRegion, Country = onboarding.OwnerCountry, Zip = onboarding.OwnerZipCode },
BankAccount =
new BankAccount
{
AccountCountryCode = onboarding.BankAccount1CountryCode,
AccountType = onboarding.BankAccount1Type,
AccountOwnershipType = onboarding.BankAccount1OwnershipType,
BankAccountNumber = onboarding.BankAccount1Number,
BankName = onboarding.BankAccount1BankName,
RoutingNumber = onboarding.BankAccount1RoutingNumber
},
SecondaryBankAccount =
new BankAccount
{
AccountCountryCode = onboarding.BankAccount2CountryCode,
AccountType = onboarding.BankAccount2Type,
AccountOwnershipType = onboarding.BankAccount2OwnershipType,
BankAccountNumber = onboarding.BankAccount2Number,
BankName = onboarding.BankAccount2BankName,
RoutingNumber = onboarding.BankAccount2RoutingNumber
},
BusinessData =
new BusinessData
{
BusinessLegalName = onboarding.BusinessLegalName,
DoingBusinessAs = onboarding.DoingBusinessAs,
EIN = onboarding.Ein,
},
CreditCardData = new CreditCardData
{
CreditCardNumber = onboarding.CreditCardNumber, // test card number
ExpirationDate = onboarding.ExpirationDate
},
PersonalData =
new PersonalData
{
DateOfBirth = onboarding.DateOfBirth.ToString(),
SourceEmail = onboarding.Email,
SocialSecurityNumber = onboarding.Ssn,
FirstName = onboarding.FirstName,
LastName = onboarding.Lastname,
MiddleInitial = onboarding.MiddleInitial,
PhoneInformation =
new PhoneInformation { DayPhone = onboarding.DayPhone, EveningPhone = onboarding.EveningPhone }
}
};
context.SaveChangesAsync();
return signupRequest;
}
}
/// <summary>
/// Request factory to ensure API key is always first parameter added.
/// </summary>
/// <param name="resource">The resource name.</param>
/// <param name="method">The HTTP method.</param>
/// <returns>Returns a new <see cref="RestRequest"/>.</returns>
private static RestRequest CreateRestRequest(string resource, Method method)
{
var credentials = GetCredentials();
var restRequest = new RestRequest { Resource = resource, Method = method, RequestFormat = DataFormat.Json, };
restRequest.AddHeader("accept", "application/json");
restRequest.AddHeader("Authorization", credentials);
return restRequest;
}
My controller class thus far is as follows:
public async Task<IActionResult> GetMerchantSignUp()
{
await _context.ProPayResponse.ToListAsync();
return Ok();
}
Are there any other steps needed to retrieve the RestSharp responses and expose them in my controller class?

Enum to JSON object for jQGrid using JSON.NET

I'm having an issue trying to convert an Enum to JSON string for jQGrid. The format I was using before (doing a manually conversion) was this:
{{0: '-', 1: 'Active', 2: 'Deactive', 3: 'Pending'}}
public static string GetStatuses(bool addDefault = false)
{
var statusesEnum = Enum.GetValues(typeof(StatusEnum));
string statuses = "{value: {0: '-', ";
foreach (StatusEnum status in statusesEnum)
statuses += String.Format("{0}: '{1}', ", (byte)status, Enum.GetName(typeof(StatusEnum), status));
return statuses.Substring(0, statuses.Length - 2) + "}}";
}
So I need to avoid this method because I think is not the best approach for this, I would like to serialize it using the JSON.NET library. So I wrote this:
public class StatusJSON
{
public byte ID { get; set; }
public string Name { get; set; }
public StatusJSON() { }
public StatusJSON(byte id, string name)
{
ID = id;
Name = name;
}
}
public class JSONUtils
{
/// <summary>
/// Get all the posible statuses of selected <paramref name="type"/> in JSON
/// </summary>
/// <param name="type">Type of the status</param>
/// <param name="addDefault">Check if add a default / NULL status</param>
/// <returns>A string JSON with the statuses</returns>
public static string GetStatuses(Type type, bool addDefault = false)
{
var statusesEnum = Enum.GetValues(type);
List<StatusJSON> statuses = new List<StatusJSON>();
if (addDefault)
statuses.Add(new StatusJSON(0, "-"));
foreach (var statusEnum in statusesEnum)
statuses.Add(new StatusJSON((byte)statusEnum, Enum.GetName(type, statusEnum)));
return JsonConvert.SerializeObject(statuses);
}
}
You can use it as: string statuses = JSONUtils.GetStatuses(typeof(StatusEnum), addDefault);. The problem is than this return a string like:
[{"ID":0,"Name":"-"},{"ID":1,"Name":"Active"},{"ID":2,"Name":"Deactive"},{"ID":3,"Name":"Pending"}]
There's any method in the library to get a string like the one I need? Thanks
What I did finally is re-use my old code. So now I have this:
public class Statutes
{
public byte ID { get; set; }
public string Name { get; set; }
public Statutes() { }
public Statutes(byte id, string name)
{
ID = id;
Name = name;
}
/// <summary>
/// Get all the posible statuses of selected <paramref name="type"/>
/// </summary>
/// <param name="type">Type of the status</param>
/// <param name="addDefault">Check if add a default / NULL status</param>
/// <returns>A list with the statuses</returns>
public static List<Statutes> SelectAll(Type type, bool addDefault = false)
{
var statusesEnum = Enum.GetValues(type);
List<Statutes> statuses = new List<Statutes>();
if (addDefault)
statuses.Add(new Statutes(0, "-"));
foreach (var statusEnum in statusesEnum)
statuses.Add(new Statutes((byte)statusEnum, Enum.GetName(type, statusEnum)));
return statuses;
}
}
public class JSONUtils
{
/// <summary>
/// Get all the posible statuses of selected <paramref name="type"/> in JSON
/// </summary>
/// <param name="type">Type of the status</param>
/// <param name="addDefault">Check if add a default / NULL status</param>
/// <returns>A string JSON for jQGrid with the statuses</returns>
public static string GetStatusesJQGrid(Type type, bool addDefault = false)
{
var statuses = Statutes.SelectAll(type, addDefault);
string result = "{value: {";
foreach (Statutes status in statuses)
result += String.Format("{0}: '{1}', ", status.ID, status.Name);
return result.Substring(0, result.Length - 2) + "}}";
}
}
You can use it as: string statuses = JSONUtils.GetStatusesJQGrid(typeof(StatusEnum), true);
Until I'll find a better approach using the JSON.NET I think this is a good piece of code to re-use for the people using jQGrid. This is valid for the select option:
colModel: {name: 'status_id', label: 'Status', edittype: 'select', sortable: true, search: true, stype:'select', editoptions: " + statuses + #", searchoptions: {sopt: ['eq', 'ne']}}

Categories