Updating article with multiple child elements from one view - asp.net-mvc-3

I've been looking for this conundrum for days now and been on many possible solutions, but either the examples are too far removed from what I am attempting and I am just not good enough to take in the data because of it. Hence I decided to ask the question myself and show my particular situation.
I got a product model like this (simplified)
public class Product
{
[Key]
public int ProductId { get; set; }
public string SKU { get; set; }
public int ProductCategoriesId { get; set; }
public bool Purchase { get; set; }
public bool ShowProduct { get; set; }
public virtual IList<ProductTranslations> ProductTranslations { get; set; }
}
public class ProductTranslations
{
[Key]
public int ProductTranslationsId { get; set; }
public int ProductId { get; set; }
public string ProductLanguage { get; set; }
public string Description { get; set; }
public string ProductName { get; set; }
public virtual Product Product { get; set; }
}
So I have one product with language neutral data, then each product can have several child elements, one for each language. I have an edit form where I want to show the language neutral data and the language specific data (names and descriptions).
Simplified view:
#model Artikelhantering.Models.Product
#using (Html.BeginForm())
{
#Html.LabelFor(model => model.SKU)
#foreach (var item in Model.ProductTranslations)
{
#Html.EditorFor(TranslationItem => item.ProductName)
#Html.TextAreaFor(TranslationItem => item.Description)
}
<p>
<input type="submit" value="Save" />
</p>
}
This gets everything onto the view nice and tidy looking I think, I think I could (should?) make a dedicated viewmodel for the editor-view later on. Anyway the problem is I don't know how to update the data on submit. I can update the language neutral data using normal EF approach but any changes to the fields from the other model are unchanged...
And to be honest that makes perfect sense to me, since there's nothing in the form to distinquish them, no unique id's or such and the product model does not contain those fields either... The way I would this in old classic asp would be to name the fields with their unique Id's and then make an SQL update query that updated each child model on submitting the form. I guess I could implement such a practice here too but it doesn't feel like the right way to go about things.
Is there a proper or 'best practices' approach in MVC for this kind of thing?

Related

Multilingual MVC 4 best practice

I know if I want to create a multilingual MVC4 application I would use resource files according to CultureInfo, but that would be useful for application's labels, messages, titles..etc, however I was thinking about defining a list of counties' names and their cities in many languages, now should I define them in a resource files (which can be exhausting) or should I use a table with many columns for each language?
And if I used resource files, how can I tell which country a user is from when he register in the system?
Which one is best practice? Is there any other approach?
Using multiple columns for each language will work, but it will also get out of hand pretty quickly as more columns and languages need to be added down the road. So I'd advise against that approach.
What you can do however is move the columns that need to be localized to a different table with a compound primary key. Here's a simple example with a cities table :
You'll have classes that look somewhat like this :
// City.cs
public class City
{
public int CityId { get; set; }
public string UnlocalizedField1 { get; set; }
public string UnlocalizedField2 { get; set; }
// Optional
public virtual List<CityTranslation> Translations { get; set; }
}
// CityTranslation.cs
public class CityTranslation
{
public int CityId { get; set; }
public string LanguageId { get; set; }
public string LocalizedField1 { get; set; }
public string LocalizedField2 { get; set; }
}
Then it becomes rather trivial to query your data in the language you need.

About MVC ViewModel and partial view [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to edit multiple models in a single Razor View
I'm using MVC3 to make an order functionality. I have Order and OrderDetail Model. Order and OrderDetail is in an one to many relationship.
The two models look something like this:
public class order
{
public int OrderId{get;set;}
public int OrderStatusID { get; set; }
public virtual OrderStatus OrderStatus { get; set; }
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
}
public class OrderDetail
{
public int OrderDetailID { get; set; }
public int OrderID { get; set; }
public int Quantity { get; set; }
public string Description { get; set; }
public int CategoryID { get; set; }
public virtual Order Order { get; set; }
public virtual Category Category { get; set; }
}
I want to use them both in a view, so I made the OrderViewModel for it below,
public class OrderViewModel
{
public virtual Order Order { get;set; }
public virtual List<OrderDetail> OrderDetails { get;set; }
}
I have two questions:
1, How can I use the OrderViewModel to make pages for creating and editing Order?
I made the partial view for the OrderDetail. In the Creating page, I did something like the following, but I don't think it's correct.
#foreach (var detail in Model.OrderDetails)
{
#Html.Partial("_OrderDetail", detail)
}
2, Order and OrderDetail is in an one to many relationship, in the creating Order page, I want users to be able to add multiple OrderDetail. I used jQuery to make a button that can make multiple OrderDetail fields, but I don't know how to Retrieve the values from every OrderDetail.
How is this done?
Use EditorFor for the details.
Please have a look of below link and see an answer of Darin Dimitrov
How to use LabelFor on a strongly typed view for a list
LabelFor not working in loop (for/foreach/template)
Do let me know if you still have any query.

User-Specific Value for Object in Razor

I am an absolute novice at using ASP.NET MVC3, and I'm having a great deal of trouble figuring out how to do something that is probably very easy.
Here's my public class:
public class Proposal
{
ProposalDBEntities proposalDB =
new ProposalDBEntities();
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime Target_Finish_Date { get; set; }
public decimal Estimated_Cost { get; set; }
public int Staffing { get; set; }
public decimal Maintenance { get; set; }
public DateTime Date_Added { get; set; }
public int Rating { get; set; }
public decimal VoteAverage { get; set; }
}
I simply want an individual logged-in user to be able to set the value for public int Rating. That is, if the user sets it to 37, he'll see the value 37 when he logs in. But another user who sets it to 50 will see 50. In other words, the value for Rating will be different depending on who's logged in. This seems like it wouldn't be hard at all, but I have no idea where to begin. Any help would be greatly appreciated.
To display the rating: In your view, you would have something like #Html.DisplayFor(p => p.Rating). This is RAZOR syntax. If you are using ASPX, it would be <%: #Html.DisplayFor(p => p.Rating) %>
To have users able to edit the rating (in Entity Framework): How will your user input the rating? Personally, as a beginner, you can create an Entity Data Model and generate code based on your database structure. Then, you can create a controller with CRUD (create, read, update, delete) principles that gives the user the ability to edit his/her rating (Keep in mind that there are views created in addition to edit: create, delete, details, and index. Use what is relevant to you.)
Lots of info to digest, I'm sure. Feel free to ask me anything. I'm in your shoes as well. Hope this helps.

Complex tabbed form with panels in .NET MVC 3

I'm trying to create some complex form scheme in a .NET MVC 3 project (or so I think). I'll show a wireframe so that you can understand better.
As you can see from the pic above, it's a form to create a new Car Dealership. I can choose from many available car's manufacturers (in the Add a tab), and each selection creates a new tab in the panel underneath it. In each panel there's a html fieldset, and I can add some new cars on it.
In the end, I want to submit all the form, which comprehends the data from the dealership (e.g. name), the car's brands that it has and the cars available for each brand. How can I do it with MVC 3? I don't know how exactly should I instantiate the model Car Dealership and its respective View. What should the cars in the panels be? An array of inputs? And how can I separate the inputs from one tab from the ones of another? All of this, using Razor!
My real-world scenario is a little bit more complicated, but I'll start by this so that I can try to solve the rest by myself. I'm using jQuery/jQuery UI, but I'm opened to other javascript alternatives (like Backbone, etc - I just don't know them yet). Thanks in advance!
UPDATE (1):
These are my models so far:
public class CarDealership
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ManufactorOnDealership> ManufactorsOnDealership { get; set; }
}
public class Manufactor
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ManufactorOnDealership> DealershipsOfManufactor { get; set; }
}
// Junction class: I believe it's needed because the list of Cars belongs to this relationship
public class ManufactorOnDealership
{
public int Id { get; set; }
public int CarDealershipId { get; set; }
public int ManufactorId { get; set; }
public virtual CarDealership CarDealership { get; set; }
public virtual Manufactor Manufactor { get; set; }
public virtual ICollection<Car> CarsOnDealership { get; set; }
}
public class Car
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ManufactorOnDealership> Manufactors { get; set; }
}

MVC3 Dynamic DataAnnotation attribute StringLength

UPDATE #3: Entire question
I have a class HB:
public class HB
{
public int Id { get; set; }
[StringLength(3000)]
public string Text { get; set; }
public Title Title { get; set; }
}
And Title:
public class Title
{
public int Id { get; set; }
public string Name { get; set; }
public int MaxChar { get; set; }
}
Before you can write a HB (which is kind of an article), you have to choose your title, so your StringLength for HB.Text can be determined. Meaning, this article can only have a certain amount of chars, deppending on what 'Title' the writer has. Example: Title1 can only write a 'HB' with 1000 chars, and Title2 can write a 'HB' with 3000 chars. So. Thats means the the StringLength has to come from Title.MaxChar. Whats the smartest way to do that?
The Title entity is prefixed data that will be stored in the db.
To be crystal clear, what I want to achieve is something in the line with: [StringLength(Title.MaxChar)]
Ive done structure/design for this mechanism in Webforms a million times, my brain just cant addapt to mvc, so some help would be appreciated. Code would be even more appreciated.
Pretty sure that is not possible as written. This strikes me as trying to force business logic into the model that belongs in the controller.
In this situation, I would make the attribute on the Text property [StringLength(3000)]. In the controller, during validation, I would write something along these lines:
public ActionResult (HB model)
{
if (model.Text.Length > model.Title.MaxChar){
ModelState.AddModelError("Text", string.Format("Text for this Title cannot exceed {0} characters.", model.Title.MaxChar));
}
if (ModelState.IsValid)
{
//do stuff
return RedirectToAction("Index"); //or something
}
else
{
return View(model);
}
}
I believe this will accomplish what you are trying to do. Now, for the Title object, I'd flatten that out a bit in your model:
public class HB
{
#region Base Properties
public int Id { get; set; }
[StringLength(3000)]
public string Text { get; set; }
#endregion
#region Title Properties
public int TitleId { get; set; }
public string TitleName { get; set; }
public int TitleMaxChar { get; set; }
#endregion
}
This is assuming you need to display that information in your view. If you just need to reference it for your business logic validation, just have the TitleId property and use that to instantiate the Title object in your controller when you need it. Don't forget to make hidden inputs for each of these properties if they are not editable!

Resources