can the parameters FromUri be read from an attribute? - c#-4.0

I have a simple controller that accepts a response from a payment system.
public async Task<IHttpActionResult> Pending([FromUri] DepositResponse response)
{
Logger.LogInfo(JsonConvert.SerializeObject(response));
return Ok(response);
}
the deposit response however has very ugly and unstandardised parameters. I have no control over that because that's what the payment system sends.
public class DepositResponse
{
public string ppp_status { get; set; }
public string ExErrorCode { get; set; }
public string PPP_TransactionID { get; set; }
public string merchant_site_id { get; set; }
//etc
}
As a result, Resharper complains about the chosen name that it doesn't match the rules and I want to change it to match all the classes in the rest of the project.
Is there an attribute I can use, or one I can create to make FromUri understand the response?
For example
public class DepositResponse
{
[FromUriName("ppp_status")]
public string pppStatus { get; set; }
[FromUriName("ExErrorCode")]
public string exErrorCode { get; set; }
[FromUriName("PPP_TransactionID")]
public string pppTransactionId { get; set; }
[FromUriName("merchant_site_id")]
public string merchantSiteId { get; set; }
//etc
}
I couldn't find such an example online, but I would imagine it can be very useful when dealing with external systems that send rubbish...
any ideas?

You can use the below model
public class DepositResponse
{
[JsonProperty(PropertyName="ppp_status")]
public string pppStatus { get; set; }
[JsonProperty(PropertyName="ExErrorCode")]
public string exErrorCode { get; set; }
[JsonProperty(PropertyName="PPP_TransactionID")]
public string pppTransactionId { get; set; }
[PropertyName(PropertyName="merchant_site_id")]
public string merchantSiteId { get; set; }
//etc
}

Related

Servicestack JsConfig with emitLowercaseUnderscoreNames = true does not work on properties with alphanumeric names

I am using Servicestack JsonConfig for serializing and deserializing the JSON. but for the following class, it works for some properties and does not for others.
public class Address
{
public string Street1 { get; set; }
public string Street2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
}
When I deserialize it to JSON ZipCode is correctly represented as "zip_code" but Street1 is represented as "street1" where the expected presentation is "street_1". Following is the code
using (JsConfig.With(emitLowercaseUnderscoreNames: true, propertyConvention: PropertyConvention.Lenient))
{
//serialize into json
requestJsonString = JsonSerializer.SerializeToString(request.SubscriptionRequest);
}
The part of the JSON I am getting is
{"address":{"street1":"100 Tlllbow Street","street2":"100 Taljjow Street","city":"Housthgon","state":"hg","zip_code":"022"}}
Please help. Thanks in Advance.
This behavior is by design, you can change it by providing an alias with [DataMember(Name] attribute, e.g:
[DataContract]
public class Address
{
[DataMember(Name="street_1")]
public string Street1 { get; set; }
[DataMember(Name="street_2")]
public string Street2 { get; set; }
[DataMember]
public string City { get; set; }
[DataMember]
public string State { get; set; }
[DataMember]
public string ZipCode { get; set; }
}
Or by renaming your properties:
public class Address
{
public string Street_1 { get; set; }
public string Street_2 { get; set; }
}

.NET core model binding with hyphenated attribute names in post request

I've subscribed to the Nexmo SMS service and they offer a callback URL for inbound SMS. The post request gives the following Json structure when notifying of SMS receipt:
{
"msisdn": "441632960960",
"to": "441632960961",
"messageId": "02000000E68951D8",
"text": "Hello7",
"type": "text",
"keyword": "HELLO7",
"message-timestamp": "2016-07-05 21:46:15"
}
Using the following code snippet, I can map all of the fields to my SmsReceipt apart from 'message-timestamp'. None of the message timestamp fields are populated.
public class SmsReceipt
{
public string msisdn { get; set; }
public string to { get; set; }
public string messageId { get; set; }
public string text { get; set; }
public string type { get; set; }
public string keyword { get; set; }
public string messagetimestamp { get; set; }
public string messageTimestamp { get; set; }
public string message_timestamp { get; set; }
}
[HttpPost("inboundsms")]
public async Task<IActionResult> Post([FromBody] SmsReceipt receipt)
{
return StatusCode(200);
}
I guess the same applies to incoming requests with other special characters such as '.' Any ideas greatly appreciated.
Your property name should match with the property name in the data being sent. Looks like your payload property name is message-timestamp. You cannot create a C# property with a - in it. So your options are
Either update your json payload property to match with one from your C# class.
Decorate your C# class with JsonProperty(From Newtonsoft.Json) where you specify what property from the posted data should be mapped to this property.
Also i suggest use the DateTime type. That type was created to deal with date time value.
public class SmsReceipt
{
public string Msisdn { get; set; }
public string To { get; set; }
public string MessageId { get; set; }
public string Text { get; set; }
public string Type { get; set; }
public string Keyword { get; set; }
[JsonProperty("message-timestamp")]
public DateTime Messagetimestamp { get; set; }
}

CRUD multiple model in one view in mvc4

i want use multiple model in one view and add records in multiple table from view
my db like below image:
(i work with vs2012 mvc4 and EF)
i create four model for each table and class "PreOrder" for repository of all
public class Orders
{
public long OrdersId { get; set; }
public string CustomerId { get; set; }
public long OrderListId { get; set; }
public int? CountProduct { get; set; }
public string CountPrice { get; set; }
public string VisitorsName { get; set; }
public DateTime? OrderDate { get; set; }
}
public class Product
{
public string ProductID { get; set; }
public string NameProduct { get; set; }
public string Price { get; set; }
}
public class Customers
{
public string CustomerID { get; set; }
[DisplayFormat(NullDisplayText = "-")]
public string Name { get; set; }
[DisplayFormat(NullDisplayText = "-")]
...
}
public class OrderList
{
public long OrderListID { get; set; }
public Nullable<long> OrdersId { get; set; }
public string ProductId { get; set; }
public Nullable<int> Count { get; set; }
public Nullable<decimal> DisCount { get; set; }
}
public class PreOrder
{
public Customers _Customer { set; get; }
public Product _Product { set; get; }
public Orders _Order { set; get; }
public OrderList _OrderList { set; get; }
}
i want use name,family,customerid from tblcustomers
and productId,NameProduct,Price from tblProducts
and all fields of tblOrders and tblOrderList
how can i create one view to fill tables Orders and OrderList??
i solved problem like below article:
How to Use ViewModel with ASP.NET MVC ?
How to Use ValueInjecter with Asp.net MVC ViewModel ?

EF Code First - Many To Many

I have a problem with devising a many to many relationship in code first. EF is creating the Junction table and associating the Fk's as I would expect, however when i try to access the User's MailingList collection, there are no entries.
I've implemented test data on Initialise via Seeding, the data is al present in the database.
I think the problem lies with the constructors for Users and MailingLists, but I'm uncertain. I want to be able to navigate the navigational property of User.MailingLists.
var user = db.Users.Find(1);
Console.WriteLine("{0}", user.EmailAddress); //This is Fine
Console.WriteLine("{0}", user.Address.PostCode); /This is Fine
foreach (MailingList ml in user.MailingLists) // this is 0
{
Console.WriteLine("{0}", ml.Name);
}
My model is below:-
public class User : IEntityBase
{
public User()
{
MailingLists = new List<MailingList>();
}
public int Id { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string EmailAddress { get; set; }
public DateTime? DateLastUpdated { get; set; }
public DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
public virtual Address Address { get; set; }
public ICollection<MailingList> MailingLists { get; set; }
}
public class MailingList : IEntityBase
{
public MailingList()
{
Users = new List<User>();
}
public int Id { get; set; }
public string Name { get; set; }
public DateTime? DateLastUpdated { get; set; }
public DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
public ICollection<User> Users { get; set; }
}
public class Address : IEntityBase
{
public int Id { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string City { get; set; }
public string County { get; set; }
public string PostCode { get; set; }
public DateTime? DateLastUpdated { get; set; }
public DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
}
Any suggestions welcome.
You are neither eager loading the MailingList entries with the query, nor fulfulling the requirements for a lazy loading proxy so there is no way EF can populate the collection.
To allow lazy loading, change the MailingList property to be virtual to allow the EF proxy to override it.
To use eager loading, use Include() (an extension method in System.Data.Entity) in the query to specify that the MailingList should be loaded.

Mapping from list down to object with AutoMapper

I'm new with AutoMapper and have a problem I'm trying to solve.
If I have a source class like this:
public class Membership
{
public int MembershipId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string OrganizationName { get; set; }
public List<Address> Addresses { get; set; }
}
And the Address class looks like this:
public class Address
{
public int AddressId{ get; set; }
public int RefAddressTypeId { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public bool IsPreferredAddress { get; set; }
}
My destination class is:
public class UserInformationModel
{
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Organization { get; set; }
public string EmailAddress { get; set; }
public PhysicalAddress BillingAddress { get; set; }
public PhysicalAddress ShippingAddress { get; set; }
}
And the destination address class is:
public class PhysicalAddress
{
public AddressType AddressType{get; set;}
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
}
I have set up a mapping like this:
Mapper.CreateMap<MinistryMattersIntegration.BusinessObjects.Entities.Cokesbury.Membership, UserInformationModel>()
.ForMember(dest => dest.Organization, opt => opt.MapFrom(src=>src.OrganizationName));
This is working for Membership to UserInformationModel, but now I need to get addresses working. One important thing to note, though, is that the destination is a single billing address and a single shipping address while in the original model, all the address are stored as a list. The way you find the shipping and billing addresses out of the list is by looking at the RefAddressTypdId and the IsPreferredAddress. Only one preferred address may exist with a particular RefAddressTypeId.
So, my question is, how do you get AutoMapper to do this kind of mapping? Is it possible, or am I better off just going with regular mapping code?
You'll want to use the Custom Value Resolvers feature of AutoMapper. So you'd setup a Custom Resolver to map from your list to your single entity using the IsPreferredAddress flag to find it.
The documentation is pretty good for the Custom Resolvers so you should be fine figuring it out from there.

Resources