c# Generic class for handling static method - c#

I want to have a base generic class to handle model conversion.
Below are the model interfaces
public interface IRawModel
{
}
public interface IDtoModel
{
}
public interface IRawDto<T1, T2>
where T1 : IRawModel
where T2 : IDtoModel
{
/// <summary>
/// Get DTO model.
/// </summary>
/// <param name="item">Raw item</param>
/// <returns>DTO item</returns>
static T2 GetDto(T1 item) => throw new NotImplementedException();
}
Model classes
public class UserDto : IDtoModel
{
/// <summary>
/// Gets or sets firstname.
/// </summary>
public string? FirstName { get; set; }
/// <summary>
/// Gets or sets lastname.
/// </summary>
public string? LastName { get; set; }
/// <summary>
/// Gets or sets email.
/// </summary>
public string? Email { get; set; }
}
public class User : IRawModel, IRawDto<User, UserDto>
{
/// <summary>
/// Gets or sets first name.
/// </summary>
public string FirstName { get; set; }
/// <summary>
/// Gets or sets last name.
/// </summary>
public string LastName { get; set; }
/// <summary>
/// Gets or sets email.
/// </summary>
public string Email { get; set; }
/// <summary>
/// Gets DTO model.
/// </summary>
/// <param name="user">User</param>
/// <returns>User DTO</returns>
public static UserDto GetDto(User user) => new UserDto
{
Email = user.Email,
FirstName = user.FirstName,
LastName = user.LastName,
};
}
When i get a collection of users and to handle conversion in generic way i created below base class
public class BaseRepository<T1, T2, T3>
where T1 : IRawModel
where T2 : IDtoModel
where T3 : IRawDto<T1, T2>
{
/// <summary>
/// Convert collection
/// </summary>
/// <param name="items">T3 items</param>
/// <returns>DTO items</returns>
public IEnumerable<T2> GetDtos(IEnumerable<T3> items)
{
IEnumerable<T2> result = Enumerable.Empty<T2>();
// Something like this, not able to figure out
//result = items
// .Select(x => T3.GetDto((T1)x))
// .ToList();
return result;
}
}
I read interfaces can't have static methods until some c# 8.
Is this an overkill for a conversion, should i implement this conversion in individual classes?

Related

Why IFormFile is null in nested object?

I've got these models
public sealed class UpdateFacilityReportFirstStepCommand : ICommand<ExecutionResult>
{
// other props
/// <summary>
/// Gets or sets the hired staff.
/// </summary>
/// <value>The hired staff.</value>
public List<HiredStaffUpsertModel> HiredStaff { get; set; } = new List<HiredStaffUpsertModel>();
}
public class HiredStaffUpsertModel
{
// other props
/// <summary>
/// Gets or sets the insurance card file.
/// </summary>
/// <value>The insurance card file.</value>
public HiredStaffCarInsuranceCardModel CarInsuranceCardFile { get; set; } = new HiredStaffCarInsuranceCardModel();
}
public class HiredStaffCarInsuranceCardModel
{
/// <summary>
/// Gets or sets the file.
/// </summary>
/// <value>The file.</value>
[FileValidator("pdf,doc,docx", 10 * 1024 * 1024, true)]
public IFormFile File { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is changed.
/// </summary>
/// <value><c>true</c> if this instance is changed; otherwise, <c>false</c>.</value>
public bool IsChanged { get; set; }
}
And in my controller I'm expecting public [FromForm] UpdateFacilityReportFirstStepCommand command.
That's how I send form in Postman (content-type: multipart/form-data):
And that's what I get:
I have no idea why my File is null, although bool IsChanged is received. My frontend developer said that he'll send me form keys like on the Postman screenshot, and I don't get why it works fine with primitive types and doesn't with files.
The way I found to solve it, it's same as yours.
public class Purchase
{
public string Customer { get; set; }
public IEnumerable<Product> Products { get; set; }
}
public class Product
{
public string ProductCode { get; set; }
public IFormFile ProductImage { get; set; }
}
You have to send it like Products[0].ProductImage, otherwise you'll get null in ProductImage.

Why is my int being read as 0 from Azure Table Storage, not as the stored value?

I'm trying to read values that I have stored in an Azure Storage Table. When I retrieve the entity, in Fiddler, I can see the response as having the correct value, i.e.:
{
"odata.etag":"W/\"datetime'2019-01-24T20%3A23%3A58.3605274Z'\"",
"PartitionKey":"0029c461-74b9-47a7-955b-28e07b1905ab",
"RowKey":"09a79860-f568-481c-9641-9a1d53ebd678",
"Timestamp":"2019-01-24T20:23:58.3605274Z",
"AdjustmentId":"[GUID]",
"CompanyName":"[CompanyNme]",
"CustomerId":"[GUID]",
"Date#odata.type":"Edm.DateTime",
"Date":"2019-01-24T20:23:49.9487324Z",
"FinalQuantity":35,
"Id":"[GUID]",
"InitialQuantity":36.0,
"OfferName":"[Product]",
"Requester":"[User]",
"Status":"Accepted",
"StatusMessage":"Created",
"Type":"QuantityAdjustment"
}
However, when I work with this resoponse in my C# code, the InitialQuantity is set to 0. I'm using Microsoft Azure WebJobs Extensions Storage v3.0.3 and WindowsAzure.Storage v9.3.3.
The entity class that the Azure Storage SDK maps this to is below:
public class Transaction : TableEntity, ITransaction
{
/// <summary>
/// Gets or sets the adjustment identifier.
/// </summary>
/// <value>The adjustment identifier.</value>
public string AdjustmentId { get; set; }
/// <summary>
/// Gets or sets the name of the company.
/// </summary>
/// <value>The name of the company.</value>
public string CompanyName { get; set; }
/// <summary>
/// Gets or sets the customer identifier.
/// </summary>
/// <value>The customer identifier.</value>
public string CustomerId { get; set; }
/// <summary>
/// Gets or sets the Transaction's date. Should be generated on creation.
/// </summary>
/// <value>The date.</value>
public DateTime? Date { get; set; }
/// <summary>
/// Gets or sets the final quantity following the transaction.
/// </summary>
/// <value>The final quantity.</value>
public int FinalQuantity { get; set; }
/// <summary>
/// Gets or sets the transaction identifier. Should be a GUID in string format. This is
/// generated when a new Transaction is created.
/// </summary>
/// <value>The identifier.</value>
public string Id { get; set; } = Guid.NewGuid().ToString().ToLower();
/// <summary>
/// Gets or sets the initial quantity.
/// </summary>
/// <value>The initial quantity.</value>
public int InitialQuantity { get; set; }
/// <summary>
/// Gets or sets the offer identifier.
/// </summary>
/// <value>The offer identifier.</value>
public string OfferId { get; set; }
/// <summary>
/// Gets or sets the name of the offer.
/// </summary>
/// <value>The name of the offer.</value>
public string OfferName { get; set; }
/// <summary>
/// Gets or sets the requester.
/// </summary>
/// <value>The requester.</value>
public string Requester { get; set; }
/// <summary>
/// Gets or sets the status. Set to pending by default.
/// </summary>
/// <value>The status.</value>
public string Status { get; set; } = TransactionStatus.Pending;
/// <summary>
/// Gets or sets the status message.
/// </summary>
/// <value>The status message.</value>
public string StatusMessage { get; set; }
/// <summary>
/// Gets or sets the type. Should be set using the constants in the <see
/// cref="T:LicenseAdjustmentManagement.Infrastructure.TransactionTypes"/> class.
/// </summary>
/// <value>The type.</value>
public string Type { get; set; }
public string ToJson()
{
return JsonConvert.SerializeObject(this);
}
}
Code that calls the entities.
var storageAccount = CloudStorageAccount.Parse("[ConnectionString]");
var tableClient = storageAccount.CreateCloudTableClient();
var transactionsTable = tableClient.GetTableReference("Transactions");
var query = TableQuery<Transaction>().Where(TableQuery.GenerateFilterCondition("Id", QueryComparisons.Equal, "[GUID]"));
var results = await transactionsTable.ExecuteQuerySegmentedAsync(query, default(TableContinuationToken)).AsEnumerable();
var transaction = results.First();
All the other values are being read correctly, but the InitialValue is always 0. Any suggestions?
Edit: As suggested by KSib below, the InitialValue is being serialized as a decimal or double so when it's deserialized as an int, it recieves the default value of int, 0. Any idea why this thing is being serialized as a decimal when it's declared as in int?
You're trying to de-serialize a decimal to an int, presumably and instead of throwing an exception I'm going to assume it just sets the property to default(int) which is 0

match json data to class properties

I have used one webapi method where [FromBody] i used my class object.
like below:
public HttpResponseMessage ProcessResource([FromBody]FileContent contentvalue)
{//some business logic
}
and below is my json format which i am sending from client machine:
{"FileContent":{"ResourceStrings":[{"StringKey":"TestKey","StringID":1,"Value":"TestKey"},{"StringKey":"SampleKey","StringID":2,"Value":"Test key 1"},{"StringKey":"HomeKey","StringID":3,"Value":"Home DEV"},{"StringKey":"custom.WVF.ContactForm.Name","StringID":4,"Value":"NAME"},{"StringKey":"custom.CMS.MenuItem","StringID":5,"Value":"CMS.MenuItem"}]},}
below is FileContent class used:
public class ResourceString
{
public string StringKey { get; set; }
/// <summary>
/// Gets or sets the StringKey
/// </summary>
/// <value>
/// StringKey
/// </value>
public int StringID { get; set; }
/// <summary>
/// Gets or sets the StringID
/// </summary>
/// <value>
/// StringID
/// </value>
public string Value { get; set; }
/// <summary>
/// Gets or sets the Value
/// </summary>
/// <value>
/// Value
/// </value>
}
/// <summary>
/// Added RootObject new class to serialize and deserialize for resource string
/// </summary>
public class RootObject
{
/// <summary>
/// Gets or sets the list of ResourceString
/// </summary>
public List<ResourceString> ResourceStrings { get; set; }
}
public class FileContent
{
public List<ResourceString> ResourceStrings { get; set; }
}
Now when i am sending json data from client machine and debugging my web api method then FileContent object value is null.
How do i get json data in this method parameter?
Now i am able to get json data in that method using Roma's solution.
After getting data i need again i need to deserialize it to ResourceString then again i should get my json format like below:
{"ResourceStrings":[{"StringKey":"TestKey","StringID":1,"Value":"TestKey"},{"StringKey":"SampleKey","StringID":2,"Value":"Test key 1"},{"StringKey":"HomeKey","StringID":3,"Value":"Home DEV"},{"StringKey":"custom.WVF.ContactForm.Name","StringID":4,"Value":"NAME"},{"StringKey":"custom.CMS.MenuItem","StringID":5,"Value":"CMS.MenuItem"}]}
How do i make it deserialize to get the same?
Make your RootObject:
public class RootObject
{
public FileContent FileContent { get; set; }
}
And change your action to:
public HttpResponseMessage ProcessResource([FromBody]RootObject obj)
{
//some business logic
}
OR
If you want to parse into FileContent your JSON should be:
{"ResourceStrings":[{"StringKey":"TestKey","StringID":1,"Value":"TestKey"},{"StringKey":"SampleKey","StringID":2,"Value":"Test key 1"},{"StringKey":"HomeKey","StringID":3,"Value":"Home DEV"},{"StringKey":"custom.WVF.ContactForm.Name","StringID":4,"Value":"NAME"},{"StringKey":"custom.CMS.MenuItem","StringID":5,"Value":"CMS.MenuItem"}]}

return array of object from C# to C in COM

I am using COM to communicate between C++ and C#.
I have the following classes in C#
Email Address
/// <summary>
/// Email Address
/// </summary>
public class EmailAddress
{
/// <summary>
/// SMTP Address
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string Address;
/// <summary>
/// Name
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string Name;
}
Mailbox
/// <summary>
/// MailBox Entity
/// </summary>
public struct MailBoxEntity
{
/// <summary>
/// SMTP Address
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string SMTPAddress;
/// <summary>
/// Mailbox Display Name
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string Name;
/// <summary>
/// Mailbox Server Name
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string sServerName;
}
EmailEntity (yet to implement IEmailEntity which will contain properties for each field)
/// <summary>
/// Class for Email Entity
/// </summary>
public class EmailEntity : IEmailEntity
{
/// <summary>
/// BccRecipients
/// </summary>
[MarshalAs(UnmanagedType.ByValArray)]
public EmailAddress[] BccRecipients;
/// <summary>
/// Body
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string Body;
/// <summary>
/// CcRecipients
/// </summary>
[MarshalAs(UnmanagedType.ByValArray)]
public EmailAddress[] CcRecipients;
/// <summary>
/// Culture
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string Culture;
/// <summary>
/// DateTimeCreated
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string DateTimeCreated;
/// <summary>
/// DateTimeReceived
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string DateTimeReceived;
/// <summary>
/// DateTimeSent
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string DateTimeSent;
/// <summary>
/// FromAddress
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string FromAddress;
/// <summary>
/// FromName
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string FromName;
/// <summary>
/// HasAttachments
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string HasAttachments;
/// <summary>
/// Id
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string Id;
/// <summary>
/// Importance
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string Importance;
/// <summary>
/// LastModifiedName
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string LastModifiedName;
/// <summary>
/// LastModifiedTime
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string LastModifiedTime;
/// <summary>
/// MimeContent
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string MimeContent;
/// <summary>
/// ParentFolderId
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string ParentFolderId;
/// <summary>
/// Original Mailbox
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public MailBoxEntity OriginalMailBox;
/// <summary>
/// ParentFolderName
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string ParentFolderName;
/// <summary>
/// ReceivedByAddress
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string ReceivedByAddress;
/// <summary>
/// ReceivedByName
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string ReceivedByName;
/// <summary>
/// Size
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string Size;
/// <summary>
/// Subject
/// </summary>
[MarshalAs(UnmanagedType.BStr)]
public string Subject;
/// <summary>
/// ToRecipients
/// </summary>
[MarshalAs(UnmanagedType.ByValArray)]
public EmailAddress[] ToRecipients;
}
How do I access access an array of EmailEnity objects (in C++) returned from a function in C#
and read the fields of the EmailEntity class. Please note that EmailEntity class contains members like
EmailAddress[] which itself is an array of objects.
I was planning to implement interface IEmailEntity that contains properties to access fields of EmailEntity
and use it to access fields in C++. Is that the right way ?
How do I access complex fields members like array of EmailAddress (EmailAddress[] ToRecipients) in C++.
Please suggest.
Thanks
You could simplify the .NET Code like this (remove all MarshalAs that should be done automatically):
[ComVisible(true)]
public class MyRootClass : IMyRootClass // some class to start with
{
public IEmailEntity[] GetEntities()
{
List<IEmailEntity> list = new List<IEmailEntity>();
for(int i = 0; i < 10; i++)
{
EmailEntity entity = new EmailEntity();
List<IEmailAddress> addresses = new List<IEmailAddress>();
addresses.Add(new EmailAddress { Name = "Joe" + i });
entity.BccRecipients = addresses.ToArray();
entity.Body = "hello world " + i;
list.Add(entity);
}
return list.ToArray();
}
}
[ComVisible(true)]
public interface IMyRootClass
{
IEmailEntity[] GetEntities();
}
public class EmailEntity : IEmailEntity
{
public IEmailAddress[] BccRecipients { get; set; }
public string Body { get; set; }
}
public class EmailAddress : IEmailAddress
{
public string Address { get; set; }
public string Name { get; set; }
}
[ComVisible(true)]
public interface IEmailAddress
{
string Address { get; set; }
string Name { get; set; }
}
[ComVisible(true)]
public interface IEmailEntity
{
IEmailAddress[] BccRecipients { get; set; }
string Body { get; set; }
// to be continued...
}
To use it with C++, you need to register the DLL and build a .TLB (Type Library file) as explained in a similar answer here: Implement a C# DLL COM File In Unmanaged C++ Program
Then, you can access these classes in C++, like this:
#include "stdafx.h"
#import "c:\MyPathToTheTlb\YourAssembly.tlb" // import the COM TLB
using namespace YourAssembly;
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
IMyRootClassPtr ptr(__uuidof(MyRootClass));
CComSafeArray<IUnknown*> entities = ptr->GetEntities(); // CComSafeArray needs atlsafe.h in the PCH
for(int i = entities.GetLowerBound(0); i <= entities.GetUpperBound(0); i++)
{
IEmailEntityPtr entity;
entities.GetAt(i).QueryInterface(&entity);
_bstr_t body = entity->Body;
printf("%S\n", body.GetBSTR());
CComSafeArray<IUnknown*> recipients = entity->BccRecipients;
for(int j = recipients.GetLowerBound(0); j <= recipients.GetUpperBound(0); j++)
{
IEmailAddressPtr address;
recipients.GetAt(j).QueryInterface(&address);
_bstr_t name = address->Name;
printf(" %S\n", name.GetBSTR());
}
}
CoUninitialize();
}

How to change background color of ListViewItem dynamically?

I have a BookItemView class for data template of ListViewItem.
/// <summary>
/// Represent a class to keep every items view.
/// </summary>
public class BookItemView : ICloneable
{
/// <summary>
/// Create a new instance of BookItemView.
/// </summary>
public BookItemView()
{
this.ID = Guid.NewGuid();
}
/// <summary>
/// Gets current instance unique id.
/// </summary>
public Guid ID
{
get;
private set;
}
/// <summary>
/// Gets or sets items title.
/// </summary>
public string Title { get; set; }
/// <summary>
/// Gets or sets items subtitle.
/// </summary>
public string Subtitle { get; set; }
/// <summary>
/// Gets or sets items description.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Gets or sets items icon.
/// </summary>
public ImageSource Icon { get; set; }
/// <summary>
/// Gets or sets a value which indicate is item marked or not.
/// </summary>
public bool Marked { get; set; }
/// <summary>
/// Gets or sets a list of BookItemView.
/// </summary>
public ObservableCollection<BookItemView> BookItems { get; set; }
/// <summary>
/// Create a shallow copy of current object.
/// </summary>
/// <returns>A shallow copy of current object.</returns>
public object Clone()
{
return base.MemberwiseClone();
}
}
How can i set an special background color for some of ListViewItems in ListView?
ItemContainerStyle is your friend. For example:
<ListView>
<ListView.ItemContainerStyle>
<Setter Property="Background" Value="{Binding Marked, Converter={StaticResource MarkedConverter}}"/>
</ListView.ItemContainerStyle>
</ListView>
Define desired property on what you want to change background and in DataTemplate defined for ListViewItem trigger changing background on specific value of your property.

Categories