I am creating one web app (mvc 4) to authorize customers (using membership provider) to view the reports(SSRS 2008) for which they are registered but they don't have any kind of access to our report server.
Based on the link How do I render a remote ReportViewer aspx page in MVC4?, I have implemented Elsimer's latest answer and it works well in downloading as a pdf file.
But when I try to render as html using the same code mentioned in the above link it is asking for the windows credentials to access the report server.
So I am giving a general credential which has all access to all the reports in the reportserver through the code. but it is still asking for the credentials for the report server when they try to view as html in the client side browser. Report is getting rendered but the images and graphs are not rendering without credentials.
Please advise, I have tried many things to solve this. but no luck.
My controller and credential class code as follows:
[Route("report/MonthlySummary")]
[ValidateAntiForgeryToken]
public ActionResult MonthlySummary(MonthlyReportParameters model)
{
if (ModelState.IsValid)
{
try
{
var actionType = model.ActionType;
if (actionType == "View Report")
{
return ExportMonthlyReportToHtml(model);
}
else if (actionType == "Download pdf report")
{
return ExportMonthlyReportToPdf(model);
}
}
catch (Exception ex)
{
//Logging errors
}
}
return null;
}
private ActionResult ExportMonthlyReportToHtml(MonthlyReportParameters monthlyParams)
{
ReportViewer reportViewer = BuildMonthlyReport(monthlyParams);
reportViewer.ServerReport.Refresh();
byte[] streamBytes = null;
string mimeType = "";
string encoding = "";
string filenameExtension = "";
string[] streamids = null;
Warning[] warnings = null;
//To view the report in html format
streamBytes = reportViewer.ServerReport.Render("HTML4.0", null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings);
var htmlReport = File(streamBytes, "text/html");
return htmlReport;
}
private static ReportViewer BuildMonthlyReport(MonthlyReportParameters model)
{
ReportViewer reportViewer = new Microsoft.Reporting.WebForms.ReportViewer();
try
{
var rptParameters = new List<ReportParameter>
{
//Building parameters
};
reportViewer.ProcessingMode = ProcessingMode.Remote;
reportViewer.ServerReport.ReportPath = "/reportFolder/reportName";
var reportServerUrl = ConfigurationManager.AppSettings["ReportServerUrl"];
if(!string.IsNullOrEmpty(reportServerUrl))
{
reportViewer.ServerReport.ReportServerUrl = new Uri(reportServerUrl);
}
reportViewer.ServerReport.ReportServerCredentials = new ReportServerCredentials();
reportViewer.ServerReport.SetParameters(rptParameters);
}
catch (Exception ex)
{
var errorMessage = ex.Message;
//TODO: handle errors;
}
return reportViewer;
}
public sealed class ReportServerCredentials : IReportServerCredentials
{
public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority)
{
authCookie = null;
userName = null;
password = null;
authority = null;
return false;
}
public WindowsIdentity ImpersonationUser
{
get
{
return null;
}
}
public ICredentials NetworkCredentials
{
get
{
string userName = ConfigurationManager.AppSettings["ReportUserName"];
if ((string.IsNullOrEmpty(userName)))
{
throw new Exception("Missing user name from web.config file");
}
string password = ConfigurationManager.AppSettings["ReportPassword"];
if ((string.IsNullOrEmpty(password)))
{
throw new Exception("Missing password from web.config file");
}
string domain = ConfigurationManager.AppSettings["DomainName"];
if ((string.IsNullOrEmpty(domain)))
{
throw new Exception("Missing domain from web.config file");
}
return new NetworkCredential(userName, password, domain);
}
}
}
Thanks in advance,
Related
I'm new in backend development and Gettig 415 Unsupported Media Type in multipart API written in .net core. I have attached the postman image for your reference. Thanks in advance.
[HttpPost]
[Route("uploadFiles")]
public async Task<ActionResult<IEnumerable<status>>> UploadFilesAsync([FromBody] UploadFile uploadFile)
{
using (var client = new AmazonS3Client("Access key", "Secret key", Region))
{
status s = new status();
try
{
if (uploadFile.Image != null && uploadFile.Image.Length > 0 && uploadFile.Name != null && uploadFile.Name != "")
{
using (var fileStream = new FileStream(uploadFile.Image.FileName, FileMode.Create))
{
uploadFile.Image.CopyTo(fileStream);
var uploadRequest = new TransferUtilityUploadRequest
{
InputStream = fileStream,
Key = uploadFile.Name,
BucketName = "needbucket",
CannedACL = S3CannedACL.PublicRead
};
var fileTransferUtility = new TransferUtility(client);
await fileTransferUtility.UploadAsync(uploadRequest);
}
s.Status = "1";
s.resone = "File uploded sucesefully.";
return Ok(s);
}
else
{
s.Status = "0";
s.resone = "Image and Image name canot be blank";
return Ok(s);
}
}
catch (Exception e)
{
s.Status = "0";
s.resone = "Somthing went wrong." + e.Message;
return Ok(s);
}
}
}
Getting in response on the postman.
1.Change your [FromBody] to [FromForm]
2.In the Body tab, select the form-data option. Then hover your mouse over the row so you can see a dropdown appear that says Text. Click this dropdown and set it to File.
Below is a work demo, you can refer to it.
public class UploadFile
{
public string Name { get; set; }
public IFormFile Image { get; set; }//this is my key name
}
Result:
FATAL ERROR: Unhandled Access Violation Reading 0x0008 Exception at 1d8257a5h
Failed missing output
I finally made it work with HostApplicationServices.getRemoteFile in local AutoCAD, then migrated it to Design Automation. It is also working now. The below is the command of .NET plugin.
To have a simple test, I hard-coded the URL in the plugin. you could replace the URL with the workflow at your side (either by an json file, or input argument of Design Automation)
My demo ReadDWG the entities from the remote URL file, then wblock the entities to current drawing (HostDWG), finally save current drawing.
Hope it helps to address the problem at your side.
.NET command
namespace PackageNetPlugin
{
class DumpDwgHostApp: HostApplicationServices
{
public override string FindFile(string fileName,
Database database,
FindFileHint hint)
{
throw new NotImplementedException();
}
public override string GetRemoteFile(Uri url,
bool ignoreCache)
{
//return base.GetRemoteFile(url, ignoreCache);
Database db =
Autodesk.AutoCAD.ApplicationServices.Application.
DocumentManager.MdiActiveDocument.Database;
string localPath = string.Empty;
if (ignoreCache)
{
localPath =
Autodesk.AutoCAD.ApplicationServices.Application.
GetSystemVariable("STARTINFOLDER") as string;
string filename =
System.IO.Path.GetFileName(url.LocalPath);
localPath += filename;
using (var client = new WebClient())
{
client.DownloadFile(url, localPath);
}
}
return localPath;
}
public override bool IsUrl(string filePath)
{
Uri uriResult;
bool result = Uri.TryCreate(filePath,
UriKind.Absolute, out uriResult)
&& (uriResult.Scheme == Uri.UriSchemeHttp ||
uriResult.Scheme == Uri.UriSchemeHttps);
return result;
}
}
public class Class1
{
[CommandMethod("MyPluginCommand")]
public void MyPluginCommand()
{
try {
string drawingPath =
#"https://s3-us-west-2.amazonaws.com/xiaodong-test-da/remoteurl.dwg";
DumpDwgHostApp oDDA = new DumpDwgHostApp();
string localFileStr = "";
if (oDDA.IsUrl(drawingPath)){
localFileStr = oDDA.GetRemoteFile(
new Uri(drawingPath), true);
}
if(!string.IsNullOrEmpty(localFileStr))
{
//source drawing from drawingPath
Database source_db = new Database(false, true);
source_db.ReadDwgFile(localFileStr,
FileOpenMode.OpenTryForReadShare, false, null);
ObjectIdCollection sourceIds =
new ObjectIdCollection();
using (Transaction tr =
source_db.TransactionManager.StartTransaction())
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
SymbolUtilityServices.GetBlockModelSpaceId(source_db),
OpenMode.ForRead);
foreach (ObjectId id in btr)
{
sourceIds.Add(id);
}
tr.Commit();
}
//current drawing (main drawing working with workitem)
Document current_doc =
Autodesk.AutoCAD.ApplicationServices.Application.
DocumentManager.MdiActiveDocument;
Database current_db = current_doc.Database;
Editor ed = current_doc.Editor;
//copy the objects in source db to current db
using (Transaction tr =
current_doc.TransactionManager.StartTransaction())
{
IdMapping mapping = new IdMapping();
source_db.WblockCloneObjects(sourceIds,
SymbolUtilityServices.GetBlockModelSpaceId(current_db),
mapping, DuplicateRecordCloning.Replace, false);
tr.Commit();
}
}
}
catch(Autodesk.AutoCAD.Runtime.Exception ex)
{
Autodesk.AutoCAD.ApplicationServices.Application.
DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
}
}
}
}
to do that i made a web service to send push (by referencing PushSharp library). I request web service through my web application. i retrieve list of device token from database(using web application) send to web service using for loop to send push. and get result/exception for each one. This process is very slow and take long long time to send notification. If anybody suggest me to what should i do i will be grateful to you.
public ActionResult SendNowToken(int certificateInfoId, string message, string certificate, int badgeNo, int pushtype, string password, string countryJsonString)
{
if (IsPushParameterValid(certificateInfoId, message, certificate, badgeNo, pushtype, password, countryJsonString))
{
var countryObject = new JavaScriptSerializer().Deserialize<Country>(countryJsonString);
var errorList = new List<ErrorList>();
byte[] certificatePath = System.IO.File.ReadAllBytes(HttpContext.Server.MapPath("~/Content/certificate/" + certificate));
foreach (var aDeviceToken in countryObject.DeviceTokens)
{
try
{
var serviceClient = new PushServiceSoapClient();
string serviceResult = serviceClient.SendPushNotification(message, badgeNo, pushtype, aDeviceToken.Token, certificatePath, password);
if (serviceResult != "Sent Notification")
{
var delimiters = new[] { ' ' };
string[] errorResult = serviceResult.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
string errorMessage = ConvertErrorCodeToErrorMessage(errorResult[0]);
var error = new ErrorList
{
CountryName = countryObject.CountryName,
ErrorTime = DateTime.Now,
ErrorMessage = errorMessage,
Token = aDeviceToken.Token
};
errorList.Add(error);
}
}
catch (Exception ex)
{
var error = new ErrorList
{
CountryName = countryObject.CountryName,
ErrorTime = DateTime.Now,
ErrorMessage = ex.Message,
Token = aDeviceToken.Token
};
errorList.Add(error);
}
}
if (errorList.Count != 0)
{
ViewBag.Message = "Push Notification does not send to country... ";
return PartialView("_SendAllError", errorList.ToList());
}
errorList.Clear();
}
return View();
}
My MVC4 application allows login using LinkedIn account. I want to pull all details that are avaible from linkedIn of the logged in User. Currently i have done the following.
In My AuthConfig.cs,
Dictionary<string, object> linkedInExtraData = new Dictionary<string, object>();
linkedInExtraData.Add("Icon", "../Images/linkedIn.png");
OAuthWebSecurity.RegisterClient(
client: new App_Start.LinkedInCustomClient("xxxxxxxxxxxx", "yyyyyyyyyyyyyyy"),
displayName: "LinkedIn",
extraData: linkedInExtraData);
In linkedInCustomClient.cs , from LinkedIn Developer Kit
public class LinkedInCustomClient : OAuthClient
{
private static XDocument LoadXDocumentFromStream(Stream stream)
{
var settings = new XmlReaderSettings
{
MaxCharactersInDocument = 65536L
};
return XDocument.Load(XmlReader.Create(stream, settings));
}
/// Describes the OAuth service provider endpoints for LinkedIn.
private static readonly ServiceProviderDescription LinkedInServiceDescription =
new ServiceProviderDescription
{
AccessTokenEndpoint =
new MessageReceivingEndpoint("https://api.linkedin.com/uas/oauth/accessToken",
HttpDeliveryMethods.PostRequest),
RequestTokenEndpoint =
new MessageReceivingEndpoint("https://api.linkedin.com/uas/oauth/requestToken?scope=r_fullprofile",
HttpDeliveryMethods.PostRequest),
UserAuthorizationEndpoint =
new MessageReceivingEndpoint("https://www.linkedin.com/uas/oauth/authorize",
HttpDeliveryMethods.PostRequest),
TamperProtectionElements =
new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
ProtocolVersion = ProtocolVersion.V10a
};
public LinkedInCustomClient(string consumerKey, string consumerSecret) :
base("linkedIn", LinkedInServiceDescription, consumerKey, consumerSecret) { }
/// Check if authentication succeeded after user is redirected back from the service provider.
/// The response token returned from service provider authentication result.
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
Justification = "We don't care if the request fails.")]
protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response)
{
// See here for Field Selectors API http://developer.linkedin.com/docs/DOC-1014
const string profileRequestUrl =
"https://api.linkedin.com/v1/people/~:(id,first-name,last-name,interests,headline,industry,summary,email-address,location:(name),picture-url,positions,associations,languages,honors,educations,date-of-birth,primary-twitter-account,three-current-positions,three-past-positions,group-memberships,specialties,skills)";
string accessToken = response.AccessToken;
string tokenSecret = (response as ITokenSecretContainingMessage).TokenSecret;
string Verifier = response.ExtraData.Values.First();
var profileEndpoint =
new MessageReceivingEndpoint(profileRequestUrl, HttpDeliveryMethods.GetRequest);
HttpWebRequest request =
WebWorker.PrepareAuthorizedRequest(profileEndpoint, accessToken);
try
{
using (WebResponse profileResponse = request.GetResponse())
{
using (Stream responseStream = profileResponse.GetResponseStream())
{
XDocument document = LoadXDocumentFromStream(responseStream);
return new AuthenticationResult(
isSuccessful: true,
provider: ProviderName,
providerUserId: userId,
userName: userName,
extraData: extraData);
}
}
}
catch (Exception exception)
{
return new AuthenticationResult(exception);
}
}
}
In my controller,
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
if (!result.IsSuccessful)
{
return RedirectToAction("ExternalLoginFailure");
}
I need to get the following details in my controller as authentication result.
(id,first-name,last-name,interests,headline,industry,summary,email-address,location:(name),picture-url,positions,associations,languages,honors,educations,date-of-birth,primary-twitter-account,three-current-positions,three-past-positions,group-memberships,specialties,skills)
The response of your request from LinkedIn will be a xml file. The format and fields are mentioned in LinkedIn Profile Fields
For getting email field, you need to modify your request token url as
RequestTokenEndpoint = new MessageReceivingEndpoint("https://api.linkedin.com/uas/oauth/requestToken?scope=r_fullprofile+r_emailaddress",
HttpDeliveryMethods.PostRequest),
You can get the fields as required in the following code
XDocument document = LoadXDocumentFromStream(responseStream);
Eg : For getting the first name field from the xml file,
var firstName = document.Root.Element("first-name").Value;
Fields like languages, positions, skills etc will be returned as structured objects as part of the profile.
Eg : Language field.
var Lang = document.Root.Element("languages");
var languages = new List<string>();
if (Lang != null)
{
foreach (var l in Lang.Elements())
{
if (l.Element("language") != null && l.Element("language").Element("name") != null)
{
languages.Add(l.Element("language").Element("name").Value);
}
}
}
Then you can add fields to "extraData" which can be accessed in the controller.
extraData.Add("firstName", firstName);
extraData.Add("languages", lang);
I want to create a registrant for a webinar using GoToWebinar API's. I came across the code at gotowebinar api php
I provided my username and password to get the oAuth object. This worked perfectly fine as described.
Now I want to do something like this:
I have a Registration page. When user fills in the required details, selects the 'register to webinar' option and clicks on 'Submit', I want to enrol him for that webinar using CreateRegistrant API. The problem is, I am not able to get the oAuth object without providing username and password. Is there a way to pass this programatically and create oAuth object?
I store my API key, UserID and password in my WebConfig then read them into a Login Object for use when I do authorization. Here's how I do it in C#:
public class Login
{
public string UserId
{ get { return System.Configuration.ConfigurationManager.AppSettings["GTWUserId"]; } }
public string Password
{ get { return System.Configuration.ConfigurationManager.AppSettings["GTWPassword"]; } }
public string APIKey
{ get { return System.Configuration.ConfigurationManager.AppSettings["GTWAPIKey"]; } }
}
public string DoAuthorize()
{
Login lg = new Login();
string sError = "";
// first we need to create the uri for the web request
string uri = String.Format("https://api.citrixonline.com/oauth/access_token?grant_type=password&user_id={0}&password={1}&client_id={2}",
lg.UserId, lg.Password, lg.APIKey);
// then the request to login is created and sent. From the response
// we need to store at least the access token and the organizer key
// to use for further calls
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Accept = "application/json";
request.ContentType = "application/json";
try
{
var response = request.GetResponse();
//the following lines duplicate the response stream so we can read it for
//deserialization and also re-read it and write it out.
using (MemoryStream ms = new MemoryStream())
{
var stream = response.GetResponseStream();
stream.CopyTo(ms);
ms.Position = 0;
stream.Close();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ResponseDirectLogin));
var deserialized = (ResponseDirectLogin)ser.ReadObject(ms);
auth.OauthToken = deserialized.AccessToken;
auth.OrganizerKey = deserialized.OrganizerKey;
}
}
catch (WebException e)
{
using (var sr = new StreamReader(e.Response.GetResponseStream()))
sError = sr.ReadToEnd();
sError = String.Concat(sError, "/n", uri);
}
return sError;
}
public class Auth {
public string OauthToken { get; set; }
public string OrganizerKey { get; set; }
}
public static Auth auth = new Auth(); // This is actually in a BaseControlelr inherited by our MVC Home Controller.
public string DoRegister(string WebinarKey)
{
// Here we authorize if we haven't alerady
if (auth.OauthToken == null)
{
sMessage = DoAuthorize();
}
// first we need to create the uri for the web request
// OrganizerKey is your authorization key for the webinar organizer
string uri = String.Format(#"https://api.citrixonline.com/G2W/rest/organizers/{0}/webinars/{1}/registrants",
OrganizerKey, WebinarKey);
//then create and serialize the registrant object
// This is for when you have questions on your webinar, you can omit them if you don't have any
List<questions> q = GetQuestionKeys(Key, OrganizerKey);
List<response> responses_ = new List<response>();
foreach (var question in q)
{
response res1 = new response();
res1.questionKey = question.questionKey;
// determine which question and set the response
if (question.question == "question")
{
res1.responseText = "response";
responses_.Add(res1);
}
}
var registrant = new Registrant
{
firstName = FirstName,
lastName = LastName,
email = EmailAddress,
responses = responses_.ToArray()
};
JavaScriptSerializer ser = new JavaScriptSerializer();
string json = ser.Serialize(registrant);
// then the request to create a registrant is created and sent
// N.B. we need to include the access token to the headers to access
// the user's account and data
try {
WebClient client = new WebClient();
client.Headers = new WebHeaderCollection();
client.Headers.Add("Accept", "application/vnd.citrix.g2wapi-v1.1+json");
client.Headers.Add("Content-type", "application/json");
client.Headers.Add("Authorization", string.Format("OAuth oauth_token={0}", OAuthToken));
try
{
string resp = client.UploadString(uri, "POST", json);
var ok = ser.Deserialize<ResponseCreateRegistrantOk>(resp);
}
catch (WebException e)
{
//if there is an error, e.g. the registrant exists already
// we need an alternative deserialization
Stream s = new MemoryStream();
using (Stream response = e.Response.GetResponseStream())
{
byte[] buffer = new byte[1024];
int byteCount;
do
{
byteCount = response.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, byteCount);
} while (byteCount > 0);
}
s.Seek(0, SeekOrigin.Begin);
string content = new StreamReader(s, Encoding.UTF8).ReadToEnd();
s.Seek(0, SeekOrigin.Begin);
using (var err = new StreamReader(s))
{
var sb = new StringBuilder("Registration Error\n");
if (content.IndexOf("int_err_code") > -1)
{
var dupe = ser.Deserialize<ResponseCreateRegistrantDuplicate>(err.ReadToEnd());
sb.AppendFormat(String.Format("Error Code: {0}<br />", dupe.ErrorCode));
sb.AppendFormat(String.Format("Message: {0}<br />", dupe.Message));
}
else
{
var dupe = ser.Deserialize<ResponseCreateRegistrantDuplicate>(err.ReadToEnd());
sb.AppendFormat(String.Format("Description: {0}<br />", dupe.Description));
//sb.AppendFormat(String.Format("Incident: {0}<br />", dupe.Incident));
//sb.AppendFormat(String.Format("Registrant key: {0}<br />", dupe.RegistrantKey));
sb.AppendFormat(String.Format("Join Url: {0}<br />", dupe.JoinUrl));
}
sMessage = sb.ToString();
}
}
} catch (Exception exc) {
exc.Data.Add("stringInfo", "inside");
return "";
}
return sMessage;
}