error : is a field but used as a type - c#-4.0

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication5
{
public class ClientContext
{
private string p;
public ClientContext(string p)
{
// TODO: Complete member initialization
this.p = p;
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//First construct client context, the object which will be responsible for
//communication with SharePoint:
private ClientContext context = new ClientContext("#url");
//then get a hold of the list item you want to download, for example
public List list;
public ClientContext
{
list = context.Web.Lists.GetByTitle("001_CFR_DPV_COST_REV_SHARING");
}
//note that data has not been loaded yet. In order to load the data
//you need to tell SharePoint client what you want to download:
context.Load(result, items=>items.Include(
item => item["Title"],
item => item["FileRef"]
));
//now you get the data
context.ExecuteQuery();
//here you have list items, but not their content (files). To download file
//you'll have to do something like this:
var item = items.First();
//get the URL of the file you want:
var fileRef = item["FileRef"];
//get the file contents:
FileInformation fileInfo = File.OpenBinaryDirect(context, fileRef.ToString());
using (var memory = new MemoryStream())
{
byte[] buffer = new byte[1024 * 64];
int nread = 0;
while ((nread = fileInfo.Stream.Read(buffer, 0, buffer.Length)) > 0)
{
memory.Write(buffer, 0, nread);
}
memory.Seek(0, SeekOrigin.Begin);
// ... here you have the contents of your file in memory,
// do whatever you want
}
}
}
this is the complete code.
I don't know why it is showing error. I searched for the error "is a field but used as a type" and I tried that but it didn't help. Please help with a solution Code to this since I am new to this. Thank you in advance.

What are you trying to achieve by this lines of code?
public partial class Form1 : Form
{
...
public ClientContext
{
list = context.Web.Lists.GetByTitle("001_CFR_DPV_COST_REV_SHARING");
}
}
What is public ClientContext {} inside class Form1 ?
It seems that you intended to create constructor to a class in another class and for compiler it looks more like a property but without accessors (get, set) as if it is a Type or smth like this.
Try to put get; set; accessors inside if you intended to create property:
public List Context
{
get
{
list = context.Web.Lists.GetByTitle("001_CFR_DPV_COST_REV_SHARING");
return list;
}
}
Or change it to method instead :
public void GetClientContext()
{
list = context.Web.Lists.GetByTitle("001_CFR_DPV_COST_REV_SHARING");
}

Related

Big JSON stream on Azure

I'm working on a big data export API, but I'm having isssues when it needs to transport big data as JSON. An example of such is a transfer of over 4 milion records. When saved as a textfile, the data is suposed to be about 380MB, but for some reason the stream is cut short to about 250-280MB (always dfferent) and when I check the file in notepad, it did just cut off the data in the middle of a record.
This behaviour is only happening on the Azure server, I can download the full file through my local IIS. Also weird is that when I export the data as XML, which results in an even bigger file of +600MB did not have this issue.
Our Azure app service plan is S3 (4 cores, 7GB memory) which I believe should be enough, the code that actually transfers the data is the following function:
public IActionResult ResponseConvert(IList data)
{
return new Microsoft.AspNetCore.Mvc.JsonResult(data);
}
The data parameter is a List<dynamic> object, containing the +4 milion records.
At first glance it seems like Azure terminates the stream prematurely, any idea why and how this can be prevented?
In the end I've writen my own JsonResult class, that would use a JsonTextWriter to transfer the data. This seems to work fine with larger objects, even on Azure.
Here's the full class:
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Text;
namespace MyProject.OutputFormat
{
public class JsonResult : ActionResult
{
private readonly IList _data;
public Formatting Formatting { get; set; }
public string MimeType { get; set; }
public JsonResult(IList data)
{
_data = data;
// Default values
MimeType = "application/json";
Formatting = Formatting.None;
}
public override void ExecuteResult(ActionContext context)
{
context.HttpContext.Response.ContentType = MimeType;
using (var sw = new StreamWriter(context.HttpContext.Response.Body, Encoding.UTF8))
{
using (var writer = new JsonTextWriter(sw) { Formatting = Formatting })
{
writer.WriteStartArray();
if (_data != null)
{
foreach (var item in _data)
{
writer.WriteStartObject();
if (item is ExpandoObject)
{
foreach (KeyValuePair<string, object> prop in item as ExpandoObject)
{
writer.WritePropertyName(prop.Key);
writer.WriteValue(prop.Value != null ? prop.Value.GetType().Name != "Byte[]" ? prop.Value.ToString() : ((byte[])prop.Value).BinaryToString() : null);
}
}
else
{
var props = item.GetType().GetProperties().Where(i => i.Name != "Item");
foreach (var prop in props)
{
var val = prop.GetValue(item);
writer.WritePropertyName(prop.Name);
writer.WriteValue(val != null ? val.GetType().Name != "Byte[]" ? val.ToString() : ((byte[])val).BinaryToString() : null);
}
}
writer.WriteEndObject();
}
}
writer.WriteEndArray();
}
}
}
}
}
The BinaryToString() method you see is a self written extension on byte[] to convert a byte array to a base64 string.
Small note, though this works for bigger data, the JsonResult in Microsoft.AspNetCore.Mvc downloads faster. Getting the response to the client is as fast, but since this method only converts during download, it takes a bit longer until the stream is fully downloaded. If you do not have any issues in your environment, I'd advise using the one in Microsoft.AspNetCore.Mvc.

mvc genericly binding byte[] properties

I've tried using a custom model binder but my request.files is not populated. IN forms collection, the input of type file for the byte[] property is populated by file name only.
<input id="collection[#index].#p.Name" name="collection[#index].#p.Name" type="file" />
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace male.services.mvc.Binders
{
public class CustomModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType.GetProperties().Any(o => o.PropertyType == typeof(byte[])))
{
HttpRequestBase request = controllerContext.HttpContext.Request;
foreach (var pi in bindingContext.ModelType.GetProperties().Where(o => o.PropertyType == typeof(byte[])))
{
// can't access any property in the parameters that gives me my file input or my stream
}
return base.BindModel(controllerContext, bindingContext);
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
}
}
I found the answer. This will allow me to go straight from html file inputs to EF models without resorting to hand-crafting a file argument for each model type and property type which needs it. (Aint nobody got time for that)
In order for a form to post files, it must have the enctype attribute:
<form enctype="multipart/form-data" ... />
Once that is done, the file can be accessed via controllerContext.HttpContext.Request.Files
UPDATE - Working Example
Note: You don't need the Regex stuff if you aren't trying to bind a collection. You also don't need the EndsWith, you can just use ==
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
namespace male.services.mvc.Binders
{
public class CustomModelBinder : DefaultModelBinder
{
HttpRequestBase request;
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
request = controllerContext.HttpContext.Request;
return base.BindModel(controllerContext, bindingContext);
}
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
if (propertyDescriptor.PropertyType == typeof(byte[]))
{
var key = request.Files.AllKeys.SingleOrDefault(o => o.EndsWith($"].{propertyDescriptor.Name}"));
var fileIndex = Regex.Match(key, #"\[(.*)\]").Groups[1].Value;
var modelIndex = Regex.Match(bindingContext.ModelName, #"\[(.*)\]").Groups[1].Value;
if(fileIndex == modelIndex)
{
HttpPostedFileWrapper httpPostedFile = (HttpPostedFileWrapper)request.Files[request.Files.AllKeys.SingleOrDefault(o => o.EndsWith(propertyDescriptor.Name))];
using (MemoryStream ms = new MemoryStream())
{
httpPostedFile.InputStream.CopyTo(ms);
propertyDescriptor.SetValue(bindingContext.Model, ms.ToArray());
}
}
}
else
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
}

Injecting dynamic content into an Orchard page body

Is it possible to inject dynamic content into an Orchard page body? I would like to inject the id of the current logged in user into links.
My initial thought was to use token replacement, so entering would replace [memberid] with the logged in user id at runtime. Is there a way I can intercept the response and run some custom code before it is sent back to the client?
This question is the same, however the answer is very specific to their issue.
Tokens might be the proper way to go, however I haven't digged into that yet. But if you want to change the response you can use response filters.
I used it to minify resulting HTML in this module https://gallery.orchardproject.net/List/Modules/Orchard.Module.JadeX.HtmlMarkupMinifier
Here's the code that should do the trick or at least give you an idea.
using System.Globalization;
using System.IO;
using System.Text;
using System.Web.Mvc;
using Orchard;
using Orchard.Mvc.Filters;
using Orchard.UI.Admin;
public class TokenReplacementFilter : FilterProvider, IActionFilter
{
private readonly WorkContext _workContext;
public TokenReplacementFilter(IWorkContextAccessor workContextAccessor)
{
_workContext = workContextAccessor.GetContext();
}
public void OnActionExecuting(ActionExecutingContext filterContext) {
// Only apply the token replacement if logged in and not in the Orchard admin area
if (filterContext.HttpContext.Response.Filter == null || _workContext.CurrentUser == null || AdminFilter.IsApplied(filterContext.RequestContext))
return;
filterContext.HttpContext.Response.Filter = new TokenReplacementStream(filterContext.HttpContext.Response.Filter, filterContext.HttpContext.Response.Output.Encoding, _workContext);
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
}
internal class TokenReplacementStream : MemoryStream
{
private readonly Stream _stream;
private readonly Encoding _encoding;
private string _html;
private readonly WorkContext _workContext;
public TokenReplacementStream(Stream filter, Encoding encoding, WorkContext workContext)
{
_stream = filter;
_encoding = encoding;
_workContext = workContext;
}
public override void Write(byte[] buffer, int offset, int count)
{
_html += _encoding.GetString(buffer);
}
public override void Flush()
{
if (_html != null) {
_html = _html.Replace("[memberid]", _workContext.CurrentUser.Id.ToString(CultureInfo.InvariantCulture));
_stream.Write(_encoding.GetBytes(_html), 0, _encoding.GetByteCount(_html));
}
}
}

Using RazorEngine with TextWriter

I want to use RazorEngine to generate some html files. It's easy to generate strings first, then write them to files. But if the generated strings are too large, that will cause memory issues.
So I wonder is there a non-cached way to use RazorEngine, like using StreamWriter as its output rather than a string.
I google this for a while, but with no luck.
I think use a custom base template should be the right way, but the documents are so few(even out of date) on the offcial homepage of RazorEngine.
Any hint will be helpful!
OK. I figured it out.
Create a class that inherits TemplateBase<T>, and take a TextWrite parameter in the constructor.
public class TextWriterTemplate<T> : TemplateBase<T>
{
private readonly TextWriter _tw;
public TextWriterTemplate(TextWriter tw)
{
_tw = tw;
}
// override Write and WriteLiteral methods, write text using the TextWriter.
public override void Write(object value)
{
_tw.Write(value);
}
public override void WriteLiteral(string literal)
{
_tw.Write(literal);
}
}
Then use the template as this:
private static void Main(string[] args)
{
using (var sw = new StreamWriter(#"output.txt"))
{
var config = new FluentTemplateServiceConfiguration(c =>
c.WithBaseTemplateType(typeof(TextWriterTemplate<>))
.ActivateUsing(context => (ITemplate)Activator.CreateInstance(context.TemplateType, sw))
);
using (var service = new TemplateService(config))
{
service.Parse("Hello #Model.Name", new {Name = "Waku"}, null, null);
}
}
}
The content of output.txt should be Hello WAKU.

how to add emoticons to richtextbox

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace abc
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
EmoticonRender ab = new EmoticonRender();
private void button1_Click(object sender, EventArgs e)
{
string textie = ab.Parse(textBox1.Text);
richTextBox1.Text += textie+"\n";
}
}
public class EmoticonRender
{
private List<KeyValuePair<string, string>> _dictionary = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>(":-)", "a.png"),
new KeyValuePair<string, string>(";-(", "a.png"),
};
public string Parse(string text)
{
foreach(KeyValuePair<string, string> kvp in _dictionary)
{
text = text.Replace(kvp.Key, #"C:\Users\Buddiez\Documents\Visual Studio 2010\Projects\abc\abc\a.png");
}
return text;
}
}
}
im using these line of codes to insert smilyes into richtextbox but instead of showing smileye it is showing the path of the png imgae ie. C:\Users\Buddiez\Documents\Visual Studio 2010\Projects\abc\abc\a.png
Copy all the images which you have and navigate to >> visual studio select Project>>Properties.There select Resources and paste all copied images on the right side pane.
Hashtable emotions;
void CreateEmotions()
{
emotions= new Hashtable(6);
emotions.Add(":-)", Project.Properties.Resources.regular_smile);
emotions.Add(":)", Project.Properties.Resources.regular_smile);
}
void AddEmotions()
{
foreach (string emote in emotions.Keys)
{
while(richTextBox1.Text.Contains(emote))
{
int ind = richTextBox1.Text.IndexOf(emote);
richTextBox1.Select(ind, emote.Length);
Clipboard.SetImage((Image)emotions[emote]);
richTextBox1.Paste();
}
}
}
A good (and relatively new) solution could be using the open-source EmojiBox project.
There's not much code there so it's quite easy to follow, just note that in order to insert an emoji into the custom RichTextBox there, the text you type has to follow the template of :emoji_name:
Of course, if you don't want to use the whole list of unicode emojis, you could also replace the image files or their names/descriptions within the json file.

Resources