How to edit a SQL Server XML data field with asp.net Dynamic Data - asp.net

I have a site based around asp.net 3.5's Dynamic Data feature. Everything's working great, but I would like to add a tagging feature via a column with an XML data type. I've made the column and added an appropriate schema, but it is showing up as read-only and the scaffold will not display or modify the field.
So, I have a few questions:
What do I need to do in order to enable my scaffold to see this xml column?
How would I go about editing the tags through the scaffold without directly editing all the xml?
Would I add logic to the getter/setter in the metadata?
Presumably I would need a custom fieldTemplate, would I add the xml parsing to it?

I hope this is helpful. As you mention, you would have to create a field template for your XML data. :
[MetadataType(typeof(DocumentMetadata))]
[DisplayName("Documents")]
public partial class Document {
[ScaffoldColumn(true)]
[Display(Name = "Some Xml")]
public string SomeXml
{
get
{
return "<note><to>Joe</to><from>Mary</from><heading>Reminder</heading><body>Hello World</body></note>"
}
}
}
public class DocumentMetadata
{
[ScaffoldColumn(false)]
public object Id { get; set; }
[Display(Name="Type")]
public object DocumentType { get; set; }
[UIHint("CustomXmlFieldTemplate")]
[Display(Name="Some XML")]
public object SomeXml { get; set; }
}

Related

How can I serialize data to XML without .xsd schema?

I am writing an ASP.NET MVC (5) application in which I need to do some custom XML serialization. Before I go on, I should mention that I wasn't exactly sure if this question belongs here or on another forum. If this question would be better suited somewhere else, please let me know. I'll gladly move it.
Software overview:
I have a view that has a form for the user to fill out. When the user fills out the required fields and clicks the submit button, the information in the form should be serialized to XML (based on certain XML requirements), and posted to a URL. That's pretty simple for some, I'm sure. I have very little experience doing this sort of thing in ASP.NET MVC.
I don't possess the .xsd document that contains the XML schema. I have a document that contains the XML specifics (a Word document), but the actual .xsd document is not available to me. I am not sure how to serialize the data so that the XML turns out the way it is supposed to.
I have the following Model:
public class BookingRequest
{
public string billTo { get; set; }
public string bookingStatus { get; set; }
public string partNote { get; set; }
public int height { get; set; }
}
Note that this is an abbreviated version; there are WAY more fields in this class. Anyway, I need the height field to look like this when it is serialized to XML:
<HeightOf>15</HeightOf>
I also need all of the elements in the XML to adhere to this schema (where all of the fields in the form I mentioned fall under the <BookingRequest> tag):
<Data>
<Header>
<UserId/>
<Password/>
</Header>
<BookingRequest>
..
..
</BookingRequest>
</Data>
Can I do this without the schema?
Any help is greatly appreciated.
You don't need the xsd, as long as you know how is going to be the desired structure.
First, you need to decorate your class with the [Serializable] attribute. Then, you can use the attributes in System.Xml.Serialization namespace to control the result. For example, in case of height property, it can be achieve like this:
[Serializable]
public class BookingRequest
{
public string billTo { get; set; }
public string bookingStatus { get; set; }
public string partNote { get; set; }
[XmlElement(ElementName = "HeightOf")]
public int height { get; set; }
}
See this for further details:
https://learn.microsoft.com/en-us/dotnet/standard/serialization/controlling-xml-serialization-using-attributes

Form Fields generated based on variable types

I have a project utilizing ASP.NET MVC and Razor page layouts. The page in question will be a survey whose questions, datatypes, and answers have been configured by an admin user and retrieved from a database. For example:
public class ExampleViewModel
{
//the user define dquestion
public string Question1Text { get; set; }
//this is an enum with "Text","YesNo","DropDown"
public AnswerType Question1Type { get; set; }
//this would hold options for the drop down list
public string Question1Options { get; set; }
//the user input answer
public string Question1Answer { get; set; }
}
What I am not sure is how to structure the Razor view to create the appropriate type of form input field depending on the AnswerType. I seem to recall something about creating templates for the various DataType() annotations but I am not sure where to start looking at that and if that applies in this case?
You want to use Templated Helpers - Here is a good walkthrough - http://www.hanselman.com/blog/ASPNETMVCDisplayTemplateAndEditorTemplatesForEntityFrameworkDbGeographySpatialTypes.aspx
In the helper itself you can do stuff like:
#if (model.AnswerType is xxx)
{
<button> xxx </button> - or your html
}
etc

Dynamic Data Web Site, how to leave out columns?

I used VS 2012 to create a Dynamic Data Web Site using the standard built in template. Using EF I have added the database to the project that I want to use, and only selected the tables I saw fit for managing data through a web site. On the first page, you get the list of tables, when you click on one of those tables, it brings up a list of everything that's in that table(rows and columns). I'm very new to doing this type of thing and I'm wondering how I can make it so only certain COLUMNS appear. I want to do this because when you click on a table, if there are more columns than a few, they drag way off the right side of the browser. So basically I just want to display only columns that I think will be relevant. BTW, this project is in ASP.NET using EF for the data model. I still want these columns to be viewable when you click on the "Details" link for the row you want to see, I just want them to not show up in the list view. How can I do this, and what files do I need to modify?
You can leave out columns by using the [ScaffoldColumn(false)] data annotation attribute. I have a similar case where I do not want to include the CreatedBy, CreatedOn, UpdatedBy, and UpdatedOn columns. See the code sample to see how to exclude them.
using System;
using System.ComponentModel.DataAnnotations;
namespace S1000DDecision.Data
{
/// <summary>
/// Summary description for Category
/// </summary>
[ScaffoldTable(true)]
[MetadataType(typeof(CategoryMetadata))]
public partial class Category
{
}
public class CategoryMetadata
{
[ScaffoldColumn(false)]
public Object CreatedBy { get; set; }
[ScaffoldColumn(false)]
public Object CreatedOn { get; set; }
[ScaffoldColumn(false)]
public Object UpdatedBy { get; set; }
[ScaffoldColumn(false)]
public Object UpdatedOn { get; set; }
}
}

Save two Entities from one View

How to save two Entities from one View. Suppose I have two Entities Party and Person with One to Many relation. Now I need to save both Entities from Party View. I am using ASP.NET MVC4.
public partial class Cm_Opt_Pty_Party_S
{
public Cm_Opt_Pty_Party_S()
{
this.Cm_Opt_Psn_Person_S = new HashSet<Cm_Opt_Psn_Person_S>();
}
public int Pty_ID { get; set; }
public Nullable<int> Pty_PARTYTYPECODE { get; set; }
public string Pty_FULLNAME { get; set; }
public string Pty_GOVTID { get; set; }
public Nullable<int> Pty_GOVTIDTC { get; set; }
public Nullable<int> Pty_GOVTIDSTAT { get; set; }
public virtual ICollection<Cm_Opt_Psn_Person_S> Cm_Opt_Psn_Person_S { get; set; }
}
What you can do is create a ViewModel This class would contain the relevant properties needed to create both entities.
Then you base your View on the ViewModel instead, and pass that to the controller.
When you want to save the entities, you can build up the separate entities and save them.
I have a better understanding of your issue, so editing this answer to show the solution I would use.
Your Controller will deliver the Party object to your view for displaying the Party information. Using a loop you can display the items contained in the collection.
#foreach(var m in Model.Persons)
{
#Html.DisplayFor(model=>m.FirstName)
#Html.DisplayFor(model=>m.Surname)
}
When you want to add more items into the collection, you will need to render a partial view or new view containing a form for adding a Person. It will be strongly typed as Person model and the Controller action recieving the post will be expecting a Person
If for example a Person just had a FirstName,Surname and PartyId the form would use these helpers in your view
#Html.TextboxFor(m=>m.FirstName)
#Html.TextboxFor(m=>m.Surname)
#Html.TextBoxFor(m=>m.PartyId)
You then submit that back to your controller, and have logic for adding the person to the collection. Then return the view with Party model containing the newly added Person in the Persons collection.
Using #Ajax.BeginForm or some custom Jquery/Javascript you could handle this async to prevent page refreshing during the process.
If you don't want to do it this way, another option is EditorTemplates. See here for example: ASP.NET MVC LIST and Create in same view

How to preserve input ids when editing lists in ASP.NET MVC?

I'm working with ASP.NET MVC 4, but I on't think that matters for the purpose of this question.
I have a relatively complex model for my edit view. Like this:
public class Recipe_model
{
public string Name { get; set; }
public List<Recipe_Ingredient_model> Ingredients { get; set; }
}
where Ingredients is
public class Recipe_Ingredient_model
{
public int RecipeID { get; set; }
public int? UnitID { get; set; }
public double? Quantity { get; set; }
public Ingredient_model Ingredient { get; set; }
}
which itself contains the Ingredient model.
When I make a form for this, the built-in Html.EditorFor() doesn't work for anything past the properties of the Recipe_model, so I'm using partial views to display the editor for each of the sub-models.
That works fine as far the interface goes, but when I submit the form to the controller and try to bind to the Recipe_model automatically using
[HttpPost]
public ActionResult Edit(Recipe_model model)
{
return View(model);
}
it fails because the ids of the input elements in the partial views do not conform to the correct pattern (I think ParentModel_Property).
Short from hard-coding the ids in the partial view or binding manually from the FormCollection in the controller, is there some way to get the correct ids generated in the partial view so that the model will bind automatically on submit?
This is common problem. Instead of simple partials, use EditorTemplates (special folder for models) and binding will work automatically.
For example look at this question: Updating multiple items within same view
in addition to the answer given by #WebDeveloper
you can also try and create a custom model binder though a little more complex but will add to the ease of posting and binding form value to the objects in long run
have a look here http://patrickdesjardins.com/blog/asp-net-mvc-model-binding
you will have to manually take all the form values and bind them to the model once and then you will be able to use the #HtmlFrom methods on the razor to do anything and you will get all the value inside the objects inside the action methods as you like.

Resources