Sitecore MVC model lost after postback - sitecore

I have a page /registration that contains two forms on it.
One for registration and one for logging in. The registration form is one controller rendering, the login form is another controller rendering.
When I load /registration the page loads correctly and the model is populated.
When I click the submit button, the Post action fires and the model is suddenly reset back to it's default state. Shouldn't the model remain populated without having to repopulate it?
My model:
using Glass.Mapper.Sc.Configuration;
using Glass.Mapper.Sc.Configuration.Attributes;
using Sitecore.Data.Items;
using Sitecore.Mvc.Presentation;
using System;
using System.Collections.Generic;
namespace MySite.Models.Items
{
public class Registration: IRenderingModel
{
public Registration()
{
FirstName = string.Empty;
LastName = string.Empty;
Email = string.Empty;
JobTitle = string.Empty;
Company = string.Empty;
Industry = string.Empty;
SubIndustry = string.Empty;
RevenueRange = string.Empty;
Country = string.Empty;
StateProvince = string.Empty;
MarketoTracking = string.Empty;
ReturnUrl = string.Empty;
}
public Rendering Rendering { get; set; }
public Item Item { get; set; }
public Item PageItem { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string JobTitle { get; set; }
public string Company { get; set; }
public string Industry { get; set; }
public string SubIndustry { get; set; }
public string RevenueRange { get; set; }
public string Country { get; set; }
public string StateProvince { get; set; }
public string MarketoTracking { get; set; }
public string ReturnUrl { get; set; }
#region "Country List"
public IEnumerable<CountryChildItem> CountryList { get; set; }
public string CountryChildMenu { get; set; }
[SitecoreType(AutoMap = true)]
public class CountryItem
{
public virtual IEnumerable<CountryChildItem> Children { get; set; }
}
[SitecoreType(AutoMap = true)]
public class CountryChildItem
{
[SitecoreId]
public virtual Guid Id { get; set; }
[SitecoreInfo(SitecoreInfoType.Path)]
public virtual string Path { get; set; }
[SitecoreField]
public virtual string DisplayName { get; set; }
[SitecoreField]
public virtual string Abbreviation { get; set; }
[SitecoreField]
public virtual string SortOrder { get; set; }
}
#endregion
#region "State / Province List"
public IEnumerable<StateProvinceChildItem> StateProvinceList { get; set; }
public class StateProvinceItem
{
public virtual IEnumerable<StateProvinceChildItem> Children { get; set; }
}
[SitecoreType(AutoMap = true)]
public class StateProvinceChildItem
{
[SitecoreId]
public virtual Guid Id { get; set; }
[SitecoreInfo(SitecoreInfoType.Path)]
public virtual string Path { get; set; }
[SitecoreField]
public virtual string DisplayName { get; set; }
[SitecoreField]
public virtual string Abbreviation { get; set; }
[SitecoreField]
public virtual string ParentCountry { get; set; }
[SitecoreField]
public virtual string SortOrder { get; set; }
}
#endregion
#region "Industry List"
public IEnumerable<IndustryChildItem> IndustryList { get; set; }
public string IndustryChildMenu { get; set; }
public class IndustryItem
{
public virtual IEnumerable<IndustryChildItem> Children { get; set; }
}
[SitecoreType(AutoMap = true)]
public class IndustryChildItem
{
[SitecoreId]
public virtual Guid Id { get; set; }
[SitecoreInfo(SitecoreInfoType.Path)]
public virtual string Path { get; set; }
[SitecoreField]
public virtual string DisplayName { get; set; }
[SitecoreField]
public virtual string SortOrder { get; set; }
}
#endregion
#region "Sub-industry List"
public IEnumerable<SubIndustryChildItem> SubIndustryList { get; set; }
public class SubIndustryItem
{
public virtual IEnumerable<SubIndustryChildItem> Children { get; set; }
}
[SitecoreType(AutoMap = true)]
public class SubIndustryChildItem
{
[SitecoreId]
public virtual Guid Id { get; set; }
[SitecoreInfo(SitecoreInfoType.Path)]
public virtual string Path { get; set; }
[SitecoreField]
public virtual string DisplayName { get; set; }
[SitecoreField]
public virtual string ParentIndustry { get; set; }
[SitecoreField]
public virtual string SortOrder { get; set; }
}
#endregion
#region "Revenue List"
public IEnumerable<RevenueChildItem> RevenueList { get; set; }
public class RevenueItem
{
public virtual IEnumerable<RevenueChildItem> Children { get; set; }
}
[SitecoreType(AutoMap = true)]
public class RevenueChildItem
{
[SitecoreId]
public virtual Guid Id { get; set; }
[SitecoreInfo(SitecoreInfoType.Path)]
public virtual string Path { get; set; }
[SitecoreField]
public virtual string DisplayName { get; set; }
[SitecoreField]
public virtual string SortOrder { get; set; }
}
#endregion
public void Initialize(Rendering rendering)
{
Rendering = rendering;
Item = rendering.Item;
PageItem = PageContext.Current.Item;
}
}
}
My view:
using Glass.Mapper.Sc;
using MySite.Analytics;
using MySite.Models.Items;
using Newtonsoft.Json.Linq;
using Sitecore.Diagnostics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace MySite.Presentation.Controllers
{
public class RegistrationController : AsyncController
{
Registration registration = new Registration();
[HttpGet]
public PartialViewResult Index(string view)
{
if (!string.IsNullOrWhiteSpace(view))
{
registration.ReturnUrl = view.Trim();
}
if (string.IsNullOrEmpty(registration.ReturnUrl) && Request.UrlReferrer != null)
{
registration.ReturnUrl = Server.UrlDecode(Request.UrlReferrer.AbsoluteUri ?? string.Empty);
}
PopulateLists();
return PartialView(registration);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(string RegistrationButton, FormCollection formCollection)
{
if (!string.IsNullOrEmpty(RegistrationButton))
{
try
{
registration.FirstName = formCollection["FirstName"].Trim();
registration.LastName = formCollection["LastName"].Trim();
registration.Email = formCollection["Email"].Trim();
registration.JobTitle = formCollection["JobTitle"].Trim();
registration.Company = formCollection["Company"].Trim();
registration.Industry = formCollection["Industry"].Trim();
registration.SubIndustry = formCollection["SubIndustry"].Trim();
registration.RevenueRange = formCollection["RevenueRange"].Trim();
registration.Country = formCollection["Country"].Trim();
registration.StateProvince = formCollection["StateProvince"].Trim();
registration.MarketoTracking = formCollection["_mkt_trk"].Trim();
ContactManagement contactManagement = new ContactManagement();
contactManagement.RegisterContact(registration);
}
catch (Exception ex)
{
Log.Error("MySite.Presentation.Controllers.RegistrationController.Index", ex, this);
}
}
return PartialView();
}
public void PopulateLists()
{
ISitecoreContext sitecoreContext = new SitecoreContext();
ISitecoreService service = new SitecoreService(sitecoreContext.Database);
Guid countryItemID = new Guid("{2FB5AE2D-E80D-4A3D-9201-3E62E781EFCD}");
Registration.CountryItem countryItem = service.GetItem<Registration.CountryItem>(countryItemID);
registration.CountryList = countryItem.Children.OrderBy(l => System.Convert.ToInt32(l.SortOrder)).ThenBy(l => l.DisplayName);
Guid stateProvinceItemID = new Guid("{6171F149-0200-4010-BF5F-5F32EAAE31B4}");
Registration.StateProvinceItem stateProvinceItem = service.GetItem<Registration.StateProvinceItem>(stateProvinceItemID);
registration.StateProvinceList = stateProvinceItem.Children.OrderBy(l => System.Convert.ToInt32(l.SortOrder)).ThenBy(l => l.DisplayName);
Guid industryItemID = new Guid("{ACD77146-0530-4EEE-A477-BF8CD54B9FFE}");
Registration.IndustryItem industryItem = service.GetItem<Registration.IndustryItem>(industryItemID);
registration.IndustryList = industryItem.Children.OrderBy(l => System.Convert.ToInt32(l.SortOrder)).ThenBy(l => l.DisplayName);
Guid subIndustryItemID = new Guid("{43AAABDF-9591-4F03-9894-0EAEFD1292B3}");
Registration.SubIndustryItem subIndustryItem = service.GetItem<Registration.SubIndustryItem>(subIndustryItemID);
registration.SubIndustryList = subIndustryItem.Children.OrderBy(l => System.Convert.ToInt32(l.SortOrder)).ThenBy(l => l.DisplayName);
Guid revenueItemID = new Guid("{86C0FF05-5A9C-4113-BEE6-B68E19BAAB37}");
Registration.RevenueItem revenueItem = service.GetItem<Registration.RevenueItem>(revenueItemID);
registration.RevenueList = revenueItem.Children.OrderBy(l => System.Convert.ToInt32(l.SortOrder)).ThenBy(l => l.DisplayName);
}
public string GetChildList(string countryDisplayName, IEnumerable<Registration.StateProvinceChildItem> stateProvinceChildItem)
{
string menuString = string.Empty;
if (stateProvinceChildItem != null)
{
JArray menuArray = new JArray();
foreach (var state in stateProvinceChildItem)
{
if (state.ParentCountry == countryDisplayName)
{
JValue menuItem = new JValue("{\"name\": \"" + state.DisplayName + " (" + state.Abbreviation + ")\", \"value\": \"" + state.Abbreviation + "\"}");
menuArray.Add(menuItem);
}
}
if (menuArray.Count > 0)
{
menuString = "data-child-menu='{\"items\": " + menuArray.ToString() + "}'";
}
}
return menuString;
}
public string GetChildList(string industryId, IEnumerable<Registration.SubIndustryChildItem> subIndustryChildItem)
{
string menuString = string.Empty;
if (subIndustryChildItem != null)
{
JArray menuArray = new JArray();
foreach (var subIndustry in subIndustryChildItem)
{
if (subIndustry.ParentIndustry.Trim().ToUpperInvariant().Contains(industryId.Trim().ToUpperInvariant()))
{
JValue menuItem = new JValue("{\"name\": \"" + subIndustry.DisplayName + "\", \"value\": \"" + subIndustry.DisplayName + "\"}");
menuArray.Add(menuItem);
}
}
if (menuArray.Count > 0)
{
menuString = #"data-child-menu='{""items"": " + menuArray.ToString() + "}'";
}
}
return menuString;
}
}
}

There is currently a problem with Sitecore MVC and having multiple forms. I believe the problem is that you have [HttpGet] set to your Index action which might mess the Sitecore Routing. You can check for more problems with multiple forms in this blog post.

Related

How to process "data" part of GCP PubSub message into a HashMap?

I'm getting pubsub message as below :
{
"data": {
"systemId": "system-1",
"userId": "userId-1",
"departmentId": "090",
"enrolmentDateTime": "2022-08-19T15:44:29.080Z",
"event_type": "REGISTRATION"
}
}
I want to further process this message in my springboot application based on the "event_type".
How can I just fetch "event_type" from this message and use it for comparison?
Any suggestions?
For eg I want to have processing like this :
if(event_type.equals("REGISTRATION")) { registrationHandler.handle(message); else { }
I have tried converting a PubSubMessage into string and then further map it to HashMap using ObjectMapper, but that gives me "data" as key and rest of the json part as a value.
public void process(final PubsubMessage message) throws ConsumerException {
String data = message.getData().toStringUtf8();
try {
ObjectMapper mapper = new ObjectMapper();
HashMap<String, String> dataMap = mapper.readValue(data, HashMap.class);
} ....
Instead of using a Map, you can use a typed object, example :
PubSubData.java file :
public class PubSubData {
private String systemId;
private String userId;
private String departmentId;
private String enrolmentDateTime;
private String event_type;
public PubSubData() {
}
public String getSystemId() {
return systemId;
}
public void setSystemId(String systemId) {
this.systemId = systemId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getDepartmentId() {
return departmentId;
}
public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}
public String getEnrolmentDateTime() {
return enrolmentDateTime;
}
public void setEnrolmentDateTime(String enrolmentDateTime) {
this.enrolmentDateTime = enrolmentDateTime;
}
public String getEvent_type() {
return event_type;
}
public void setEvent_type(String event_type) {
this.event_type = event_type;
}
}
PubSubResult.java file :
public class PubSubResult {
private PubSubData data;
public PubSubResult() {
}
public PubSubData getData() {
return data;
}
public void setData(PubSubData data) {
this.data = data;
}
}
Example of an unit test that deserializes data from PubsubMessage to the PubSubResult object :
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.google.protobuf.ByteString;
import com.google.pubsub.v1.PubsubMessage;
import org.junit.Test;
public class MyTest {
private static final ObjectMapper OBJECT_MAPPER;
static {
final ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
OBJECT_MAPPER = mapper;
}
#Test
public void testDeserializePubSubData() {
final String data = "{\n" +
" \"data\": {\n" +
" \"systemId\": \"system-1\",\n" +
" \"userId\": \"userId-1\",\n" +
" \"departmentId\": \"090\",\n" +
" \"enrolmentDateTime\": \"2022-08-19T15:44:29.080Z\",\n" +
" \"event_type\": \"REGISTRATION\"\n" +
" }\n" +
"}";
final PubsubMessage message = PubsubMessage.newBuilder()
.setData(ByteString.copyFrom(data.getBytes()))
.build();
final String dataResult = message.getData().toStringUtf8();
final PubSubResult resultData = deserialize(dataResult);
// Access to the event type.
final String eventType = resultData.getData().getEvent_type();
}
private PubSubResult deserialize(final String value) {
try {
return OBJECT_MAPPER.readValue(value, PubSubResult.class);
} catch (JsonProcessingException e) {
throw new IllegalStateException("Error !!", e);
}
}
}

Having a composition relationship in ASP .NET?

I have a Car composed by a Driver. I have problems showing either informations on the gridview. It's only shows Car's info. on the gridview, and I wanna display like: Car: Lancia Driver: Sandro, something like that.
Here's the code:
Car:
[Serializable]
public class Car
{
public String Brand { get; set; }
public String Model { get; set; }
public int Year { get; set; }
public Driver Driver { get; set; }
public Car(String Brand, String Model, int Year, Driver Driver)
{
Brand = Brand;
Model = Model;
Year = Year;
Driver = Driver;
}
public Car()
{
Init();
}
public void Init()
{
Brand = string.Empty;
Model = string.Empty;
Year = 0;
Driver = new Driver();
}
Driver:
[Serializable]
public class Driver
{
public String Name { get; set; }
public int Age { get; set; }
public String Nationality { get; set; }
public Driver(String Name, int Age, String Nationality)
{
Name = Name;
Age = Age;
Nationality = Nationality;
}
public Driver()
{
Init();
}
public void Init()
{
Name = string.Empty;
Age = 0;
Nationality = string.Empty;
}
}
aspx.cs:
public partial class WebForm1 : System.Web.UI.Page
{
//private ArrayList garageList;
private List<Car> garageList;
private static int counterPost = 0;
private static int counterLoad = 0;
public void Page_Load(object sender, EventArgs e)
{
TextBox masterTextLoad = (TextBox) Master.FindControl("txtLoad");
masterTextLoad.Text = Convert.ToString(counterLoad++);
if (IsPostBack)
{
TextBox masterTextPost = (TextBox) Master.FindControl("txtPost");
masterTextPost.Text = Convert.ToString(counterPost++);
garageList = (List<Car>)ViewState["Cars"];
//garageList = (ArrayList) ViewState["Cars"];
if (garageList == null)
{
//garageList = new ArrayList();
garageList = new List<Car>();
}
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
//Driver
Driver driver = new Driver();
TextBox driverName = (TextBox) Master.FindControl("txtName");
driver.Name = driverName.Text;
TextBox driverAge = (TextBox) Master.FindControl("txtAge");
driver.Age = Convert.ToInt32(driverAge.Text);
TextBox driverNationality = (TextBox)Master.FindControl("txtNationality");
driver.Nationality = driverNationality.Text;
//Car
Car car = new Car();
car.Brand = txtBrand.Text;
car.Model = txtModel.Text;
car.Year = Int32.Parse(txtYear.Text);
garageList.Add(car);
//ViewState["Cars"] = garageList;
ViewState["garageList"] = garageList;
cleanControls();
}
private void cleanControls()
{
//Cleaning driver controls
TextBox masterTextPost = (TextBox)Master.FindControl("txtPost");
masterTextPost.Text = string.Empty;
TextBox driverName = (TextBox)Master.FindControl("txtName");
driverName.Text = string.Empty;
TextBox driverAge = (TextBox)Master.FindControl("txtAge");
driverAge.Text= string.Empty;
TextBox driverNationality = (TextBox)Master.FindControl("txtNationality");
driverNationality.Text = string.Empty;
//Cleaning Car controls
txtBrand.Text = String.Empty;
txtModel.Text = String.Empty;
txtYear.Text = String.Empty;
}
protected void btnShow_Click1(object sender, EventArgs e)
{
grvShow.AutoGenerateColumns = true;
grvShow.DataSource = garageList;
grvShow.DataBind();
//grvShow.Visible = true;
}
}

Using a class in a static arrayed list C#

Here is what i would want to accomplish - i want this class globally accessible, and i need 6 instances of it. So basically it should be something like List[6] which would be initalized in a public static class...
class HH
{
public string hand { get; set; }
public string user { get; set; }
public int z { get; set; }
public int bb { get; set; }
public int eff { get; set; }
public int pos { get; set; }
public string pre { get; set; }
public string f { get; set; }
public string t { get; set; }
public string r { get; set; }
}
public static class tx
{
public static List<HH>[] HH = new List<HH>[6];
}
Now obv. this is wrong - but maybe you get the idea what i try to accomplish. Could someone give me an idea how i can accomplish that so that in my code i can access the elements of the class and read and write from and to it?
"public static List[] HH = new List[6];"
I think this is not enough. You only initialized the array, but HH objects left. After that code, you may write a loop to instantiate every HH object.
I hope that would be helpful. But if not, it may be great if you can provide more detail.
:)
You can do something like this:
public static class TX
{
public static List<HH> _HH { get; private set; }
static TX()
{
_HH = new List<HH>()
{
new HH(), new HH(), new HH(),
new HH(), new HH(), new HH()
};
}
internal class HH
{
public string hand { get; set; }
public string user { get; set; }
public int z { get; set; }
public int bb { get; set; }
public int eff { get; set; }
public int pos { get; set; }
public string pre { get; set; }
public string f { get; set; }
public string t { get; set; }
public string r { get; set; }
}
}
And use it like :
var hand = TX._HH[0].hand;

Error on Spring REST webservice call

I have following webservice call
#RequestMapping(value = "modifyUser/{userDn}", method = RequestMethod.POST, headers="Accept=application/json")
public #ResponseBody
JSONObject modifyUser(#PathVariable String userDn, #RequestBody DirectoryUser directoryUser) {
// Modify User
boolean modifiedUser = this.authenticationService.modifyUser(userDn, directoryUser.getPassword(), directoryUser);
// Build JSONObject
JSONObject jsonObject = new JSONObject();
jsonObject.put("modifyUser", modifiedUser);
return jsonObject;
}
I am using following client method to access above REST webservice.
String url = "http://www.local.com:8080/CommonAuth-1.0-SNAPSHOT/api/authentication/modifyUser/";
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url + "user6.external")
JSONObject ob = new JSONObject();
ob.put("description", "updated");
System.out.println(ob.toString());
StringEntity entity = new StringEntity(ob.toString());
entity.setContentType("application/json");
httpPost.setEntity(entity);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
I always get "The server refused this request because the request entity is in a format not supported by the requested resource for the requested method" error. What is wrong in my code. I am able to access other webservice calls without using #RequestBody and using simple path variables. The issue is with #RequestBody and how i am using HttpPost.
public class DirectoryUser {
private String displayName;
private String fullName;
private String userName;
private String firstName;
private String lastName;
private String description;
private String country;
private String company;
private String phone;
private String emailAddress;
private String password;
private boolean expirePassword = true;
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isExpirePassword() {
return expirePassword;
}
public void setExpirePassword(boolean expirePassword) {
this.expirePassword = expirePassword;
}
}
JSON string i am posting is {"description":"updated"}
try {
/* your code */
if (httpResponse != null) {
InputStream in = httpResponse.getEntity().getContent();
StringBuffer out = new StringBuffer();
int n = 1;
while (n > 0) {
byte[] b = new byte[4096];
n = in.read(b);
if (n > 0)
out.append(new String(b, 0, n));
}
System.out.println(out.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
Can you check what the status code says? Also, please check if it is HTTPS.
By default Spring try to use Jackson for json marshall/unmarshall:
private static final boolean jackson2Present =
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", WebMvcConfigurationSupport.class.getClassLoader()) &&
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", WebMvcConfigurationSupport.class.getClassLoader());
you need to add Jackson libs to your project.

List Serialization and Deserialization by binary formatter

I have a class. I wanna serialize and the serialize a list that contains object of that class. I want to use binary formatter.
This is my class:
[Serializable]
public class Section :ISerializable
{
private double ClearCover;
private string SectionName;
private double Diameter;
public double Height;
private double Width;
private double InternalDiameter;
private double ExternalDiameter;
private double InternalHeight;
private double ExternalHeight;
private double InternalWidth;
private double ExternalWidth;
private double WebWidth;
private double FlangeWidth;
private double FlangeThickness;
public double clearCover
{
get { return ClearCover; }
set { ClearCover = value; }
}
public string sectionName
{
get{return SectionName;}
set{SectionName=value;}
}
public double diameter
{
get { return Diameter; }
set { Diameter = value; }
}
public double height
{
set { Height = value; }
get { return Height; }
}
public double width
{
set { Width = value; }
get { return Width; }
}
public double internalDiameter
{
set { InternalDiameter = value; }
get { return InternalDiameter; }
}
public double externalDiameter
{
set { ExternalDiameter = value; }
get { return ExternalDiameter; }
}
public double internalHeight
{
set { InternalHeight = value; }
get { return InternalHeight; }
}
public double externalHeight
{
set { ExternalHeight = value; }
get { return ExternalHeight; }
}
public double internalWidth
{
set { InternalWidth = value; }
get { return InternalWidth; }
}
public double externalWidth
{
set { ExternalWidth = value; }
get { return ExternalWidth; }
}
public double flangeWidth
{
set { FlangeWidth = value; }
get { return FlangeWidth; }
}
public double flangeThickness
{
set { FlangeThickness = value; }
get { return FlangeThickness; }
}
public double webWidth
{
set { WebWidth = value; }
get { return WebWidth; }
}
public Section() { }
protected Section(SerializationInfo info, StreamingContext context)
{
sectionName = info.GetString("Section Name");
clearCover = info.GetDouble("Clear Cover");
diameter = info.GetDouble("Diameter");
//internalDiameter = info.GetDouble("Internal Diameter");
//externalDiameter = info.GetDouble("External Diameter");
height = info.GetDouble("Height");
width = info.GetDouble("Width");
internalHeight = info.GetDouble("Internal Height");
externalHeight = info.GetDouble("External Height");
internalWidth = info.GetDouble("Internal Width");
externalWidth = info.GetDouble("External Width");
flangeWidth = info.GetDouble("Flange Width");
flangeThickness = info.GetDouble("Flange Thickness");
webWidth = info.GetDouble("Web Width");
}
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Section Name", sectionName);
info.AddValue("Clear Cover", clearCover);
info.AddValue("Diameter",diameter);
//info.AddValue("Internal Diameter", internalDiameter);
//info.AddValue("External Diameter", externalDiameter);
info.AddValue("Height",height);
info.AddValue("Width",width);
info.AddValue("Internal Height",internalHeight);
info.AddValue("External Height",externalHeight);
info.AddValue("Internal Width",internalWidth);
info.AddValue("External Width",externalWidth);
info.AddValue("Flange Width",flangeWidth);
info.AddValue("Flange Thickness", flangeThickness);
info.AddValue("Web Width", webWidth);
}
}
I don't have any problem in serialization. But for deserialize, it can just deserialize first object not all of them. What should I do, please help me!
From a separate email from the OP, the following methods were obtained (I've tidied them a little, not much):
static void Serialize(object obj, string filename)
{
using (FileStream streamOut = new FileStream(filename, FileMode.Append))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(streamOut, obj);
}
}
public static List<Section> DeserializeList(string filename)
{
using (FileStream streamIn = File.OpenRead(filename))
{
BinaryFormatter formatter = new BinaryFormatter();
return (List<Section>) formatter.Deserialize(streamIn);
}
}
The key observation here is that it is assuming that BinaryFormatter is an appendable format, and that serializing two objects sequentially is the same as serializing 2 items at the same time (a list), for example:
if(File.Exists("foo.bin")) File.Delete("foo.bin"); // start afresh
Serialize(new Section { Diameter = 1.2, ClearCover = 3.4 }, "foo.bin");
Serialize(new Section { Diameter = 5.6, ClearCover = 7.8 }, "foo.bin");
var clone = DeserializeList("foo.bin");
However, that simply is not the case. To deserialize the items in this way, we would have to do something like:
public static List<Section> DeserializeList(string filename)
{
using (FileStream streamIn = File.OpenRead(filename))
{
List<Section> list = new List<Section>();
BinaryFormatter formatter = new BinaryFormatter();
while(streamIn.Position != streamIn.Length)
{
list.Add((Section) formatter.Deserialize(streamIn));
}
return list;
}
}
which it a little vexing - not least because it can't be applied to all streams (.Length and even .Position are not universally available).
The above should work, but I would strongly advise using an appendable format, such as protobuf. In fact, protobuf-net makes this scenario effortless, both in terms of the model:
[ProtoContract]
public class Section
{
[ProtoMember(1)] public double ClearCover { get; set; }
[ProtoMember(2)] public string SectionName { get; set; }
[ProtoMember(3)] public double Diameter { get; set; }
[ProtoMember(4)] public double Height { get; set; }
[ProtoMember(5)] public double Width { get; set; }
[ProtoMember(6)] public double InternalDiameter { get; set; }
[ProtoMember(7)] public double ExternalDiameter { get; set; }
[ProtoMember(8)] public double InternalHeight { get; set; }
[ProtoMember(9)] public double ExternalHeight { get; set; }
[ProtoMember(10)] public double InternalWidth { get; set; }
[ProtoMember(11)] public double ExternalWidth { get; set; }
[ProtoMember(12)] public double FlangeWidth { get; set; }
[ProtoMember(13)] public double FlangeThickness { get; set; }
[ProtoMember(14)] public double WebWidth { get; set; }
}
and the serialization / deserialization:
static void Main()
{
if (File.Exists("foo.bin")) File.Delete("foo.bin"); // start afresh
Serialize(new Section { Diameter = 1.2, ClearCover = 3.4 }, "foo.bin");
Serialize(new Section { Diameter = 5.6, ClearCover = 7.8 }, "foo.bin");
var clone = DeserializeList("foo.bin");
}
static void Serialize(object obj, string filename)
{
using (FileStream streamOut = new FileStream(filename, FileMode.Append))
{
Serializer.NonGeneric.SerializeWithLengthPrefix(
streamOut, obj, PrefixStyle.Base128, Serializer.ListItemTag);
}
}
public static List<Section> DeserializeList(string filename)
{
using (FileStream streamIn = File.OpenRead(filename))
{
return Serializer.DeserializeItems<Section>(
streamIn, PrefixStyle.Base128, Serializer.ListItemTag).ToList();
}
}
Finally, the BinaryFormatter data for those 2 rows was 750 bytes; with protobuf-net: 40 bytes.