WkHtmlToXSharp How to add Headers and Footers? - pdf

I'm building an HTML to PDF converter with the WkHtmlToXSharp (QT webkit) library, and was wondering if someone knows how to add headers and footers to the document? I've seen a few questions about this library here, but couldn't find anything about the headers and footers.
In the wkhtmltopdf manual (http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html) there are documentation about headers and footers, but I couldn't find anything in the .NET wrapper library (WkHtmlToXSharp), it is probably not implemented?
Thanks for any help or suggestions!

Here are some snippets of how I do it:
public class HeaderFooterSettings
{
public string HtmlUrl { get; set; }
public string Right { get; set; }
public string Spacing { get; set; }
}
public class PdfObjectSettings
{
private WebSettings _webSettings = new WebSettings();
private LoadSettings _loadSettings = new LoadSettings();
private HeaderFooterSettings _headerSettings = new HeaderFooterSettings();
private HeaderFooterSettings _footerSettings = new HeaderFooterSettings();
public string Page { get; set; }
public string Cover { get; set; }
public bool ProduceForms { get; set; }
public bool PagesCount { get; set; }
public HeaderFooterSettings Header { get { return _headerSettings; } }
public HeaderFooterSettings Footer { get { return _footerSettings; } }
public WebSettings Web { get { return _webSettings; } }
public LoadSettings Load { get { return _loadSettings; } }
// TODO: Add remaining settings..
//see the following page for settings format http://www.cs.au.dk/~jakobt/libwkhtmltox_0.10.0_doc/pagesettings.html
}
Here is the main logic of setting the header and footer URL:
var objectSettings = new PdfObjectSettings();
objectSettings.Header.HtmlUrl = headerHtmlUrl;
objectSettings.Header.Spacing = ConfigurationManager.AppSettings["ContentSpacing"];
objectSettings.Footer.HtmlUrl = footerHtmlUrl;
I hope this helps.
Rafi

Related

how to send array to API which contains image and other data in .net core

When I am passing a single object like below then it is working as per below image
[HttpPost]
public async Task<ActionResult> Post([FromForm] MyModel Details)
{
}
but when I am passing the List of the object to API then it is not working. option to upload a file is not visible. and if I entered any values in the array then also I am getting count 0 for details.
[HttpPost]
public async Task<ActionResult> Post([FromForm] List<MyModel> Details)
{}
I want to pass the List of images and descriptions to API. How can I achieve it?
Thanks in advance!
You need custom model binding for the list model . Here is a similar demo:
custom model binding code:
public class MetadataValueModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException(nameof(bindingContext));
var values = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (values.Length == 0)
return Task.CompletedTask;
var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
var deserialized = JsonSerializer.Deserialize(values.FirstValue, bindingContext.ModelType, options);
bindingContext.Result = ModelBindingResult.Success(deserialized);
return Task.CompletedTask;
}
}
Add the model binder to the model class:
public class MasterDTO
{
public string Comments { get; set; }
public IFormFile File { get; set; }
public List<DetailDTO> Details { get; set; }
public MasterDTO()
{
this.Details = new List<DetailDTO>();
}
}
[ModelBinder(BinderType = typeof(MetadataValueModelBinder))]
public class DetailDTO
{
public Int64 ElementId { get; set; }
public double LowerLimit { get; set; }
public double HigherLimit { get; set; }
public string Status { get; set; }
public string UserAuthorization { get; set; }
public DateTime? AutorizationDate { get; set; }
}
controller/action
[HttpPost]
public async Task<IActionResult> CreateProjectLimit([FromForm] MasterDTO masterDto)
{
//...
return Ok();
}
You can just use postman to pass the list of images and Descriptions to API
Below is the right answer. we can use Postman to pass images in the array as shown below.

ASP.Net core web API encode string to base64

I am new to .Net Core development. I have a model:
public class CoreGoal
{
[Key]
public long CoreGoalId { get; set; }
public string Title { get; set; }
public string Effect { get; set; }
public string Target_Audience { get; set; }
public string Infrastructure { get; set; }
public virtual ICollection<Image> Images { get; set; }
public CoreGoal()
{
}
}
And Image model is as following:
public class Image
{
[Key]
public long ImagelId { get; set; }
public string Base64 { get; set; }
[ForeignKey("CoreGoalId")]
public long CoreGoalId { get; set; }
public Image()
{
}
}
I am using Repository pattern. My repository:
public interface ICoreGoalRepository
{
void CreateCoreGoal(CoreGoal coreGoal);
}
public class CoreGoalRepository : ICoreGoalRepository
{
private readonly WebAPIDataContext _db;
public CoreGoalRepository(WebAPIDataContext db)
{
_db = db;
}
//Find specific
public CoreGoal Find(long key)
{
return _db.CoreGoals.FirstOrDefault(t => t.CoreGoalId == key);
}
//Add new
public void CreateCoreGoal(CoreGoal coreGoal)
{
_db.CoreGoals.Add(coreGoal);
_db.SaveChanges();
}
}
And controller:
[Route("api/[controller]")]
public class CoreGoalController : Controller
{
private readonly ICoreGoalRepository _coreGoalRepository;
//Controller
public CoreGoalController(ICoreGoalRepository coreGoalRepository) {
_coreGoalRepository = coreGoalRepository;
}
[HttpGet("{id}", Name = "GetCoreGoal")]
public IActionResult GetById(long id)
{
var item = _coreGoalRepository.Find(id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}
//Create
[HttpPost]
public IActionResult Create([FromBody] CoreGoal item)
{
if (item == null)
{
return BadRequest();
}
_coreGoalRepository.CreateCoreGoal(item);
return CreatedAtRoute("GetCoreGoal", new { id = item.CoreGoalId }, item);
}
}
On POST request for CoreGoal- While creating a new CoreGoal, I would like to convert Image model's Base64 attribute from string to byte[]. I found this (https://adrientorris.github.io/aspnet-core/manage-base64-encoding.html) blogpost, but I am not sure where Am I supposed to write this piece of code.
Can someone help me?
Initially you should chage you database model to save you binary image to db (also, it's still not good idea, but let leave it for a now):
public class Image
{
[Key]
public long ImagelId { get; set; }
[NotMapped]
public string Base64 { get; set; }
public byte[] Binary {get; set;}
[ForeignKey("CoreGoalId")]
public long CoreGoalId { get; set; }
public Image()
{
}
}
next you just should convert your image inside controller:
[HttpPost]
public IActionResult Create([FromBody] CoreGoal item)
{
if (item == null)
{
return BadRequest();
}
item.Binary = Convert.FromBase64String(item.Base64);
_coreGoalRepository.CreateCoreGoal(item);
return CreatedAtRoute("GetCoreGoal", new { id = item.CoreGoalId }, item);
}
BTW:you code still not good. It's not necessary to use Repository pattern with EF core (https://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework-core/). And you should introduce two model layers: public layer and model layer. You shouldn't expose EF Core contract to outside.

Using ReadAsAsync<T>() to deserialize complex Json object

I want to use ReadAsAsync() in my mvc project with .net 4.0. The result comes as null.
If I enter the uri to address bar, the result in chrome as(tag names are changed):
<ns2:MyListResponse xmlns:ns2="blablabla">
<customerSessionId>xxcustomerSessionIdxx</customerSessionId>
<numberOfRecordsRequested>0</numberOfRecordsRequested>
<moreResultsAvailable>false</moreResultsAvailable>
<MyList size="1" activePropertyCount="1">
<MySummary order="0">
<id>1234</id>
<name>...</name>
.
.
</MySummary>
</MyList>
</ns2:MyListResponse>
If I use the statement in code :
using (var client = new HttpClient())
{
var response = client.GetAsync(apiUri).Result;
var message = response.Content.ReadAsStringAsync().Result;
var result1 = JsonConvert.DeserializeObject<MyListResponse>(message);
var result2 = response.Content.ReadAsAsync<MyListResponse>().Result;
}
the message comes in string format as "{\"MyListResponse\":{\"customerSessionId\"...}" which corresponds to a json object as:
{"MyListResponse":
{"customerSessionId":"xxcustomerSessionIdxx",
"numberOfRecordsRequested":0,
"moreResultsAvailable":false,
"MyList":
{"#size":"1",
"#activePropertyCount":"1",
"MySummary":
{"#order":"0",
"id":1234,
"name":"...",
.
.
}
}
}
}
and the properties of result1 and result2 came as null or default values. Class definitions are below. I want to read the content as an object but I couldn't. What do you advice to solve this? What am I doing wrong? Thanks in advance.
public class MySummary
{
public int #Order { get; set; }
public string Id { get; set; }
public string Name { get; set; }
.
.
}
public class MyList
{
public int #Size { get; set; }
public int #ActivePropertyCount { get; set; }
public MySummary MySummary{ get; set; }
}
public class MyListResponse
{
public string CustomerSessionId { get; set; }
public int NumberOfRecordsRequested { get; set; }
public bool MoreResultsAvailable { get; set; }
public MyList MyList { get; set; }
}
I defined a new class as:
public class ResponseWrapper
{
public MyListResponse MyListResponse { get; set; }
}
then I used this wrapper with,
var result1 = JsonConvert.DeserializeObject<ResponseWrapper>(message);
var result2 = response.Content.ReadAsAsync<ResponseWrapper>().Result;
then it worked. I need only MySummary object but I should write more classes to make it work.
After reading your solution I came up with one that doesn't need an extra class:
private static async Task<U> Execute<U>(HttpClient client, string path)
{
U output = default(U);
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
var jsonAsString = await response.Content.ReadAsStringAsync();
output = JsonConvert.DeserializeObject<U>(jsonAsString);
}
else
{
throw new ApplicationException(string.Format("Response message is not OK. Issues in action: {0}", path));
}
return output;
}
For the sake of future readers, I think the correct approach is using ReadAsAsync overload that takes IEnumerable<MediaTypeFormatter> and provide a formatter with the same settings used on the server for serialization. That should fix it.
It is possible to use at client ReadAsAsync with MyListResponse directly (in consequence without ResponseWrapper). To do this, you can define "BodyStyle = WebMessageBodyStyle.Bare" in the operation contract of "apiuri" in stead of "BodyStyle = WebMessageBodyStyle.Wrapped" (server side, i.e. service contract).

ServiceStack - calling 3rd party web service with class

I am trying to call a 3rd party web service
Their REST API uses the following URL style.
http://www.VoiceBase.com/services?version=1.0&apikey=your-apikey&password=secret&action=list&status=processing
All of their service calls go to the same /services
How do I create a class so the following would work?
var client = new JsonServiceClient("http://www.voicebase.com");
var response = client.Get<ResponseVoiceBaseListClass>(new VoiceBaseListClass());
Additional classes I have created but I am not quite there yet
public class VoiceBaseBaseClass
{
public string version { get; set; }
public string apikey { get; set; }
public string password { get; set; }
public VoiceBaseBaseClass()
{
this.version = "1.0";
this.apikey = "API";
this.password = "password";
}
}
public class VoiceBaseListClass : VoiceBaseBaseClass, IReturn<ResponseVoiceBaseListClass>
{
public string action { get; set; }
public string status { get; set; }
public VoiceBaseListClass()
: base()
{
this.action = "list";
this.status = "processing";
}
}
public class ResponseVoiceBaseListClass
{
public string requestStatus { get; set; }
public string statusMessage { get; set; }
public string fileStatus { get; set; }
public List<string> mediaIds { get; set; }
public ResponseVoiceBaseListClass()
{
this.mediaIds = new List<string>();
}
}
Using the above classes the call that goes to the server is
/json/syncreply/VoiceBaseListClass?action=list&status=processing&version=1.0&apikey=API&Password=password
Is there a way I can force the service stack client to go to the
/Services
instead of
/json/syncreply/VoiceBaseListClass
I found a way to do this and it is working great for me.
[RestService("/services", "GET")]
public class VoiceBaseListClass : VoiceBaseBaseClass, IReturn<ResponseVoiceBaseListClass>
{
}
Although this is a deprecated attribute - the new attribute is called Route
https://github.com/ServiceStack/ServiceStack/wiki/Release-Notes
Chris

Json parsing in windows phone (C#)

I am new to Windows Phone development.I want to parse some data using json parsing.After
googling i find a number of example but I am not able to understand properly.I have follow
a link
http://dotnetbyexample.blogspot.in/2012/01/json-deserialization-with-jsonnet.html
to do json parsing But i am not able to show Storage ,Memory, ScreenSize in my List and my code is
private void Load_Click(object sender, RoutedEventArgs e)
{
var w = new WebClient();
Observable
.FromEvent<DownloadStringCompletedEventArgs>(w, "DownloadStringCompleted")
.Subscribe(r =>
{
var deserialized =
JsonConvert.DeserializeObject<List<RootObject>>(r.EventArgs.Result);
PhoneList.ItemsSource = deserialized;
});
w.DownloadStringAsync(
new Uri("http://www.schaikweb.net/dotnetbyexample/JSONPhones1.txt"));
}
}
public class Specs
{
public string Storage { get; set; }
public string Memory { get; set; }
public string Screensize { get; set; }
}
public class RootObject
{
public string Brand { get; set; }
public string Type { get; set; }
public Specs Specs { get; set; }
}
}
Please Help me to solve this issue or any other sample for the same is also appreciated
Thanks
The code seems ok, so if you aren't running in to any errors there might be an issue with your UI code or UI to data coupling.
You need to post the UI code to get some help with this I suspect.