I am trying to serialize a list of (ValidationAttribute) as shown below:
RequiredAttribute tRequired = new RequiredAttribute();
List<ValidationAttribute> ValidationList = new List<ValidationAttribute>();
ValidationList.Add(tRequired);
XmlSerializer tXMLSerializer = new XmlSerializer(typeof(List<ValidationAttribute>));
MemoryStream tMemStream = new MemoryStream();
StreamWriter tStreamWriter = new StreamWriter(tMemStream);
tXMLSerializer.Serialize(tStreamWriter, ValidationList);
When the (Serialize) function execute, the following exception will be thrown:
The type System.ComponentModel.DataAnnotations.RequiredAttribute was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically
I have figured it out. I needed to pass the type of (RequiredAttribute) to the XMLSerializer:
RequiredAttribute tRequired = new RequiredAttribute();
List<ValidationAttribute> ValidationList = new List<ValidationAttribute>();
ValidationList.Add(tRequired);
Type[] tExtraTypes = new Type[] { typeof(RequiredAttribute) };
XmlSerializer tXMLSerializer = new XmlSerializer(typeof(List<ValidationAttribute>),tExtraTypes );
Related
I'm getting exception:
Inner Exception: Object reference not set to an instance of an object.
at Glass.Mapper.AbstractService.InstantiateObject(AbstractTypeCreationContext abstractTypeCreationContext)
At InstantiateObject the creation context it's not null, the item it's populated.
If I add the typeOf(TItem) then it crashes there at TItem cast, if I comment then it crashes at instatinate.
I tried to remove ConstructorParameter but even on that case it's crashing
The code before upgrade:
var creationContext = new SitecoreTypeCreationContext
{
SitecoreService = sitecoreContext,
RequestedType = typeof(TItem),
ConstructorParameters = new object[0],
Item = item,
InferType = false,
IsLazy = true,
Parameters = new Dictionary<string, object>()
};
var result = sitecoreContext.InstantiateObject(creationContext) as TItem;
The code after upgrade
var creationContext = new SitecoreTypeCreationContext
{
SitecoreService = mvcContext.SitecoreService,
Item = item,
Parameters = new Dictionary<string, object>(),
Options = new GetOptions()
{
//Type = typeof(TItem),
InferType = false,
Lazy = LazyLoading.Enabled,
ConstructorParameters = new List<ConstructorParameter>()
}
};
var result= mvcContext.SitecoreService.InstantiateObject(creationContext) as TItem;
I missed maybe a configuration or RequestedType it's not equal Option.Type?
i would like to reconstruction my last project.
in past, i did't use any Web API.
can i just use the ODataQueryOptions to do $filter, $orderby , $top ,$skip
for my query in my own handler.ashx ?
some thing like.
var option = new ODataQueryOptions(request.params);
var query = option.ApplyTo(db.products);
Based on sfuqua's answer above I made my own helper class that builds OdataQueryOptions class based on Odata Uri:
using System.Linq;
using System.Net.Http;
using System.Web.Http.OData;
using System.Web.Http.OData.Builder;
using System.Web.Http.OData.Query;
namespace OdataHelpers
{
public static class ODataBuilder<T>
{
public static ODataQueryOptions<T> BuildOptions(string oDataUri)
{
var baseUri = "";
var odUri = "";
var spl = oDataUri.Split('?');
if (spl.Count() == 0)
odUri = spl[0];
else
{
baseUri = spl[0];
odUri = spl[1];
}
if (string.IsNullOrEmpty(baseUri))
baseUri = "http://localhost/api/" + typeof(T).Name;
var request = new HttpRequestMessage(HttpMethod.Get, baseUri + "?" + oDataUri.Replace("?", ""));
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.AddEntity(typeof(T));
var edmModel = modelBuilder.GetEdmModel();
var oDataQueryContext = new ODataQueryContext(edmModel, typeof(T));
return new ODataQueryOptions<T>(oDataQueryContext, request);
}
}
}
Example use:
var OdataStuff = ODataBuilder<CustomerIntView>.BuildOptions("$orderby=Id");
One way to accomplish this is by manually constructing the request URI and setting that in the request parameter of the ODataQueryOptions constructor. So this may not be precisely what the original poster was looking for (question needed some clarification).
In my case I have a unit test, and I wanted to validate that the odata options were being applied to my queryable object. In the following sample code, assume that you are testing a ProductController that has a ProductName field in it.
// Manually set an OData query parameter
const string restUrl = "http://localhost/api/product?$orderby=ProductName";
// Need to construct an HTTP Context and a Request, then inject them into the controller
var config = new HttpConfiguration();
var request = new HttpRequestMessage(HttpMethod.Post, restUrl);
var route = config.Routes.MapHttpRoute(WebApiConfig.DefaultRouteName, "api/{controller}/{id}");
var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "Product" } });
var controller = new ProductController()
{
Request = request,
ControllerContext = new HttpControllerContext(config, routeData, request),
Url = new UrlHelper(request)
};
// Build up the OData query parameters
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.AddEntity(typeof(Product));
var edmModel = modelBuilder.GetEdmModel();
var oDataQueryContext = new ODataQueryContext(edmModel, typeof(Product));
var oDataQueryOptions = new ODataQueryOptions<Product>(oDataQueryContext, _controller.Request);
// Finally, call the controller
var result = controller.Get(oDataQueryOptions);
I do think you can if you can constructor an instance of ODataQueryOptions.
But, What's this:
var option = new ODataQueryOptions(request.params);
Web API doesn't provide such constructor. Is it your own implementation?
Thanks.
I've a method on my Web Api Controller that returns MemoryStream. Problem occurs when JsonMediaTypeFormatter is selected by DefaultContentNegotiator and WriteToStreamAsync is called. (I'm using default media type formatters)
Newtonsoft.Json.JsonSerializationException: Error getting value from 'MemStreamMaxLength on 'System.IO.MemoryStream'
Following code simulates the situation:
var stream = new MemoryStream();
stream.WriteByte(1);
stream.Position = 0;
var formatter = new JsonMediaTypeFormatter();
var writeStream = new MemoryStream();
formatter.WriteToMemoryStreamAsync(stream.GetType(), stream, writeStream, null, null).Wait();
I've verified using System.Text.Encoding.ASCII.GetString(ms.ToArray)); that my memorystream has the expected data.
However using the LinqToCSV nuget library will not generate my csv file. I get no errors or exceptions thrown. I just get an empty file when I'm prompted to open the file.
Here is my Action Method
public FileStreamResult Export(){
var results = _service.GetProperties().Take(3);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.TextWriter txt = new System.IO.StreamWriter(ms);
CsvFileDescription inputFileDescription = new CsvFileDescription{
SeparatorChar =',',
FirstLineHasColumnNames = true
}
;
CsvContext csv = new CsvContext();
csv.Write(results,txt,inputFileDescription);
return File(ms , "application/x-excel");
}
I find it interesting, if I change the return type to contentResult, and the return method to Content() and pass it System.Text.Encoding.ASCII.GetString(ms.ToArray)); I do get a browser window showing my data.
Make sure you reset stream position to 0. Also make sure you flush your StreamWriter before that.
Calling the Web API method to return CVS file from JavaScript.
public HttpResponseMessage Bidreport([FromBody]int formData).....
Fill in your IEnumerable<YourObject>query = from LINQ query
....
This is how to return it:
using (var ms = new MemoryStream())
{
using (TextWriter txt = new StreamWriter(ms))
{
var cc = new CsvContext();
cc.Write(query, txt, outputFileDescription);
txt.Flush();
ms.Position = 0;
var fileData = Encoding.ASCII.GetString(ms.ToArray());
var result = new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent(fileData)};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-excel");
return result;
}
}
I'm currently attempting to read certain properties from Outlook Contact objects through Microsoft's EWS managed API. I retrieve these Contact objects from the FindItems() function. Some of these fields are extended properties such as the Title or User1 field and I'm having difficulty reading them. At the moment, I have:
Guid propertySetId = new Guid("{00062004-0000-0000-C000-000000000046}");
ExtendedPropertyDefinition titleProp = new ExtendedPropertyDefinition(propertySetId, 0x3A45, MapiPropertyType.String);
ExtendedPropertyDefinition user1Prop = new ExtendedPropertyDefinition(propertySetId, 0x804F, MapiPropertyType.String);
string title, user1;
contact.TryGetProperty(titleProp, out title);
contact.TryGetProperty(user1Prop, out user1);
When running this, TryGetProperty always returns false. I have verified that these fields are populated in Outlook for the contacts that I am searching for.
Edit: This is how I retrieve the contact objects.
ExchangeService service = //...
Mailbox userMailbox = new Mailbox(emailAddress);
FolderId folderId = new FolderId(WellKnownFolderName.Contacts, userMailbox);
FindItemsResults<Item> results;
const string AQS = "Category:~>\"CategoryTag\"";
ItemView view = new ItemView(200);
results = service.FindItems(folderId, AQS, view);
foreach (var result in results)
{
Contact contact = result as Contact;
//...Try to read fields
}
You need to change the ItemView to include the properties (PropertySet) you wish to access.
var user1Val = string.Empty;
var user1Prop = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Address, 0x804F, MapiPropertyType.String);
ExtendedPropertyDefinition[] extendedFields = new ExtendedPropertyDefinition[] { user1Prop };
PropertySet extendedPropertySet = new PropertySet(BasePropertySet.FirstClassProperties, extendedFields);
ItemView view = new ItemView(200) { PropertySet = extendedPropertySet };
// ...
var title = contact.CompleteName.Title; // Title value
contact.TryGetProperty(user1Prop, out user1Val); // user field 1 value