فایل PDF، یک فایل باینری هست و سازگاری با فرمت و استاندارد متنی JSON ندارد. به همین جهت اگر از مثلا JSON.NET استفاده کنید، خروجی باینری را تبدیل به یک رشته base64 میکند و سپس ارائه.
پاسخ به بازخوردهای پروژهها
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); } }
public class VideoStream { private readonly string _filename; private long _contentLength; public long FileLength { get { return _contentLength; } } public VideoStream(string videoPath) { _filename = videoPath; using (var video = File.Open(_filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { _contentLength = video.Length; } } public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context) { try { var buffer = new byte[65536]; using (var video = File.Open(_filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { var length = (int)video.Length; var bytesRead = 1; while (length > 0 && bytesRead > 0) { bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length)); await outputStream.WriteAsync(buffer, 0, bytesRead); length -= bytesRead; } } } catch (HttpException) { return; } finally { outputStream.Close(); } } }
while (length > 0 && bytesRead > 0) { bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length)); await outputStream.WriteAsync(buffer, 0, bytesRead); length -= bytesRead; }
public class VideoController : ApiController { [Route("api/video/{ext}/{fileName}")] public HttpResponseMessage Get(string ext, string fileName) { string videoPath = HostingEnvironment.MapPath(string.Format("~/Videos/{0}.{1}", fileName, ext)); if (File.Exists(videoPath)) { FileInfo fi = new FileInfo(videoPath); var video = new VideoStream(videoPath); var response = Request.CreateResponse(); response.Content = new PushStreamContent((Action<Stream, HttpContent, TransportContext>)video.WriteToStream, new MediaTypeHeaderValue("video/" + ext)); response.Content.Headers.Add("Content-Disposition", "attachment;filename=" + fi.Name.Replace(" ", "")); response.Content.Headers.Add("Content-Length", video.FileLength.ToString()); return response; } else { return Request.CreateResponse(HttpStatusCode.NotFound); } } }
[Route("api/video/{ext}/{fileName}")]
api/video/mp4/sample
string videoPath = HostingEnvironment.MapPath(string.Format("~/Videos/{0}.{1}", fileName, ext));
var video = new VideoStream(videoPath);
var response = Request.CreateResponse(); response.Content = new PushStreamContent((Action<Stream, HttpContent, TransportContext>)video.WriteToStream, new MediaTypeHeaderValue("video/" + ext));
response.Content.Headers.Add("Content-Disposition", "attachment;filename=" + fileName); response.Content.Headers.Add("Content-Length", video.FileLength.ToString());
if(File.Exists(videoPath)) { // removed for bravity } else { return Request.CreateResponse(HttpStatusCode.NotFound); }
public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } }
<div> <div> <video width="480" height="270" controls="controls" preload="auto"> <source src="/api/video/mp4/sample" type="video/mp4" /> Your browser does not support the video tag. </video> </div> </div>
D:\Prog\1389\CodePlex\slpdatepicker\SlPDatePickerNuGet>NuGet.exe spec
Created 'Package.nuspec' successfully.
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Silverlight.4.Persian.DatePicker</id>
<version>1.0</version>
<authors>Vahid Nasiri</authors>
<owners>Vahid Nasiri</owners>
<licenseUrl>http://slpdatepicker.codeplex.com/license</licenseUrl>
<projectUrl>http://slpdatepicker.codeplex.com/</projectUrl>
<iconUrl>https://slpdatepicker.svn.codeplex.com/svn/SilverlightPersianDatePicker/Views/Images/date.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Silverlight 4 Persian DatePicker Control</description>
<tags>Silverlight WPF Persian DatePicker</tags>
</metadata>
<files>
<file src="..\SilverlightPersianDatePicker\Bin\Release\*.dll" target="lib" />
<file src="..\SilverlightPersianDatePicker\Bin\Release\*.pdb" target="lib" />
<file src="..\SilverlightPersianDatePicker\Bin\Release\*.xml" target="lib" />
</files>
</package>
NuGet.exe pack Package.nuspec
get-package -remote -filter silverlight
nuget push name.nupkg key
System.IO.FileNotFoundException
System.IO.FileLoadExceptio
<?xml version="1.0"?> <configuration> <runtime> <assemblyBinding xmlns="urn:schemasmicrosoftcom:asm.v1"> <probing privatePath="AuxFiles;bin\subdir" /> <dependentAssembly> <assemblyIdentity name="SomeClassLibrary" publicKeyToken="32ab4ba45e0a69a1" culture="neutral"/> <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" /> <codeBase version="2.0.0.0" href="http://www.Wintellect.com/SomeClassLibrary.dll" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="TypeLib" publicKeyToken="1f2e74e897abbcfe" culture="neutral"/> <bindingRedirect oldVersion="3.0.0.03.5.0.0" newVersion="4.0.0.0" /> <publisherPolicy apply="no" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
Probing | در
قسمت بیستم گفتیم که در این المان، مکانهایی را که CLR برای پیدا کردن
اسمبلیهای با نام ضعیف، باید اسکن کند، وارد میکنیم که هر مسیر با , از هم جدا شدهاست. برای اسمبلیهای با نام قوی CLR باید داخل GAC را نگاه
کند و در URL هایی که از طریق المان CodeBase مشخص کردهایم. اگر المان
CodeBase مشخص نشود، CLR برای پیدا کردن اسمبلیهای با نام قوی، داخل
دایرکتوریهای این المان را اسکن خواهد کرد. |
Dependent Assembly اول | در
اولین فرزند این المان، Assembly Identity یک اسمبلی با مشخصاتی مثل
Culture و توکن عمومی معرفی میشود و در BindingRedirect به CLR اطلاع
میدهد موقعی که به دنبال نسخه یک این اسمبلی است، نسخهی دو آن را برای
استفاده جایگزین کند. |
Code Base | این
المان میگوید که وقتی CLR سعی در پیدا کردن نسخهی 2 اسمبلی را دارد، آن را
از طریق آدرس مورد نظر پیدا کند. این المان میتواند برای اسمبلیهای با نام
ضعیف هم کار کند. |
Dependent Assembly دوم | این مورد هم همانند سابق است با این تفاوت که گسترهی نسخه 3 تا 3.5 را به نسخهی 4 تغییر میدهد. |
Publisher Policy | اگر
سازمان تولید کننده این اسمبلی فایلی برای تعیین Policy به همراه اسمبلی
ارائه کرده باشد، این المان باعث میشود این فایل ندیده گرفته شود (در مورد
فایل Policy در آینده صحبت میکنیم). |
نکته : اگر مدیر بخواهد تمام برنامههای موجود از این اسمبلی جدید استفاده کنند باید فایل machine.config را ویرایش کند.
filterContext.Controller.ViewBag.CanonicalUrl = absoluteUrlToLower;
<link rel="canonical" href="@ViewBag.CanonicalUrl"/>