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

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

Related

How can I store multiple images in a database with a Blazor application?

I have an application that shows a form to the users. The form is taken by the server and stored in a database where the information can be read on another page in the application. Part of the form takes an image, where the image is converted to a Base64 string and sent to Azure to be stored, and the URL to the image is stored in the database as a string. This all works fine. My trouble comes from trying to implement a feature where users can select multiple images.
I tried changing the string Image {get;set;} to a List<string> {get;set;} where the database would just store a list of the URLs where I could iterate through them in the application. This obviously did not work, as through some research, I learned that databases cannot store lists.
I am now wondering what I can do here. Is there a simpler way of doing this that I'm missing? What am I doing wrong?
I tried changing the string Image {get;set;} to a List
{get;set;} where the database would just store a list of the URLs
where I could iterate through them in the application. This obviously
did not work, as through some research, I learned that databases
cannot store lists.
You can try to use the following methods:
Add separator between the Image urls. Use string Image {get;set;} to store the image urls, the value like this: "image1url,image2url,etc" (use the , as the separator). You can consider using the String.Join Method.
Create a new Image table to store the Image information (contains ID, Name, Urls), then configure one-to-many relationship between the Main table and the Image model. In the Main model, use navigation property to add the Image. Code like this:
public class Main
{
public int Id { get; set; }
public string Name { get; set; }
public List<Image> Images { get; set; }
}
public class Image
{
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
}
More detail information about the Entity relationship, see:
Relationships
Configuring One To Many Relationships in Entity Framework Core
Saving Related Data

Ignore certain ViewModel properties in API requests?

Suppose I have the following example Resource Model defined for API Create/Read/Update/Delete interactions involving the Customer types:
public class CustomerModel
{
public string Address { get; set; }
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Url]
public Uri Website { get; set; }
public DateTimeOffset WhenCreated { get; set; }
public DateTimeOffset WhenUpdated { get; set; }
}
Id, WhenCreated, and WhenUpdated are metadata to be generated by the underlying data repository and as such, if the customer adds them to a request they should not be kept (Id for example, would be specified in the URL so no need to include in the request body). However, these values are still important to the client.
Is there a simple approach to ignoring these metadata attributes if sent in the client request? I would expect this in the form of an attribute but have not found anything promising for .NET Core 3.1.
The JsonIgnore attribute would make sense but it wouldn't serialize the values in responses either.
I could create a separate model only used by clients for requests but this seems redundant, especially because it will require new mapping profiles. However, if using something like Swashbuckle for API documentation this could be the best approach since the class documentation wouldn't represent those as valid properties for requests.
I could add some logic to remove those properties in the business logic layer but that would likely involve another request to the database to retrieve their original values so it isn't ideal.
Thank you!

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

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.

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

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; }
}

Resources