POST Complex Object to ApiController Subclass - c#

I am working on an API method that should accept an Image model object, which has a property List<Comment> Comments. The Image POSTed from the mobile app works fine but if I include an array of Comment objects they aren't showing up on the instance of the Image. I'm not super great with C# so any help would be appreciated.
Image Class
public class Image
{
public int? ImageId { get; set; }
[Required]
public string Image { get; set; }
[Required]
public string ContentType { get; set; }
[Required]
public string Filename { get; set; }
[Required]
public DateTime DateTaken { get; set; }
[Required]
public int UserId { get; set; }
[Required]
public int CompanyId { get; set; }
[Required]
public int LocationId { get; set; }
public decimal? Lat { get; set; }
public decimal? Long { get; set; }
public List<ApiComment> Comments { get; set; }
}
Comment Class
public class ApiComment
{
[Required]
public string Comment { get; set; }
[Required]
public DateTime DateCreated { get; set; }
[Required]
public int UserId { get; set; }
}
Beginning of ImagesController
public class ImagesController : ApiController
{
[System.Web.Http.HttpPost]
public ActionResult Post(Image image)

I believe there's something wrong with the request body of your request:
I tried this in fiddler:
{ "Comments" : [{ "Comment" : "Hello"}, {"Comment" : "World"}]}
And I got two counts for Comments in my WebAPI Action Method.
Check there are no typo error with the request object you are posting and the Json is valid.

Related

how can I get image file with other form property's together in asp web api application

I have a form in react application that include registration form.
this simple form have some input like title, content , etc and image.
so when I posted this form to server I couldn't see expected result:
as you know for posting this types of form we forced to set content-type: form-data in header of request.
my controller is:
public class StoreRequest
{
public News news { get; set; }
public int?[] categories { get; set; }
public HttpPostedFileBase image { get; set; }
};
public class NewsController : ApiController
{
[System.Web.Http.HttpPost]
[JwtAuthentication]
public IHttpActionResult Store(StoreRequest storeRequest)
{
return Ok(storeRequest);
.
.
.
}
}
and my model is:
public class News : BaseModel
{
public News()
{
this.Category = new HashSet<Category>();
}
[Required]
[Column(TypeName = "nvarchar")]
public string title { get; set; }
[Column(TypeName = "text")]
public string content { get; set; }
[Required]
[Column(TypeName = "bit")]
public bool slide { get; set; }
[ForeignKey("Staff")]
public int staff_id { get; set; }
public virtual Staff Staff { get; set; }
public virtual ICollection<Category> Category { get; set; }
}
How can I solve this problem?
I'm beginner in C# specially in asp.

How to define a navigation property via Entity Framework code first approach

I have the following class that I want to use as my data context in Entity Framework:
public class AggregateRecord : IAggregateRecord
{
[Key]
public int AggregateRecordID { get; set; }
public DateTime? InsertDate { get; set; } = DateTime.Now;
public DateTime BookingDate { get; set; }
public string AmountTypeName { get; set; }
public int? UnifiedInstrumentCode { get; set; }
public double? Amount { get; set; }
public string BookingAccountID { get; set; }
public string AccountCurrency { get; set; }
public string ClientCurrency { get; set; }
public string AffectsBalance { get; set; }
public string AssetType { get; set; }
public string UnderlyingInstrumentSubType { get; set; }
public string InstrumentSymbol { get; set; }
public string InstrumentSubType { get; set; }
public string UnderlyingInstrumentAssetType { get; set; }
public string UnderlyingInstrumentDescription { get; set; }
public string UnderlyingInstrumentSymbol { get; set; }
public string UnderlyingInstrumentUic { get; set; }
public double? AmountAccountCurrency { get; set; }
public string AmountClientCurrency { get; set; }
public string InstrumentDescription { get; set; }
public virtual ICollection<InstrumentInfo> InstrumentInfo { get; set; }
}
public class InstrumentInfo
{
[Key]
public int InstumentInfoID {get;set;}
public string SomeInformation { get; set; }
public int AggregateRecordID { get; set; }
public virtual AggregateRecord AggregateRecord { get; set; }
}
I have studies the examples provided for EF6 but I still have the problem that when I try to update my migration that I get the following error:
One or more validation errors were detected during model generation:
There are no primary or candidate keys in the referenced table 'dbo.AggregateRecords' that match the referencing column list in the foreign key 'FK_dbo.InstrumentInfoes_dbo.AggregateRecords_AggregateRecordID'.
Could not create constraint or index. See previous errors.
How do I have to define the classes so that InstrumentInfo can be accessed via a navigation property?
public class InstrumentInfo
{
[Key]
public int InstumentInfoID {get;set;}
public string SomeInformation { get; set; }
public int AggregateRecordId { get; set; }
public virtual AggregateRecord AggregateRecord { get; set; }
}
Seems you forgot "public"
I "solved" the problem. It's weird, but maybe it helps somebody in future that's why I answer my own question.
I renamed my class AggregateRecord to AggregateEntry. Performed the Add-Migration and Update-Database, with the new renamed class name. And it worked.
It looks like there was some problem with the migration definition or whatsoever, but it solved it.
In the end, I renamed it back to the original name, did the same procedure again and, voila, it works.
#Dennis Spade: Thanks for your effort, without your hint it would have taken me even more time to find the real "problem".

ASP.NET MVC: How to display a detail from one-to-many related model in a view

So basically I have a Post model, which is associated with the user that created it:
public class Post
{
public int Id { get; set; }
[Required]
public string PostContent { get; set; }
[Required]
public DateTime DatePosted { get; set; }
[Required]
public string PostTitle { get; set; }
public ApplicationUser ApplicationUser { get; set; }
}
And the ApplicationUser has posts:
public virtual ICollection<Post> Posts { get; set; }
So now on the Posts index view page, I just want to show the Email of the ApplicationUser who wrote the post. So the following doesn't work (it just shows blank on the page):
#Html.DisplayFor(modelItem => item.ApplicationUser.Email)
What's the best/easiest way to do this?
Your Posts class/view model can look like the following:
public class PostViewModel
{
public int Id { get; set; }
[Required]
public string PostContent { get; set; }
[Required]
public DateTime DatePosted { get; set; }
[Required]
public string PostTitle { get; set; }
public ApplicationUserViewModel PostOwner { get; set; }
public List<ApplicationUserViewModel> PostContributors { get; set; }
}
And Your ApplicationUserViewModel can look like the below:
public class ApplicationUserViewModel
{
public int UserId { get; set; }
[Required]
public string UserName { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string Email { get; set; }
public virtual List<dtoPost> Posts { get; set; }
}
Adding a dto so you would not have a circular reference to the View Model:
public class dtoPost
{
public int Id { get; set; }
[Required]
public string PostContent { get; set; }
[Required]
public DateTime DatePosted { get; set; }
[Required]
public string PostTitle { get; set; }
public ApplicationUserViewModel PostOwner { get; set; }
public List<ApplicationUserViewModel> PostContributors { get; set; }
}
You can access the Email of the Post owner like this in the index view of Post with a reference to the PostViewModel:
#model WordClues.ViewModels.PostViewModel
<div>
#Html.DisplayFor(m => m.PostOwner.Email)
</div>
You have to write the appropriate Controller Method in your code. BTW it is asp.net MVC.

Error while pasing JSON

While I am trying to call the
`var obj = JsonConvert.DeserializeObject<UserModel>({myjsonString})`
it keeps throwing me unable to deserialize exception.
To check if my json string was well formed i decided to
Parse the string and called
JsonSchema schema = JsonSchema.Parse({myjsonString});
now i get the error below, not quite sure what it means
Additional information: Expected object while parsing schema object,
got String. Path ''
**UPDATE**
"{\"Id\":5,\"Username\":\"Sid\",\"FirstName\":\"Sid \",\"LastName\":\"LastSid\",\"Email\":\"test#gmail.com\",\"Password\":\"sample\",\"GravatarHash\":\"http://www.gravatar.com/avatar/f4f901415af5aff35801e8444cd5adc1?d=retro&?s=50\",\"Country\":\"Moon\",\"OrganizationId\":1,\"IsLocked\":false,\"CreatedDate\":\"12/13/2013 2:34:28 AM\",\"UpdatedDate\":\"12/13/2013 2:34:28 AM\",\"DataLoaded\":true}"
UPDATE 2
"\"{\\\"Id\\\":5,\\\"Username\\\":\\\"Sid\\\",\\\"FirstName\\\":\\\"Siddharth \\\",\\\"LastName\\\":\\\"Kosta\\\",\\\"Email\\\":\\\"Skosta#gmail.com\\\",\\\"Password\\\":\\\"PAssword\\\",\\\"GravatarHash\\\":\\\"http://www.gravatar.com/avatar/f4f901415af5aff35801e8c4bcd5adc1?d=retro&?s=50\\\",\\\"Country\\\":\\\"India\\\",\\\"OrganizationId\\\":1,\\\"IsLocked\\\":false,\\\"CreatedDate\\\":\\\"2013-12-13T02:34:28.037\\\",\\\"UpdatedDate\\\":\\\"2013-12-13T02:34:28.23\\\",\\\"DataLoaded\\\":true}\""
The User Model
public class UserModel
{
public Int32 Id { get; set; }
public String Username { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String Email { get; set; }
public String Password { get; set; }
public String GravatarHash { get; set; }
public String Country { get; set; }
public Int32 OrganizationId { get; set; }
public Boolean IsLocked { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime UpdatedDate { get; set; }
}
I also tried
public String CreatedDate { get; set; }
public String UpdatedDate { get; set; }
thinking if the dates were causing a problem
Update:
It works perfectly fine with your UserModel, at least for me.
Assume you have such UserModel:
public class UserModel
{
public int Id { get; set; }
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string GravatarHash { get; set; }
public string Country { get; set; }
public int OrganizationId { get; set; }
public bool IsLocked { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime UpdatedDate { get; set; }
public bool DataLoaded { get; set; }
}
var input =
"{\"Id\":5,\"Username\":\"Sid\",\"FirstName\":\"Sid \",\"LastName\":\"LastSid\",\"Email\":\"test#gmail.com\",\"Password\":\"sample\",\"GravatarHash\":\"http://www.gravatar.com/avatar/f4f901415af5aff35801e8444cd5adc1?d=retro&?s=50\",\"Country\":\"Moon\",\"OrganizationId\":1,\"IsLocked\":false,\"CreatedDate\":\"12/13/2013 2:34:28 AM\",\"UpdatedDate\":\"12/13/2013 2:34:28 AM\",\"DataLoaded\":true}";
var userModel = JsonConvert.DeserializeObject<UserModel>(input);
I think the problem with your model, can you please provided it?
It looks to me like your JSON is getting double serialized. (Having a bunch of extra backslashes in your JSON is a symptom of this.) I notice in the comments on another answer that you said you are using Web API. The Web API framework takes care of serialization for you, so you do not need to call JsonConvert.SerializeObject() in those methods. Instead just return your result directly. Then you should be able to deserialize it normally in your client. See this question.
Is there a reason why you have the curly braces in
var obj = JsonConvert.DeserializeObject<UserModel>({myjsonString})
That seems like the source of the error. Change it to:
var obj = JsonConvert.DeserializeObject<UserModel>(myjsonString)
You're missing the DataLoaded property.
public bool DataLoaded { get; set; }
In future, use this website to generate your C# classes from JSON.
http://json2csharp.com/
EDIT:
Try this step by step...
Copy and paste this class exactly as is.
public class UserModel
{
public int Id { get; set; }
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string GravatarHash { get; set; }
public string Country { get; set; }
public int OrganizationId { get; set; }
public bool IsLocked { get; set; }
public string CreatedDate { get; set; }
public string UpdatedDate { get; set; }
public bool DataLoaded { get; set; }
}
Now in the console have this:
var jsonString = #"{""Id"":5,""Username"":""Sid"",""FirstName"":""Sid "",""LastName"":""LastSid"",""Email"":""test#gmail.com"",""Password"":""sample"",""GravatarHash"":""http://www.gravatar.com/avatar/f4f901415af5aff35801e8444cd5adc1?d=retro&?s=50"",""Country"":""Moon"",""OrganizationId"":1,""IsLocked"":false,""CreatedDate"":""12/13/2013 2:34:28 AM"",""UpdatedDate"":""12/13/2013 2:34:28 AM"",""DataLoaded"":true}";
var user = JsonConvert.DeserializeObject<UserModel>(jsonString);
Console.WriteLine(user.Country);
Console.ReadLine();

ServiceStack DTO For Dropdown Lists

I have a request object for a POST in a ServiceStack service that looks like this:
[Route("/jtip/cases/search", "POST")]
public class FindAgencyCases : IReturn<List<AgencyCaseResponse>>
{
public int? AgencyId { get; set; }
public string AgencyCaseNumber { get; set; }
public int? ServiceId { get; set; }
public string IndividualFirstName { get; set; }
public string IndividualLastName { get; set; }
public string CompanyName { get; set; }
public string LicenseNumber { get; set; }
public string LicenseState { get; set; }
public string IndividualType { get; set; }
public DateTime? RequestStartDate { get; set; }
public DateTime? RequestEndDate { get; set; }
public string Status { get; set; }
public int? ResultsLimit { get; set; }
}
The values for AgencyId, ServiceId, etc need to come from dropdown lists. This DTO doesn't care how it gets those values, but I need to provide collections for my agencies, services, etc.
Because this is a request object, I can't grab my lists from the database and send them to the client. So how would I go about getting the lists for my dropdowns (in an HTML form) that contain the values to populate the above request DTO? I'm I overlooking something really obvious?
Why not simply create another request / route that lists the available agencies and services?
[Route("/jtip/cases/agencies", "GET")]
public class AgencyListRequest : IReturn<List<Agency>>
{
}
public class Agency {
public int Id { get; set; }
public string Name { get; set; }
}
[Route("/jtip/cases/services", "GET")]
public class ServiceListRequest : IReturn<List<Service>>
{
}
public class Service {
public int Id { get; set; }
public string Name { get; set; }
}

Categories

Resources